zstd compression

This commit is contained in:
minjaesong
2024-01-11 22:27:19 +09:00
parent 234eb8e45f
commit c520c72141
9 changed files with 49 additions and 18 deletions

13
.idea/libraries/aircompressor_0_25.xml generated Normal file
View File

@@ -0,0 +1,13 @@
<component name="libraryTable">
<library name="aircompressor-0.25">
<CLASSES>
<root url="jar://$PROJECT_DIR$/lib/aircompressor-0.25.jar!/" />
</CLASSES>
<JAVADOC>
<root url="jar://$PROJECT_DIR$/lib/aircompressor-0.25-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://$PROJECT_DIR$/lib/aircompressor-0.25-sources.jar!/" />
</SOURCES>
</library>
</component>

View File

@@ -1,12 +1,12 @@
// some manual configurations // some manual configurations
// //
let IPFMODE = 2 // 1 or 2 let IPFMODE = 1 // 1 or 2
let TOTAL_FRAMES = 3813 let TOTAL_FRAMES = 6636
let FPS = 30 // must be integer let FPS = 15 // must be integer
let WIDTH = 560 let WIDTH = 560
let HEIGHT = 448 let HEIGHT = 448
let PATHFUN = (i) => `/ddol2/${(''+i).padStart(5,'0')}.png` // how can be the image file found, if a frame number (starts from 1) were given let PATHFUN = (i) => `C:/steamboat/${(''+i).padStart(5,'0')}.png` // how can be the image file found, if a frame number (starts from 1) were given
let AUDIOTRACK = 'ddol.mp2' let AUDIOTRACK = 'C:/steamboat.mp2'
let AUDIOFORMAT = 'MP2fr' // undefined or PCMu8 or MP2fr let AUDIOFORMAT = 'MP2fr' // undefined or PCMu8 or MP2fr
// to export video to its frames (with automatic scaling and cropping): // to export video to its frames (with automatic scaling and cropping):
// ffmpeg -i file.mp4 -vf scale=560:448:force_original_aspect_ratio=increase,crop=560:448 file/%05d.png // ffmpeg -i file.mp4 -vf scale=560:448:force_original_aspect_ratio=increase,crop=560:448 file/%05d.png

Binary file not shown.

Binary file not shown.

BIN
lib/aircompressor-0.25.jar Normal file

Binary file not shown.

View File

@@ -440,26 +440,26 @@ Packet Types -
GLOBAL TYPE 0 Packet - GLOBAL TYPE 0 Packet -
uint32 SIZE OF FRAMEDATA uint32 SIZE OF FRAMEDATA
* FRAMEDATA COMPRESSED IN GZIP * COMPRESSED FRAMEDATA
GLOBAL TYPE 1 Packet - GLOBAL TYPE 1 Packet -
byte[512] Palette Data byte[512] Palette Data
uint32 SIZE OF FRAMEDATA uint32 SIZE OF FRAMEDATA
* FRAMEDATA COMPRESSED IN GZIP * COMPRESSED FRAMEDATA
GLOBAL TYPE 2 Packet - GLOBAL TYPE 2 Packet -
uint32 SIZE OF FRAMEDATA BYTE-PLANE 1 uint32 SIZE OF FRAMEDATA BYTE-PLANE 1
* FRAMEDATA COMPRESSED IN GZIP * COMPRESSED FRAMEDATA
uint32 SIZE OF FRAMEDATA BYTE-PLANE 2 uint32 SIZE OF FRAMEDATA BYTE-PLANE 2
* FRAMEDATA COMPRESSED IN GZIP * COMPRESSED FRAMEDATA
GLOBAL iPF Packet - GLOBAL iPF Packet -
uint32 SIZE OF FRAMEDATA uint32 SIZE OF FRAMEDATA
* FRAMEDATA COMPRESSED IN GZIP // only the actual gzip (and no UNCOMPRESSED SIZE) of the "Blocks.gz" is stored * COMPRESSED FRAMEDATA // only the actual gzip (and no UNCOMPRESSED SIZE) of the "Blocks.gz" is stored
GLOBAL TYPE 16+ Packet - GLOBAL TYPE 16+ Packet -
uint32 SIZE OF FRAMEDATA BYTE-PLANE 1 uint32 SIZE OF FRAMEDATA BYTE-PLANE 1
* FRAMEDATA (COMPRESSED IN GZIP for TGA/GZ) * FRAMEDATA (COMPRESSED for TGA/GZ)
MP2 Packet & ADPCM Packet - MP2 Packet & ADPCM Packet -
uint16 TYPE OF PACKET // follows the Metadata Packet Type scheme uint16 TYPE OF PACKET // follows the Metadata Packet Type scheme
@@ -487,6 +487,12 @@ Frame Timing
needs explicit "sync" packet for proper frame timing. needs explicit "sync" packet for proper frame timing.
Comperssion Method
Old standard used Gzip, new standard is Zstd.
tsvm will read the zip header and will use appropriate decompression method, so that the old Gzipped
files remain compatible.
NOTE FROM DEVELOPER NOTE FROM DEVELOPER
In the future, the global packet type will be deprecated. In the future, the global packet type will be deprecated.

View File

@@ -1,6 +1,9 @@
package net.torvald.tsvm package net.torvald.tsvm
import com.badlogic.gdx.utils.compression.Lzma import com.badlogic.gdx.utils.compression.Lzma
import io.airlift.compress.zstd.ZstdInputStream
import io.airlift.compress.zstd.ZstdOutputStream
import net.torvald.terrarum.modulecomputers.virtualcomputer.tvd.toUint
import java.io.ByteArrayInputStream import java.io.ByteArrayInputStream
import java.io.ByteArrayOutputStream import java.io.ByteArrayOutputStream
import java.util.zip.GZIPInputStream import java.util.zip.GZIPInputStream
@@ -77,13 +80,14 @@ class CompressorDelegate(private val vm: VM) {
companion object { companion object {
val GZIP_HEADER = byteArrayOf(31, -117, 8) // .gz in DEFLATE val GZIP_HEADER = byteArrayOf(31, -117, 8) // .gz in DEFLATE
val ZSTD_HEADER = byteArrayOf(40, -75, 47, -3)
fun comp(str: String) = comp(str.toByteArray(VM.CHARSET)) fun comp(str: String) = comp(str.toByteArray(VM.CHARSET))
fun comp(ba: ByteArray): ByteArray { fun comp(ba: ByteArray): ByteArray {
val baos = ByteArrayOutputStream() val baos = ByteArrayOutputStream()
val gz = GZIPOutputStream(baos) val gz = ZstdOutputStream(baos)
gz.write(ba); gz.flush(); gz.finish() gz.write(ba); gz.flush(); gz.close()
baos.flush(); baos.close() baos.flush(); baos.close()
return baos.toByteArray() return baos.toByteArray()
} }
@@ -92,10 +96,16 @@ class CompressorDelegate(private val vm: VM) {
fun decomp(str: String) = decomp(str.toByteArray(VM.CHARSET)) fun decomp(str: String) = decomp(str.toByteArray(VM.CHARSET))
fun decomp(ba: ByteArray): ByteArray { fun decomp(ba: ByteArray): ByteArray {
val header = ba[0].toUint().shl(24) or ba[1].toUint().shl(16) or ba[2].toUint().shl(8) or ba[3].toUint()
val bais = ByteArrayInputStream(ba) val bais = ByteArrayInputStream(ba)
val gz = GZIPInputStream(bais) val zis = when (header) {
val ret = gz.readBytes() in 0x1F8B0800..0x1F8B08FF -> GZIPInputStream(bais)
gz.close(); bais.close() 0x28B52FFD -> ZstdInputStream(bais)
else -> throw Error()
}
val ret = zis.readBytes()
zis.close(); bais.close()
return ret return ret
} }
} }

View File

@@ -4,6 +4,7 @@ import com.badlogic.gdx.Gdx
import com.badlogic.gdx.files.FileHandle import com.badlogic.gdx.files.FileHandle
import net.torvald.tsvm.CompressorDelegate import net.torvald.tsvm.CompressorDelegate
import net.torvald.tsvm.CompressorDelegate.Companion.GZIP_HEADER import net.torvald.tsvm.CompressorDelegate.Companion.GZIP_HEADER
import net.torvald.tsvm.CompressorDelegate.Companion.ZSTD_HEADER
import net.torvald.tsvm.VM import net.torvald.tsvm.VM
import java.io.File import java.io.File
import kotlin.experimental.xor import kotlin.experimental.xor
@@ -27,9 +28,9 @@ open class VMProgramRom {
fun readAll(): String { fun readAll(): String {
// check if bios is compressed in gzip // check if bios is compressed in gzip
return if (contents.startsWith(byteArrayOf(31, -85, 26))) return if (contents.startsWith(dec(GZIP_HEADER)) || contents.startsWith(dec(ZSTD_HEADER)))
CompressorDelegate.decomp(dec(contents)).toString(VM.CHARSET) CompressorDelegate.decomp(dec(contents)).toString(VM.CHARSET)
else if (contents.startsWith(GZIP_HEADER)) else if (contents.startsWith(GZIP_HEADER) || contents.startsWith(ZSTD_HEADER))
CompressorDelegate.decomp(contents).toString(VM.CHARSET) CompressorDelegate.decomp(contents).toString(VM.CHARSET)
else else
contents.toString(VM.CHARSET) contents.toString(VM.CHARSET)

View File

@@ -14,5 +14,6 @@
<orderEntry type="library" name="jetbrains.kotlin.stdlib.jdk8" level="project" /> <orderEntry type="library" name="jetbrains.kotlin.stdlib.jdk8" level="project" />
<orderEntry type="library" name="jetbrains.kotlin.reflect" level="project" /> <orderEntry type="library" name="jetbrains.kotlin.reflect" level="project" />
<orderEntry type="library" name="jetbrains.kotlin.test" level="project" /> <orderEntry type="library" name="jetbrains.kotlin.test" level="project" />
<orderEntry type="library" name="aircompressor-0.25" level="project" />
</component> </component>
</module> </module>