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.