aboutsummaryrefslogtreecommitdiff
path: root/tools/apultra
diff options
context:
space:
mode:
authorJuan J. Martinez <jjm@usebox.net>2021-12-06 22:14:14 +0000
committerJuan J. Martinez <jjm@usebox.net>2021-12-06 22:14:14 +0000
commit11a569e72365370fc908de56b8a05da754980bf3 (patch)
tree8f62d170a53afc69566efbf9e26fce1b7cb6e338 /tools/apultra
parentb7883d2690720a02f440959ea3f32a9105618213 (diff)
downloadubox-msx-lib-11a569e72365370fc908de56b8a05da754980bf3.tar.gz
ubox-msx-lib-11a569e72365370fc908de56b8a05da754980bf3.zip
Update apultra to 1.4.4
Diffstat (limited to 'tools/apultra')
-rw-r--r--tools/apultra/asm/68000/unaplib_68000.S3
-rw-r--r--tools/apultra/src/apultra.c2
-rw-r--r--tools/apultra/src/shrink.c242
3 files changed, 137 insertions, 110 deletions
diff --git a/tools/apultra/asm/68000/unaplib_68000.S b/tools/apultra/asm/68000/unaplib_68000.S
index a60ae32..4ecf6ac 100644
--- a/tools/apultra/asm/68000/unaplib_68000.S
+++ b/tools/apultra/asm/68000/unaplib_68000.S
@@ -1,4 +1,4 @@
-; unaplib_68000.s - aPLib decompressor for 68000 - 154 bytes
+; unaplib_68000.s - aPLib decompressor for 68000 - 156 bytes
;
; in: a0 = start of compressed data
; a1 = start of decompression buffer
@@ -87,6 +87,7 @@ apl_decompress:
addx.b d0,d0 ; shift second bit into d0
bsr.s .get_dibits ; read a data bit into d0, one into carry
addx.b d0,d0 ; shift second bit into d0
+ tst.b d0 ; check offset value
beq.s .write_zero ; if offset is zero, write a 0
move.l a1,a6 ; calculate backreference address
diff --git a/tools/apultra/src/apultra.c b/tools/apultra/src/apultra.c
index d59a415..e4a867e 100644
--- a/tools/apultra/src/apultra.c
+++ b/tools/apultra/src/apultra.c
@@ -45,7 +45,7 @@
#define OPT_STATS 2
#define OPT_BACKWARD 4
-#define TOOL_VERSION "1.4.2"
+#define TOOL_VERSION "1.4.4"
/*---------------------------------------------------------------------------*/
diff --git a/tools/apultra/src/shrink.c b/tools/apultra/src/shrink.c
index 5859790..6dfb0cf 100644
--- a/tools/apultra/src/shrink.c
+++ b/tools/apultra/src/shrink.c
@@ -49,9 +49,9 @@
#define CountShift(N,bits) if ((N)>>(bits)) { (N)>>=(bits); (n) += (bits); }
-/** Gamma2 bit counts for common values, up to 255 */
-static char _gamma2_size[256] = {
- 0, 0, 2, 2, 4, 4, 4, 4, 6, 6, 6, 6, 6, 6, 6, 6, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+/** Gamma2 bit counts for common values, up to 2047 */
+static const char _gamma2_size[2048] = {
+ 0, 0, 2, 2, 4, 4, 4, 4, 6, 6, 6, 6, 6, 6, 6, 6, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
};
/**
@@ -73,7 +73,7 @@ static int apultra_write_bits(unsigned char *pOutData, int nOutOffset, const int
if (nOutOffset < 0) return -1;
for (i = nBits - 1; i >= 0; i--) {
- if ((*nCurBitsOffset) == INT_MIN) {
+ if ((*nCurBitShift) == -1) {
/* Allocate a new byte in the stream to pack bits in */
if (nOutOffset >= nMaxOutDataSize) return -1;
(*nCurBitsOffset) = nOutOffset;
@@ -84,10 +84,6 @@ static int apultra_write_bits(unsigned char *pOutData, int nOutOffset, const int
pOutData[(*nCurBitsOffset)] |= ((nValue >> i) & 1) << (*nCurBitShift);
(*nCurBitShift) --;
- if ((*nCurBitShift) == -1) {
- /* Current byte is full */
- (*nCurBitsOffset) = INT_MIN;
- }
}
return nOutOffset;
@@ -101,7 +97,7 @@ static int apultra_write_bits(unsigned char *pOutData, int nOutOffset, const int
* @return number of bits required
*/
static int apultra_get_gamma2_size(int nValue) {
- if (nValue >= 0 && nValue < 256)
+ if (nValue >= 0 && nValue < 2048)
return _gamma2_size[nValue];
else {
unsigned int n = 0;
@@ -132,16 +128,12 @@ static int apultra_write_gamma2_value(unsigned char *pOutData, int nOutOffset, c
while ((nValue >> msb--) == 0);
while (msb > 0) {
- int bit = (nValue >> msb) & 1;
+ const int bit = (nValue >> msb--) & 1;
- nOutOffset = apultra_write_bits(pOutData, nOutOffset, nMaxOutDataSize, bit, 1, nCurBitsOffset, nCurBitShift);
- msb--;
- nOutOffset = apultra_write_bits(pOutData, nOutOffset, nMaxOutDataSize, 1, 1, nCurBitsOffset, nCurBitShift);
+ nOutOffset = apultra_write_bits(pOutData, nOutOffset, nMaxOutDataSize, (bit << 1) | 1, 2, nCurBitsOffset, nCurBitShift);
}
- nOutOffset = apultra_write_bits(pOutData, nOutOffset, nMaxOutDataSize, nValue & 1, 1, nCurBitsOffset, nCurBitShift);
- nOutOffset = apultra_write_bits(pOutData, nOutOffset, nMaxOutDataSize, 0, 1, nCurBitsOffset, nCurBitShift);
- return nOutOffset;
+ return apultra_write_bits(pOutData, nOutOffset, nMaxOutDataSize, (nValue & 1) << 1, 2, nCurBitsOffset, nCurBitShift);
}
/**
@@ -205,10 +197,10 @@ static void apultra_insert_forward_match(apultra_compressor *pCompressor, const
for (j = 0; j < nArrivalsPerPosition && arrival[j].from_slot; j++) {
if (arrival[j].follows_literal) {
- int nRepOffset = arrival[j].rep_offset;
+ const int nRepOffset = arrival[j].rep_offset;
- if (nMatchOffset != nRepOffset && nRepOffset) {
- int nRepPos = arrival[j].rep_pos;
+ if (nMatchOffset != nRepOffset) {
+ const int nRepPos = arrival[j].rep_pos;
if (nRepPos >= nStartOffset &&
(nRepPos + 1) < nEndOffset &&
@@ -222,51 +214,53 @@ static void apultra_insert_forward_match(apultra_compressor *pCompressor, const
if (!memcmp(pInWindowAtRepOffset, pInWindowAtRepOffset - nMatchOffset, 2)) {
visited[nRepPos].inner = nMatchOffset;
- int nLen0 = rle_len[nRepPos - nMatchOffset];
- int nLen1 = rle_len[nRepPos];
- int nMinLen = (nLen0 < nLen1) ? nLen0 : nLen1;
+ if (nRepOffset) {
+ const int nLen0 = rle_len[nRepPos - nMatchOffset];
+ const int nLen1 = rle_len[nRepPos];
+ int nMinLen = (nLen0 < nLen1) ? nLen0 : nLen1;
- int nMaxRepLen = nEndOffset - nRepPos;
- if (nMaxRepLen > LCP_MAX)
- nMaxRepLen = LCP_MAX;
+ int nMaxRepLen = nEndOffset - nRepPos;
+ if (nMaxRepLen > LCP_MAX)
+ nMaxRepLen = LCP_MAX;
- if (nMinLen > nMaxRepLen)
- nMinLen = nMaxRepLen;
+ if (nMinLen > nMaxRepLen)
+ nMinLen = nMaxRepLen;
- const unsigned char* pInWindowMax = pInWindowAtRepOffset + nMaxRepLen;
- pInWindowAtRepOffset += nMinLen;
+ const unsigned char* pInWindowMax = pInWindowAtRepOffset + nMaxRepLen;
+ pInWindowAtRepOffset += nMinLen;
- while ((pInWindowAtRepOffset + 8) < pInWindowMax && !memcmp(pInWindowAtRepOffset, pInWindowAtRepOffset - nMatchOffset, 8))
- pInWindowAtRepOffset += 8;
- while ((pInWindowAtRepOffset + 4) < pInWindowMax && !memcmp(pInWindowAtRepOffset, pInWindowAtRepOffset - nMatchOffset, 4))
- pInWindowAtRepOffset += 4;
- while (pInWindowAtRepOffset < pInWindowMax && pInWindowAtRepOffset[0] == pInWindowAtRepOffset[-nMatchOffset])
- pInWindowAtRepOffset++;
+ while ((pInWindowAtRepOffset + 8) < pInWindowMax && !memcmp(pInWindowAtRepOffset, pInWindowAtRepOffset - nMatchOffset, 8))
+ pInWindowAtRepOffset += 8;
+ while ((pInWindowAtRepOffset + 4) < pInWindowMax && !memcmp(pInWindowAtRepOffset, pInWindowAtRepOffset - nMatchOffset, 4))
+ pInWindowAtRepOffset += 4;
+ while (pInWindowAtRepOffset < pInWindowMax && pInWindowAtRepOffset[0] == pInWindowAtRepOffset[-nMatchOffset])
+ pInWindowAtRepOffset++;
- int nCurRepLen = (int)(pInWindowAtRepOffset - (pInWindow + nRepPos));
+ const int nCurRepLen = (int)(pInWindowAtRepOffset - (pInWindow + nRepPos));
- apultra_match* fwd_match = pCompressor->match + ((nRepPos - nStartOffset) << MATCHES_PER_INDEX_SHIFT);
- unsigned short* fwd_depth = pCompressor->match_depth + ((nRepPos - nStartOffset) << MATCHES_PER_INDEX_SHIFT);
- int r;
+ apultra_match* fwd_match = pCompressor->match + ((nRepPos - nStartOffset) << MATCHES_PER_INDEX_SHIFT);
+ unsigned short* fwd_depth = pCompressor->match_depth + ((nRepPos - nStartOffset) << MATCHES_PER_INDEX_SHIFT);
+ int r;
- for (r = 0; fwd_match[r].length >= MIN_MATCH_SIZE; r++) {
- if (fwd_match[r].offset == nMatchOffset && (fwd_depth[r] & 0x3fff) == 0) {
- if ((int)fwd_match[r].length < nCurRepLen) {
- fwd_match[r].length = nCurRepLen;
- fwd_depth[r] = 0;
+ for (r = 0; fwd_match[r].length; r++) {
+ if (fwd_match[r].offset == nMatchOffset && (fwd_depth[r] & 0x3fff) == 0) {
+ if ((int)fwd_match[r].length < nCurRepLen) {
+ fwd_match[r].length = nCurRepLen;
+ fwd_depth[r] = 0;
+ }
+ r = NMATCHES_PER_INDEX;
+ break;
}
- r = NMATCHES_PER_INDEX;
- break;
}
- }
- if (r < NMATCHES_PER_INDEX) {
- fwd_match[r].offset = nMatchOffset;
- fwd_match[r].length = nCurRepLen;
- fwd_depth[r] = 0;
+ if (r < NMATCHES_PER_INDEX) {
+ fwd_match[r].offset = nMatchOffset;
+ fwd_match[r].length = nCurRepLen;
+ fwd_depth[r] = 0;
- if (nDepth < 9)
- apultra_insert_forward_match(pCompressor, pInWindow, nRepPos, nMatchOffset, nStartOffset, nEndOffset, nArrivalsPerPosition, nDepth + 1);
+ if (nDepth < 9)
+ apultra_insert_forward_match(pCompressor, pInWindow, nRepPos, nMatchOffset, nStartOffset, nEndOffset, nArrivalsPerPosition, nDepth + 1);
+ }
}
}
}
@@ -333,15 +327,16 @@ static void apultra_optimize_forward(apultra_compressor *pCompressor, const unsi
nLiteralScore = nShortOffset ? 3 : 1;
if (cur_arrival[nArrivalsPerPosition].from_slot) {
+ apultra_arrival* pDestSlots = &cur_arrival[nArrivalsPerPosition];
+
for (j = 0; j < nArrivalsPerPosition && cur_arrival[j].from_slot; j++) {
- int nPrevCost = cur_arrival[j].cost & 0x3fffffff;
- int nCodingChoiceCost = nPrevCost + nLiteralCost;
- int nScore = cur_arrival[j].score + nLiteralScore;
+ const int nPrevCost = cur_arrival[j].cost & 0x3fffffff;
+ const int nCodingChoiceCost = nPrevCost + nLiteralCost;
+ const int nScore = cur_arrival[j].score + nLiteralScore;
- apultra_arrival* pDestSlots = &cur_arrival[nArrivalsPerPosition];
if (nCodingChoiceCost < pDestSlots[nArrivalsPerPosition - 1].cost ||
(nCodingChoiceCost == pDestSlots[nArrivalsPerPosition - 1].cost && nScore < pDestSlots[nArrivalsPerPosition - 1].score)) {
- int nRepOffset = cur_arrival[j].rep_offset;
+ const int nRepOffset = cur_arrival[j].rep_offset;
int exists = 0;
for (n = 0;
@@ -405,9 +400,9 @@ static void apultra_optimize_forward(apultra_compressor *pCompressor, const unsi
}
else {
for (j = 0; j < nArrivalsPerPosition && cur_arrival[j].from_slot; j++) {
- int nPrevCost = cur_arrival[j].cost & 0x3fffffff;
- int nCodingChoiceCost = nPrevCost + nLiteralCost;
- int nScore = cur_arrival[j].score + nLiteralScore;
+ const int nPrevCost = cur_arrival[j].cost & 0x3fffffff;
+ const int nCodingChoiceCost = nPrevCost + nLiteralCost;
+ const int nScore = cur_arrival[j].score + nLiteralScore;
apultra_arrival* pDestArrival = &cur_arrival[nArrivalsPerPosition + j];
@@ -427,7 +422,8 @@ static void apultra_optimize_forward(apultra_compressor *pCompressor, const unsi
const apultra_match *match = pCompressor->match + ((i - nStartOffset) << MATCHES_PER_INDEX_SHIFT);
const unsigned short *match_depth = pCompressor->match_depth + ((i - nStartOffset) << MATCHES_PER_INDEX_SHIFT);
- int nNumArrivalsForThisPos = j, nOverallMinRepLen = 0, nOverallMaxRepLen = 0;
+ const int nNumArrivalsForThisPos = j;
+ int nOverallMinRepLen = 0, nOverallMaxRepLen = 0;
int nRepMatchArrivalIdx[(2 * NARRIVALS_PER_POSITION_MAX) + 1];
int nNumRepMatchArrivals = 0;
@@ -442,27 +438,27 @@ static void apultra_optimize_forward(apultra_compressor *pCompressor, const unsi
for (j = 0; j < nNumArrivalsForThisPos; j++) {
if (cur_arrival[j].follows_literal) {
- int nRepOffset = cur_arrival[j].rep_offset;
+ const int nRepOffset = cur_arrival[j].rep_offset;
- if (nRepOffset && i >= nRepOffset) {
- if (pInWindowStart[0] == pInWindowStart[-nRepOffset]) {
- int nLen0 = rle_len[i - nRepOffset];
- int nMinLen = (nLen0 < nLen1) ? nLen0 : nLen1;
+ if (i >= nRepOffset) {
+ if (!memcmp(pInWindowStart, pInWindowStart - nRepOffset, 2)) {
+ if (nRepOffset) {
+ const int nLen0 = rle_len[i - nRepOffset];
+ int nMinLen = (nLen0 < nLen1) ? nLen0 : nLen1;
- if (nMinLen > nMaxRepLenForPos)
- nMinLen = nMaxRepLenForPos;
+ if (nMinLen > nMaxRepLenForPos)
+ nMinLen = nMaxRepLenForPos;
- const unsigned char* pInWindowAtRepOffset = pInWindowStart + nMinLen;
- while ((pInWindowAtRepOffset + 8) < pInWindowMax && !memcmp(pInWindowAtRepOffset, pInWindowAtRepOffset - nRepOffset, 8))
- pInWindowAtRepOffset += 8;
- while ((pInWindowAtRepOffset + 4) < pInWindowMax && !memcmp(pInWindowAtRepOffset, pInWindowAtRepOffset - nRepOffset, 4))
- pInWindowAtRepOffset += 4;
- while (pInWindowAtRepOffset < pInWindowMax && pInWindowAtRepOffset[0] == pInWindowAtRepOffset[-nRepOffset])
- pInWindowAtRepOffset++;
+ const unsigned char* pInWindowAtRepOffset = pInWindowStart + nMinLen;
+ while ((pInWindowAtRepOffset + 8) < pInWindowMax && !memcmp(pInWindowAtRepOffset, pInWindowAtRepOffset - nRepOffset, 8))
+ pInWindowAtRepOffset += 8;
+ while ((pInWindowAtRepOffset + 4) < pInWindowMax && !memcmp(pInWindowAtRepOffset, pInWindowAtRepOffset - nRepOffset, 4))
+ pInWindowAtRepOffset += 4;
+ while (pInWindowAtRepOffset < pInWindowMax && pInWindowAtRepOffset[0] == pInWindowAtRepOffset[-nRepOffset])
+ pInWindowAtRepOffset++;
- int nCurMaxLen = (int)(pInWindowAtRepOffset - pInWindowStart);
+ const int nCurMaxLen = (int)(pInWindowAtRepOffset - pInWindowStart);
- if (nCurMaxLen >= 2) {
nRepMatchArrivalIdx[nNumRepMatchArrivals++] = j;
nRepMatchArrivalIdx[nNumRepMatchArrivals++] = nCurMaxLen;
@@ -520,8 +516,7 @@ static void apultra_optimize_forward(apultra_compressor *pCompressor, const unsi
nJumpMatchLen = nMatchLen + 1;
if (nStartingMatchLen <= 3 && nMatchOffset < 128) {
- nNoRepMatchOffsetCostForLit[0] = 8 + TOKEN_SIZE_7BIT_MATCH;
- nNoRepMatchOffsetCostForLit[1] = 8 + TOKEN_SIZE_7BIT_MATCH;
+ nNoRepMatchOffsetCostForLit[1] = nNoRepMatchOffsetCostForLit[0] = 8 + TOKEN_SIZE_7BIT_MATCH;
}
else {
nNoRepMatchOffsetCostForLit[0] = 8 + TOKEN_SIZE_LARGE_MATCH + apultra_get_gamma2_size((nMatchOffset >> 8) + 2);
@@ -530,7 +525,7 @@ static void apultra_optimize_forward(apultra_compressor *pCompressor, const unsi
nNoRepMatchOffsetCostDelta = nNoRepMatchOffsetCostForLit[1] - nNoRepMatchOffsetCostForLit[0];
for (k = nStartingMatchLen; k <= nMatchLen; k++) {
- int nRepMatchMatchLenCost = apultra_get_gamma2_size(k);
+ const int nRepMatchMatchLenCost = apultra_get_gamma2_size(k);
apultra_arrival *pDestSlots = &cur_arrival[k * nArrivalsPerPosition];
/* Insert non-repmatch candidate */
@@ -552,12 +547,12 @@ static void apultra_optimize_forward(apultra_compressor *pCompressor, const unsi
for (j = 0; j < nNumArrivalsForThisPos; j++) {
const int nFollowsLiteral = cur_arrival[j].follows_literal;
if (nMatchOffset != cur_arrival[j].rep_offset || nFollowsLiteral == 0) {
- int nPrevCost = cur_arrival[j].cost & 0x3fffffff;
- int nMatchCmdCost = nNoRepMatchMatchLenCost + nNoRepMatchOffsetCostForLit[nFollowsLiteral];
- int nCodingChoiceCost = nPrevCost + nMatchCmdCost;
+ const int nPrevCost = cur_arrival[j].cost & 0x3fffffff;
+ const int nMatchCmdCost = nNoRepMatchMatchLenCost + nNoRepMatchOffsetCostForLit[nFollowsLiteral];
+ const int nCodingChoiceCost = nPrevCost + nMatchCmdCost;
if (nCodingChoiceCost <= (pDestSlots[nArrivalsPerPosition - 1].cost + 1)) {
- int nScore = cur_arrival[j].score + nScorePenalty;
+ const int nScore = cur_arrival[j].score + nScorePenalty;
if (nCodingChoiceCost < pDestSlots[nArrivalsPerPosition - 2].cost ||
(nCodingChoiceCost == pDestSlots[nArrivalsPerPosition - 2].cost && nScore < pDestSlots[nArrivalsPerPosition - 2].score)) {
@@ -573,7 +568,7 @@ static void apultra_optimize_forward(apultra_compressor *pCompressor, const unsi
}
if (!exists) {
- int nRevisedCodingChoiceCost = nCodingChoiceCost - nNoRepCostAdjusment;
+ const int nRevisedCodingChoiceCost = nCodingChoiceCost - nNoRepCostAdjusment;
for (;
n < nArrivalsPerPosition - 1 && pDestSlots[n].cost == nRevisedCodingChoiceCost && nScore >= pDestSlots[n].score;
@@ -641,7 +636,7 @@ static void apultra_optimize_forward(apultra_compressor *pCompressor, const unsi
/* Insert repmatch candidate */
if (k > nOverallMinRepLen && k <= nOverallMaxRepLen) {
- int nRepMatchCmdCost = TOKEN_SIZE_LARGE_MATCH + 2 /* apultra_get_gamma2_size(2) */ + nRepMatchMatchLenCost;
+ const int nRepMatchCmdCost = TOKEN_SIZE_LARGE_MATCH + 2 /* apultra_get_gamma2_size(2) */ + nRepMatchMatchLenCost;
int nCurRepMatchArrival;
if (k <= 90)
@@ -651,13 +646,13 @@ static void apultra_optimize_forward(apultra_compressor *pCompressor, const unsi
for (nCurRepMatchArrival = 0; (j = nRepMatchArrivalIdx[nCurRepMatchArrival]) >= 0; nCurRepMatchArrival += 2) {
if (nRepMatchArrivalIdx[nCurRepMatchArrival + 1] >= k) {
- int nPrevCost = cur_arrival[j].cost & 0x3fffffff;
- int nRepCodingChoiceCost = nPrevCost + nRepMatchCmdCost;
- int nScore = cur_arrival[j].score + 2;
+ const int nPrevCost = cur_arrival[j].cost & 0x3fffffff;
+ const int nRepCodingChoiceCost = nPrevCost + nRepMatchCmdCost;
+ const int nScore = cur_arrival[j].score + 2;
if (nRepCodingChoiceCost < pDestSlots[nArrivalsPerPosition - 1].cost ||
(nRepCodingChoiceCost == pDestSlots[nArrivalsPerPosition - 1].cost && nScore < pDestSlots[nArrivalsPerPosition - 1].score)) {
- int nRepOffset = cur_arrival[j].rep_offset;
+ const int nRepOffset = cur_arrival[j].rep_offset;
int exists = 0;
for (n = 0;
@@ -725,8 +720,7 @@ static void apultra_optimize_forward(apultra_compressor *pCompressor, const unsi
}
if (k == 3 && nMatchOffset < 128) {
- nNoRepMatchOffsetCostForLit[0] = 8 + TOKEN_SIZE_LARGE_MATCH + 2 /* apultra_get_gamma2_size((nMatchOffset >> 8) + 2) */;
- nNoRepMatchOffsetCostForLit[1] = 8 + TOKEN_SIZE_LARGE_MATCH + 2 /* apultra_get_gamma2_size((nMatchOffset >> 8) + 3) */;
+ nNoRepMatchOffsetCostForLit[1] = nNoRepMatchOffsetCostForLit[0] = 8 + TOKEN_SIZE_LARGE_MATCH + 2;
}
if (k == nJumpMatchLen)
@@ -966,7 +960,6 @@ static int apultra_reduce_commands(apultra_compressor *pCompressor, const unsign
if ((i + pMatch->length) < nEndOffset && pMatch->offset > 0 &&
pBestMatch[i + pMatch->length].offset > 0 &&
pBestMatch[i + pMatch->length].length >= 2 &&
- (pMatch->length + pBestMatch[i + pMatch->length].length) >= LEAVE_ALONE_MATCH_SIZE &&
(pMatch->length + pBestMatch[i + pMatch->length].length) <= MAX_VARLEN &&
(i + pMatch->length) >= pMatch->offset &&
(i + pMatch->length) >= pBestMatch[i + pMatch->length].offset &&
@@ -974,33 +967,66 @@ static int apultra_reduce_commands(apultra_compressor *pCompressor, const unsign
!memcmp(pInWindow + i + pMatch->length - pMatch->offset,
pInWindow + i + pMatch->length - pBestMatch[i + pMatch->length].offset,
pBestMatch[i + pMatch->length].length)) {
- int nMatchLen = pMatch->length;
-
/* Join large matches */
+ const int nMatchLen = pMatch->length;
int nNextIndex = i + pMatch->length + pBestMatch[i + pMatch->length].length;
int nNextFollowsLiteral = 0;
int nCannotEncode = 0;
+ int nCurCommandSize, nReducedCommandSize;
while (nNextIndex < nEndOffset && pBestMatch[nNextIndex].length < 2) {
nNextIndex++;
nNextFollowsLiteral = 1;
}
- if (nNextIndex < nEndOffset && nNextFollowsLiteral && pBestMatch[nNextIndex].length >= 2 &&
- pBestMatch[nNextIndex].offset == pBestMatch[i + pMatch->length].offset) {
- if ((pBestMatch[nNextIndex].offset >= MINMATCH3_OFFSET && pBestMatch[nNextIndex].length < 3) ||
- (pBestMatch[nNextIndex].offset >= MINMATCH4_OFFSET && pBestMatch[nNextIndex].length < 4)) {
- nCannotEncode = 1;
+ if (pMatch->offset == nRepMatchOffset && nFollowsLiteral) {
+ nCurCommandSize = TOKEN_SIZE_LARGE_MATCH + 2 /* apultra_get_gamma2_size(2) */ + apultra_get_gamma2_size(pMatch->length);
+ }
+ else {
+ nCurCommandSize = apultra_get_offset_varlen_size(pMatch->length, pMatch->offset, nFollowsLiteral) + apultra_get_match_varlen_size(pMatch->length, pMatch->offset);
+ }
+
+ nCurCommandSize += apultra_get_offset_varlen_size(pBestMatch[i + nMatchLen].length, pBestMatch[i + nMatchLen].offset, 0 /* follows literal */) + apultra_get_match_varlen_size(pBestMatch[i + nMatchLen].length, pBestMatch[i + nMatchLen].offset);
+
+ if (nNextIndex < nEndOffset && pBestMatch[nNextIndex].length >= 2) {
+ if (pBestMatch[nNextIndex].offset == pBestMatch[i + nMatchLen].offset && nNextFollowsLiteral) {
+ nCurCommandSize += TOKEN_SIZE_LARGE_MATCH + 2 /* apultra_get_gamma2_size(2) */ + apultra_get_gamma2_size(pBestMatch[nNextIndex].length);
+ }
+ else {
+ nCurCommandSize += apultra_get_offset_varlen_size(pBestMatch[nNextIndex].length, pBestMatch[nNextIndex].offset, nNextFollowsLiteral) + apultra_get_match_varlen_size(pBestMatch[nNextIndex].length, pBestMatch[nNextIndex].offset);
+ }
+ }
+
+ if (pMatch->offset == nRepMatchOffset && nFollowsLiteral) {
+ nReducedCommandSize = TOKEN_SIZE_LARGE_MATCH + 2 /* apultra_get_gamma2_size(2) */ + apultra_get_gamma2_size(pMatch->length + pBestMatch[i + nMatchLen].length);
+ }
+ else {
+ nReducedCommandSize = apultra_get_offset_varlen_size(pMatch->length + pBestMatch[i + nMatchLen].length, pMatch->offset, nFollowsLiteral) + apultra_get_match_varlen_size(pMatch->length + pBestMatch[i + nMatchLen].length, pMatch->offset);
+ }
+
+ if (nNextIndex < nEndOffset && pBestMatch[nNextIndex].length >= 2) {
+ if (pBestMatch[nNextIndex].offset == pMatch->offset && nNextFollowsLiteral) {
+ nReducedCommandSize += TOKEN_SIZE_LARGE_MATCH + 2 /* apultra_get_gamma2_size(2) */ + apultra_get_gamma2_size(pBestMatch[nNextIndex].length);
+ }
+ else {
+ nReducedCommandSize += apultra_get_offset_varlen_size(pBestMatch[nNextIndex].length, pBestMatch[nNextIndex].offset, nNextFollowsLiteral) + apultra_get_match_varlen_size(pBestMatch[nNextIndex].length, pBestMatch[nNextIndex].offset);
+
+ if ((pBestMatch[nNextIndex].offset >= MINMATCH3_OFFSET && pBestMatch[nNextIndex].length < 3) ||
+ (pBestMatch[nNextIndex].offset >= MINMATCH4_OFFSET && pBestMatch[nNextIndex].length < 4)) {
+ nCannotEncode = 1;
+ }
}
}
if (!nCannotEncode) {
- pMatch->length += pBestMatch[i + nMatchLen].length;
- pBestMatch[i + nMatchLen].offset = 0;
- pBestMatch[i + nMatchLen].length = -1;
- nDidReduce = 1;
- continue;
+ if (nCurCommandSize >= nReducedCommandSize) {
+ pMatch->length += pBestMatch[i + nMatchLen].length;
+ pBestMatch[i + nMatchLen].offset = 0;
+ pBestMatch[i + nMatchLen].length = -1;
+ nDidReduce = 1;
+ continue;
+ }
}
}
@@ -1662,7 +1688,7 @@ size_t apultra_compress(const unsigned char *pInputData, unsigned char *pOutBuff
int nPreviousBlockSize = 0;
int nNumBlocks = 0;
- int nCurBitsOffset = INT_MIN, nCurBitShift = 0, nCurFollowsLiteral = 0;
+ int nCurBitsOffset = 0, nCurBitShift = -1, nCurFollowsLiteral = 0;
int nBlockFlags = 1;
int nCurRepMatchOffset = 0;
@@ -1697,7 +1723,7 @@ size_t apultra_compress(const unsigned char *pInputData, unsigned char *pOutBuff
if (!nError) {
nOriginalSize += nInDataSize;
nCompressedSize += nOutDataSize;
- if (nCurBitsOffset != INT_MIN)
+ if (nCurBitShift != -1)
nCurBitsOffset -= nOutDataSize;
}
}