pread/pwrite/ipf encoder/ipf decoder

This commit is contained in:
minjaesong
2022-09-17 23:36:02 +09:00
parent 96b54933c7
commit d4dc99ff83
13 changed files with 141 additions and 15 deletions

View File

@@ -261,8 +261,20 @@ _TVDOS.DRV.FS.SERIAL.getFileLen = (fd) => {
}
return Number(com.pullMessage(port[0]))
}
// TODO pread replaces DMA.comToRam
// TODO pwrite replaces DMA.ramToCom
_TVDOS.DRV.FS.SERIAL.pread = (fd, ptr, count, offset) => {
if (129 == _TVDOS.DRV.FS.SERIAL._openr(fd)) throw Error(`No such file: ${fd.fullPath}`)
let port = _TVDOS.DRV.FS.SERIAL._toPorts(fd.driveLetter)
com.sendMessage(port[0], "READ")
let response = com.getStatusCode(port[0])
if (135 == response) {
throw Error("File not opened")
}
if (response < 0 || response >= 128) {
throw Error("Reading a file failed with "+response)
}
dma.comToRam(port[0], offset, ptr, count)
}
_TVDOS.DRV.FS.SERIAL.sread = (fd) => {
if (129 == _TVDOS.DRV.FS.SERIAL._openr(fd)) throw Error(`No such file: ${fd.fullPath}`)
@@ -277,6 +289,15 @@ _TVDOS.DRV.FS.SERIAL.sread = (fd) => {
}
return com.pullMessage(port[0])
}
_TVDOS.DRV.FS.SERIAL.pwrite = (fd, ptr, count, offset) => {
if (offset) throw Error(`Write offset not supported on Serial device such as disk drives`)
let rrrr = _TVDOS.DRV.FS.SERIAL._openw(fd); if (rrrr != 0) throw Error("Writing a file failed with "+rrrr)
let port = _TVDOS.DRV.FS.SERIAL._toPorts(fd.driveLetter)
dma.ramToCom(ptr, port[0], count)
}
_TVDOS.DRV.FS.SERIAL.swrite = (fd, string) => {
let rrrr = _TVDOS.DRV.FS.SERIAL._openw(fd); if (rrrr != 0) throw Error("Writing a file failed with "+rrrr)
@@ -399,6 +420,7 @@ _TVDOS.DRV.FS.DEVRND.pread = (fd, ptr, count, offset) => {
for (let i = 0; i < count; i++) {
sys.poke(ptr + i, bytes[offset + i])
}
}
_TVDOS.DRV.FS.DEVRND.pwrite = (fd, ptr, count, offset) => {}
@@ -570,8 +592,8 @@ Object.freeze(_TVDOS.DRV.FS.DEVFBIPF)
// Legacy Serial filesystem, !!pending for removal!!
/*
const filesystem = {};
/*const filesystem = {};
filesystem._toPorts = (driveLetter) => {
if (driveLetter.toUpperCase === undefined) {
@@ -692,8 +714,8 @@ filesystem.remove = (driveLetter) => {
var response = com.getStatusCode(port[0]);
return (response === 0);
};
Object.freeze(filesystem);
*/
Object.freeze(filesystem);*/
///////////////////////////////////////////////////////////////////////////////

View File

@@ -0,0 +1,47 @@
if (exec_args[1] == undefined) {
println("decodeipf <input.ipf>")
return 1
}
let infile = files.open(_G.shell.resolvePathInput(exec_args[1]).full)
// read input file
let infilePtr = sys.malloc(infile.size)
infile.pread(infilePtr, infile.size, 0)
// check if magic number matches
const MAGIC = [0x1F, 0x54, 0x53, 0x56, 0x4D, 0x69, 0x50, 0x46]
let magicMatching = true
MAGIC.forEach((b,i) => {
let testb = sys.peek(infilePtr + i) & 255 // for some reason this must be located here
if (testb != b) {
magicMatching = false
}
})
if (!magicMatching) {
println("Not an iPF file (MAGIC mismatch)")
return 1
}
// decode input image
let width = sys.peek(infilePtr+8) | (sys.peek(infilePtr+9) << 8)
let height = sys.peek(infilePtr+10) | (sys.peek(infilePtr+11) << 8)
let hasAlpha = (sys.peek(infilePtr+12) != 0)
let ipfType = sys.peek(infilePtr+13)
let imgLen = sys.peek(infilePtr+24) | (sys.peek(infilePtr+25) << 8) | (sys.peek(infilePtr+26) << 16) | (sys.peek(infilePtr+27) << 24)
let decodefun = undefined
if (ipfType == 1) decodefun = graphics.decodeIpf1
if (ipfType == 2) decodefun = graphics.decodeIpf2
if (decodefun === undefined) throw Error(`Unknown IPF format: ${ipfType}`)
let ipfbuf = sys.malloc(imgLen)
gzip.decompFromTo(infilePtr + 28, infile.size - 28, ipfbuf) // should return FBUF_SIZE
sys.free(infilePtr)
graphics.setGraphicsMode(4)
graphics.clearText(); graphics.clearPixels(0); graphics.clearPixels2(0)
decodefun(ipfbuf, -1048577, -1310721, width, height, hasAlpha)
sys.free(ipfbuf)

View File

@@ -0,0 +1,57 @@
if (exec_args[3] == undefined) {
println("encodeipf <1/2> <input picture> <output filename> [/noalpha]")
return 1
}
let noalpha = exec_args[4] != undefined && exec_args[4].toLowerCase() == "/noalpha"
let infile = files.open(_G.shell.resolvePathInput(exec_args[2]).full)
let outfile = files.open(_G.shell.resolvePathInput(exec_args[3]).full)
let ipfType = exec_args[1]|0
let encodefun = undefined
if (1 == exec_args[1]) encodefun = graphics.encodeIpf1
if (2 == exec_args[1]) encodefun = graphics.encodeIpf2
if (encodefun === undefined) throw Error(`Unknown IPF format: ${exec_args[1]}`)
// read input file
let infilePtr = sys.malloc(infile.size)
infile.pread(infilePtr, infile.size, 0)
// decode input image
const [imgw, imgh, channels, imageDataPtr] = graphics.decodeImage(infilePtr, infile.size) // stored as [R | G | B | (A)]
sys.free(infilePtr)
let hasAlpha = (4 == channels) && !noalpha
// encode image
let ipfBlockCount = Math.ceil(imgw / 4.0) * Math.ceil(imgh / 4.0)
let ipfSizePerBlock = 12 + 4*(ipfType - 1) + 8*hasAlpha
let ipfRawSize = ipfSizePerBlock * ipfBlockCount
let ipfarea = sys.malloc(ipfRawSize)
let gzippedImage = sys.malloc(28 + ipfRawSize+8) // ipf file header + somewhat arbitrary number. Get the actual count using 28+gzlen
encodefun(imageDataPtr, ipfarea, imgw, imgh, channels, hasAlpha, 0)
let gzlen = gzip.compFromTo(ipfarea, ipfRawSize, gzippedImage + 28)
sys.free(ipfarea)
// write to the output bin
//// write header
;[
0x1F, 0x54, 0x53, 0x56, 0x4D, 0x69, 0x50, 0x46, // magic
imgw & 255, (imgw >> 8) & 255, // width
imgh & 255, (imgh >> 8) & 255, // height
0+hasAlpha, // has alpha
ipfType, // ipf type
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // reserved
(gzlen >>> 0) & 255, // uncompressed size
(gzlen >>> 8) & 255,
(gzlen >>> 16) & 255,
(gzlen >>> 24) & 255
].forEach((b,i) => sys.poke(gzippedImage + i, b))
outfile.mkFile()
outfile.pwrite(gzippedImage, 28 + gzlen, 0)
//dma.ramToCom(writeBuf, 0, writeCount)
sys.free(gzippedImage)
println(`Wrote ${28 + gzlen} bytes to the file`)

BIN
assets/disk0/ycocg.ipf1 Normal file

Binary file not shown.

BIN
assets/disk0/ycocg.ipf2 Normal file

Binary file not shown.

BIN
assets/disk0/ycocg2.ipf1 Normal file

Binary file not shown.

BIN
assets/disk0/ycocg2.ipf2 Normal file

Binary file not shown.

View File

@@ -413,13 +413,13 @@ TYPE 255 FRAME -
TSVM Interchangeable Picture Format (aka iPF Type 1/2)
Image is divided into 4x4 blocks and each block is serialised, then the entire file is gzipped
Image is divided into 4x4 blocks and each block is serialised, then the entire iPF blocks are gzipped
# File Structure
\x1F T S V M i P F
[HEADER]
[Blocks.gz] or [Blocks] // gzipping is optional and only done for videos
[Blocks.gz]
- Header
uint16 WIDTH

View File

@@ -6,7 +6,7 @@ import java.io.ByteArrayOutputStream
import java.util.zip.GZIPInputStream
import java.util.zip.GZIPOutputStream
class CompressorDelegate(val vm: VM) {
class CompressorDelegate(private val vm: VM) {
fun comp(str: String) = Companion.comp(str)
fun comp(ba: ByteArray) = Companion.comp(ba)

View File

@@ -6,7 +6,7 @@ import net.torvald.tsvm.peripheral.GraphicsAdapter
/**
* Created by minjaesong on 2021-10-15.
*/
class DMADelegate(val vm: VM) {
class DMADelegate(private val vm: VM) {
private val READ = "READ".toByteArray(VM.CHARSET)
private val FLUSH = "FLUSH".toByteArray(VM.CHARSET)

View File

@@ -8,7 +8,7 @@ import net.torvald.tsvm.peripheral.GraphicsAdapter
import net.torvald.tsvm.peripheral.fmod
import kotlin.math.roundToInt
class GraphicsJSR223Delegate(val vm: VM) {
class GraphicsJSR223Delegate(private val vm: VM) {
private fun getFirstGPU(): GraphicsAdapter? {
return vm.findPeribyType(VM.PERITYPE_GPU_AND_TERM)?.peripheral as? GraphicsAdapter

View File

@@ -137,7 +137,7 @@ object SerialHelper {
data class DeviceStatus(val code: Int, val message: String)
}
class SerialHelperDelegate(val vm: VM) {
class SerialHelperDelegate(private val vm: VM) {
fun sendMessage(portNo: Int, message: String) = SerialHelper.sendMessage(vm, portNo, message.toByteArray(VM.CHARSET))
fun pullMessage(portNo: Int) = SerialHelper.pullMessage(vm, portNo).toString(VM.CHARSET)
fun sendMessageGetBytes(portNo: Int, message: String) = SerialHelper.sendMessageGetBytes(vm, portNo, message.toByteArray(VM.CHARSET)).toString(VM.CHARSET)

View File

@@ -11,7 +11,7 @@ import java.nio.charset.Charset
/**
* Pass the instance of the class to the ScriptEngine's binding, preferably under the namespace of "vm"
*/
class VMJSR223Delegate(val vm: VM) {
class VMJSR223Delegate(private val vm: VM) {
fun poke(addr: Int, value: Int) = vm.poke(addr.toLong(), value.toByte())
fun peek(addr: Int) = vm.peek(addr.toLong())!!.toInt().and(255)
@@ -186,13 +186,13 @@ class VMJSR223Delegate(val vm: VM) {
}
}
class VMSerialDebugger(val vm: VM) {
class VMSerialDebugger(private val vm: VM) {
fun print(s: Any?) = System.out.print("$s")
fun println(s: Any?) = System.out.println("$s")
fun printerr(s: Any?) = System.err.println("$s")
}
class Parallel(val vm: VM) {
class Parallel(private val vm: VM) {
fun spawnNewContext(): VMRunner {
return VMRunnerFactory(vm.assetsDir, vm, "js")
}