From 11a569e72365370fc908de56b8a05da754980bf3 Mon Sep 17 00:00:00 2001 From: "Juan J. Martinez" Date: Mon, 6 Dec 2021 22:14:14 +0000 Subject: Update apultra to 1.4.4 --- tools/apultra/asm/68000/unaplib_68000.S | 3 +- tools/apultra/src/apultra.c | 2 +- tools/apultra/src/shrink.c | 242 ++++++++++++++++++-------------- 3 files changed, 137 insertions(+), 110 deletions(-) (limited to 'tools') 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; } } -- cgit v1.2.3