aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJuan J. Martinez <jjm@usebox.net>2022-02-26 15:44:56 +0000
committerJuan J. Martinez <jjm@usebox.net>2022-02-26 15:44:56 +0000
commitccca016a9d02fb7ac14c0553f765288c14125df7 (patch)
tree0ff36feffe4ddf45986bf83b4f363478e3e131c1
parent1acd6982100865edf10a3838da1b16446a8dd8ec (diff)
downloadubox-msx-lib-ccca016a9d02fb7ac14c0553f765288c14125df7.tar.gz
ubox-msx-lib-ccca016a9d02fb7ac14c0553f765288c14125df7.zip
Updated apultra to 1.4.6
-rw-r--r--CHANGES.md2
-rw-r--r--tools/apultra/src/apultra.c2
-rw-r--r--tools/apultra/src/matchfinder.c60
-rw-r--r--tools/apultra/src/shrink.c172
4 files changed, 117 insertions, 119 deletions
diff --git a/CHANGES.md b/CHANGES.md
index abba299..33f6c09 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -1,6 +1,6 @@
## Release 1.x.x - 2021-??-??
- - Updated apultra to 1.4.5
+ - Updated apultra to 1.4.6
## Release 1.1.9 - 2021-12-29
diff --git a/tools/apultra/src/apultra.c b/tools/apultra/src/apultra.c
index 4800ff6..a6c3c38 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.5"
+#define TOOL_VERSION "1.4.6"
/*---------------------------------------------------------------------------*/
diff --git a/tools/apultra/src/matchfinder.c b/tools/apultra/src/matchfinder.c
index a9987f9..7b17e0e 100644
--- a/tools/apultra/src/matchfinder.c
+++ b/tools/apultra/src/matchfinder.c
@@ -241,25 +241,20 @@ int apultra_find_matches_at(apultra_compressor *pCompressor, const int nOffset,
unsigned short *cur_depth = NULL;
if (nOffset >= match_pos && (nBlockFlags & 3) == 3) {
- int nMatchOffset = (int)(nOffset - match_pos);
- int nMatchLen = (int)(ref >> (LCP_SHIFT + TAG_BITS));
+ const int nMatchOffset = (const int)(nOffset - match_pos);
if ((matchptr - pMatches) < nMaxMatches) {
+ const int nMatchLen = (const int)(ref >> (LCP_SHIFT + TAG_BITS));
+
if (nMatchOffset <= nMaxOffset) {
- if (nPrevOffset && nPrevLen > 2 && nMatchOffset == (nPrevOffset - 1) && nMatchLen == (nPrevLen - 1) && cur_depth && nCurDepth < LCP_MAX) {
- nCurDepth++;
- *cur_depth = nCurDepth;
- }
- else {
- nCurDepth = 0;
+ nCurDepth = 0;
- cur_depth = depthptr;
- matchptr->length = nMatchLen;
- matchptr->offset = nMatchOffset;
- *depthptr = 0;
- matchptr++;
- depthptr++;
- }
+ cur_depth = depthptr;
+ matchptr->length = nMatchLen;
+ matchptr->offset = nMatchOffset;
+ *depthptr = 0;
+ matchptr++;
+ depthptr++;
nPrevLen = nMatchLen;
nPrevOffset = nMatchOffset;
@@ -272,10 +267,11 @@ int apultra_find_matches_at(apultra_compressor *pCompressor, const int nOffset,
match_pos = intervals[super_ref & POS_MASK] & EXCL_VISITED_MASK;
if (nOffset >= match_pos && (nBlockFlags & 3) == 3) {
- int nMatchOffset = (int)(nOffset - match_pos);
- int nMatchLen = (int)(ref >> (LCP_SHIFT + TAG_BITS));
+ const int nMatchOffset = (const int)(nOffset - match_pos);
if ((matchptr - pMatches) < nMaxMatches) {
+ const int nMatchLen = (const int)(ref >> (LCP_SHIFT + TAG_BITS));
+
if (nMatchOffset <= nMaxOffset && abs(nMatchOffset - nPrevOffset) >= 128) {
if (nPrevOffset && nPrevLen > 2 && nMatchOffset == (nPrevOffset - 1) && nMatchLen == (nPrevLen - 1) && cur_depth && nCurDepth < LCP_MAX) {
nCurDepth++;
@@ -303,10 +299,11 @@ int apultra_find_matches_at(apultra_compressor *pCompressor, const int nOffset,
match_pos = intervals[super_ref & POS_MASK] & EXCL_VISITED_MASK;
if (nOffset > match_pos && (nBlockFlags & 3) == 3) {
- int nMatchOffset = (int)(nOffset - match_pos);
- int nMatchLen = (int)(ref >> (LCP_SHIFT + TAG_BITS));
+ const int nMatchOffset = (const int)(nOffset - match_pos);
if ((matchptr - pMatches) < nMaxMatches) {
+ const int nMatchLen = (const int)(ref >> (LCP_SHIFT + TAG_BITS));
+
if (nMatchOffset <= nMaxOffset && (nMatchLen >= 3 || (nMatchLen >= 2 && (matchptr - pMatches) < (nMaxMatches - 1))) && nMatchLen < 1280 && abs(nMatchOffset - nPrevOffset) >= 128) {
if (nPrevOffset && nPrevLen > 2 && nMatchOffset == (nPrevOffset - 1) && nMatchLen == (nPrevLen - 1) && cur_depth && nCurDepth < LCP_MAX) {
nCurDepth++;
@@ -333,12 +330,12 @@ int apultra_find_matches_at(apultra_compressor *pCompressor, const int nOffset,
intervals[ref & POS_MASK] = nOffset | VISITED_FLAG;
pos_data[match_pos] = (unsigned long long)ref;
- int nMatchOffset = (int)(nOffset - match_pos);
- int nMatchLen = (int)(ref >> (LCP_SHIFT + TAG_BITS));
+ const int nMainMatchOffset = (const int)(nOffset - match_pos);
+ const int nMainMatchLen = (const int)(ref >> (LCP_SHIFT + TAG_BITS));
if ((matchptr - pMatches) < nMaxMatches) {
- if (nMatchOffset <= nMaxOffset && nMatchOffset != nPrevOffset) {
- if (nPrevOffset && nPrevLen > 2 && nMatchOffset == (nPrevOffset - 1) && nMatchLen == (nPrevLen - 1) && cur_depth && nCurDepth < LCP_MAX) {
+ if (nMainMatchOffset <= nMaxOffset && nMainMatchOffset != nPrevOffset) {
+ if (nPrevOffset && nPrevLen > 2 && nMainMatchOffset == (nPrevOffset - 1) && nMainMatchLen == (nPrevLen - 1) && cur_depth && nCurDepth < LCP_MAX) {
nCurDepth++;
*cur_depth = nCurDepth;
}
@@ -346,20 +343,20 @@ int apultra_find_matches_at(apultra_compressor *pCompressor, const int nOffset,
nCurDepth = 0;
cur_depth = depthptr;
- matchptr->length = nMatchLen;
- matchptr->offset = nMatchOffset;
+ matchptr->length = nMainMatchLen;
+ matchptr->offset = nMainMatchOffset;
*depthptr = 0;
matchptr++;
depthptr++;
}
- nPrevLen = nMatchLen;
- nPrevOffset = nMatchOffset;
+ nPrevLen = nMainMatchLen;
+ nPrevOffset = nMainMatchOffset;
}
}
- if (nMatchOffset && nMatchOffset < 16 && nMatchLen)
- *pMatch1 = nMatchOffset;
+ if (nMainMatchOffset && nMainMatchOffset < 16 && nMainMatchLen)
+ *pMatch1 = nMainMatchOffset;
if (super_ref == 0)
break;
@@ -367,10 +364,11 @@ int apultra_find_matches_at(apultra_compressor *pCompressor, const int nOffset,
match_pos = intervals[ref & POS_MASK] & EXCL_VISITED_MASK;
if (nOffset > match_pos && (nBlockFlags & 3) == 3) {
- int nMatchOffset = (int)(nOffset - match_pos);
- int nMatchLen = (int)(ref >> (LCP_SHIFT + TAG_BITS));
+ const int nMatchOffset = (const int)(nOffset - match_pos);
if ((matchptr - pMatches) < nMaxMatches) {
+ const int nMatchLen = (const int)(ref >> (LCP_SHIFT + TAG_BITS));
+
if (nMatchOffset <= nMaxOffset && nMatchLen >= 2 && abs(nMatchOffset - nPrevOffset) >= 128) {
if (nPrevOffset && nPrevLen > 2 && nMatchOffset == (nPrevOffset - 1) && nMatchLen == (nPrevLen - 1) && cur_depth && nCurDepth < LCP_MAX) {
nCurDepth++;
diff --git a/tools/apultra/src/shrink.c b/tools/apultra/src/shrink.c
index fae7692..8e123e0 100644
--- a/tools/apultra/src/shrink.c
+++ b/tools/apultra/src/shrink.c
@@ -68,22 +68,22 @@ static const char _gamma2_size[2048] = {
* @return updated write index into output buffer, or -1 in case of an error
*/
static int apultra_write_bits(unsigned char *pOutData, int nOutOffset, const int nMaxOutDataSize, const int nValue, const int nBits, int *nCurBitsOffset, int *nCurBitShift) {
- int i;
+ if (nOutOffset >= 0) {
+ int i;
+
+ for (i = nBits - 1; i >= 0; i--) {
+ if ((*nCurBitShift) == -1) {
+ /* Allocate a new byte in the stream to pack bits in */
+ if (nOutOffset >= nMaxOutDataSize) return -1;
+ (*nCurBitsOffset) = nOutOffset;
+ (*nCurBitShift) = 7;
+ pOutData[nOutOffset++] = 0;
+ }
- if (nOutOffset < 0) return -1;
+ pOutData[(*nCurBitsOffset)] |= ((nValue >> i) & 1) << (*nCurBitShift);
- for (i = nBits - 1; i >= 0; i--) {
- if ((*nCurBitShift) == -1) {
- /* Allocate a new byte in the stream to pack bits in */
- if (nOutOffset >= nMaxOutDataSize) return -1;
- (*nCurBitsOffset) = nOutOffset;
- (*nCurBitShift) = 7;
- pOutData[nOutOffset++] = 0;
+ (*nCurBitShift)--;
}
-
- pOutData[(*nCurBitsOffset)] |= ((nValue >> i) & 1) << (*nCurBitShift);
-
- (*nCurBitShift) --;
}
return nOutOffset;
@@ -191,7 +191,7 @@ static inline int apultra_get_match_varlen_size(int nLength, const int nMatchOff
*/
static void apultra_insert_forward_match(apultra_compressor *pCompressor, const unsigned char *pInWindow, const int i, const int nMatchOffset, const int nStartOffset, const int nEndOffset, const int nArrivalsPerPosition, int nDepth) {
const apultra_arrival *arrival = pCompressor->arrival + ((i - nStartOffset) * nArrivalsPerPosition);
- const int *rle_len = (int*)pCompressor->intervals /* reuse */;
+ const int *rle_len = (const int*)pCompressor->intervals /* reuse */;
apultra_visited* visited = ((apultra_visited*)pCompressor->pos_data) - nStartOffset /* reuse */;
int j;
@@ -209,22 +209,22 @@ static void apultra_insert_forward_match(apultra_compressor *pCompressor, const
visited[nRepPos] = nMatchOffset;
if (nRepPos >= nMatchOffset && nRepOffset && pCompressor->match[((nRepPos - nStartOffset) << MATCHES_PER_INDEX_SHIFT) + NMATCHES_PER_INDEX - 1].length == 0) {
- const unsigned char* pInWindowAtRepOffset = pInWindow + nRepPos;
+ const unsigned char* pInWindowStart = pInWindow + nRepPos;
- if (!memcmp(pInWindowAtRepOffset, pInWindowAtRepOffset - nMatchOffset, 2)) {
+ if (!memcmp(pInWindowStart, pInWindowStart - nMatchOffset, 2)) {
const int nLen0 = rle_len[nRepPos - nMatchOffset];
const int nLen1 = rle_len[nRepPos];
- int nMinLen = (nLen0 < nLen1) ? nLen0 : nLen1;
+ const int nMinLen = (nLen0 < nLen1) ? nLen0 : nLen1;
int nMaxRepLen = nEndOffset - nRepPos;
if (nMaxRepLen > LCP_MAX)
nMaxRepLen = LCP_MAX;
- if (nMinLen > nMaxRepLen)
- nMinLen = nMaxRepLen;
+ const unsigned char* pInWindowMax = pInWindowStart + nMaxRepLen;
+ const unsigned char* pInWindowAtRepOffset = pInWindowStart + nMinLen;
- const unsigned char* pInWindowMax = pInWindowAtRepOffset + nMaxRepLen;
- pInWindowAtRepOffset += nMinLen;
+ if (pInWindowAtRepOffset > pInWindowMax)
+ pInWindowAtRepOffset = pInWindowMax;
while ((pInWindowAtRepOffset + 8) < pInWindowMax && !memcmp(pInWindowAtRepOffset, pInWindowAtRepOffset - nMatchOffset, 8))
pInWindowAtRepOffset += 8;
@@ -233,7 +233,7 @@ static void apultra_insert_forward_match(apultra_compressor *pCompressor, const
while (pInWindowAtRepOffset < pInWindowMax && pInWindowAtRepOffset[0] == pInWindowAtRepOffset[-nMatchOffset])
pInWindowAtRepOffset++;
- const int nCurRepLen = (int)(pInWindowAtRepOffset - (pInWindow + nRepPos));
+ const int nCurRepLen = (const int)(pInWindowAtRepOffset - pInWindowStart);
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);
@@ -280,28 +280,32 @@ static void apultra_insert_forward_match(apultra_compressor *pCompressor, const
*/
static void apultra_optimize_forward(apultra_compressor *pCompressor, const unsigned char *pInWindow, const int nStartOffset, const int nEndOffset, const int nInsertForwardReps, const int *nCurRepMatchOffset, const int nBlockFlags, const int nArrivalsPerPosition) {
apultra_arrival *arrival = pCompressor->arrival - (nStartOffset * nArrivalsPerPosition);
- const int* rle_len = (int*)pCompressor->intervals /* reuse */;
+ const int* rle_len = (const int*)pCompressor->intervals /* reuse */;
apultra_visited* visited = ((apultra_visited*)pCompressor->pos_data) - nStartOffset /* reuse */;
- int i, j, n;
+ apultra_arrival* cur_arrival;
+ int i;
if ((nEndOffset - nStartOffset) > pCompressor->block_size) return;
- memset(arrival + (nStartOffset * nArrivalsPerPosition), 0, sizeof(apultra_arrival) * ((nEndOffset - nStartOffset + 1) * nArrivalsPerPosition));
+ for (i = (nStartOffset * nArrivalsPerPosition); i != ((nEndOffset+1) * nArrivalsPerPosition); i += nArrivalsPerPosition) {
+ int j;
- arrival[nStartOffset * nArrivalsPerPosition].from_slot = -1;
- arrival[nStartOffset * nArrivalsPerPosition].rep_offset = *nCurRepMatchOffset;
+ memset(arrival + i, 0, sizeof(apultra_arrival) * nArrivalsPerPosition);
- for (i = (nStartOffset * nArrivalsPerPosition); i != ((nEndOffset+1) * nArrivalsPerPosition); i++) {
- arrival[i].cost = 0x40000000;
+ for (j = 0; j < nArrivalsPerPosition; j++)
+ arrival[i + j].cost = 0x40000000;
}
+ arrival[nStartOffset * nArrivalsPerPosition].cost = 0;
+ arrival[nStartOffset * nArrivalsPerPosition].from_slot = -1;
+ arrival[nStartOffset * nArrivalsPerPosition].rep_offset = *nCurRepMatchOffset;
+
if (nInsertForwardReps) {
memset(visited + nStartOffset, 0, (nEndOffset - nStartOffset) * sizeof(apultra_visited));
}
- for (i = nStartOffset; i != nEndOffset; i++) {
- apultra_arrival *cur_arrival = &arrival[i * nArrivalsPerPosition];
- int m;
+ for (i = nStartOffset, cur_arrival = &arrival[nStartOffset * nArrivalsPerPosition]; i != nEndOffset; i++, cur_arrival += nArrivalsPerPosition) {
+ int j, m;
const unsigned char nMatch1Offs = pCompressor->match1[i - nStartOffset];
int nShortOffset;
@@ -326,15 +330,14 @@ static void apultra_optimize_forward(apultra_compressor *pCompressor, const unsi
apultra_arrival* pDestSlots = &cur_arrival[nArrivalsPerPosition];
for (j = 0; j < nArrivalsPerPosition && cur_arrival[j].from_slot; j++) {
- const int nPrevCost = cur_arrival[j].cost & 0x3fffffff;
- const int nCodingChoiceCost = nPrevCost + nLiteralCost;
+ const int nCodingChoiceCost = cur_arrival[j].cost + nLiteralCost;
const int nScore = cur_arrival[j].score + nLiteralScore;
const int nRepOffset = cur_arrival[j].rep_offset;
if (nCodingChoiceCost < pDestSlots[nArrivalsPerPosition - 1].cost ||
(nCodingChoiceCost == pDestSlots[nArrivalsPerPosition - 1].cost && nScore < pDestSlots[nArrivalsPerPosition - 1].score &&
nRepOffset != pDestSlots[nArrivalsPerPosition - 1].rep_offset)) {
- int exists = 0;
+ int exists = 0, n;
for (n = 0;
pDestSlots[n].cost < nCodingChoiceCost;
@@ -395,8 +398,7 @@ static void apultra_optimize_forward(apultra_compressor *pCompressor, const unsi
}
else {
for (j = 0; j < nArrivalsPerPosition && cur_arrival[j].from_slot; j++) {
- const int nPrevCost = cur_arrival[j].cost & 0x3fffffff;
- const int nCodingChoiceCost = nPrevCost + nLiteralCost;
+ const int nCodingChoiceCost = cur_arrival[j].cost + nLiteralCost;
const int nScore = cur_arrival[j].score + nLiteralScore;
apultra_arrival* pDestArrival = &cur_arrival[nArrivalsPerPosition + j];
@@ -429,7 +431,6 @@ static void apultra_optimize_forward(apultra_compressor *pCompressor, const unsi
nMaxRepLenForPos = LCP_MAX;
const unsigned char* pInWindowStart = pInWindow + i;
const unsigned char* pInWindowMax = pInWindowStart + nMaxRepLenForPos;
- const int nLen1 = rle_len[i];
for (j = 0; j < nNumArrivalsForThisPos; j++) {
if (cur_arrival[j].follows_literal) {
@@ -439,12 +440,13 @@ static void apultra_optimize_forward(apultra_compressor *pCompressor, const unsi
if (!memcmp(pInWindowStart, pInWindowStart - nRepOffset, 2)) {
if (nRepOffset) {
const int nLen0 = rle_len[i - nRepOffset];
- int nMinLen = (nLen0 < nLen1) ? nLen0 : nLen1;
+ const int nLen1 = rle_len[i];
+ const int nMinLen = (nLen0 < nLen1) ? nLen0 : nLen1;
+ const unsigned char* pInWindowAtRepOffset = pInWindowStart + nMinLen;
- if (nMinLen > nMaxRepLenForPos)
- nMinLen = nMaxRepLenForPos;
+ if (pInWindowAtRepOffset > pInWindowMax)
+ pInWindowAtRepOffset = pInWindowMax;
- 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))
@@ -452,7 +454,7 @@ static void apultra_optimize_forward(apultra_compressor *pCompressor, const unsi
while (pInWindowAtRepOffset < pInWindowMax && pInWindowAtRepOffset[0] == pInWindowAtRepOffset[-nRepOffset])
pInWindowAtRepOffset++;
- const int nCurMaxLen = (int)(pInWindowAtRepOffset - pInWindowStart);
+ const int nCurMaxLen = (const int)(pInWindowAtRepOffset - pInWindowStart);
nRepMatchArrivalIdx[nNumRepMatchArrivals++] = j;
nRepMatchArrivalIdx[nNumRepMatchArrivals++] = nCurMaxLen;
@@ -468,18 +470,18 @@ static void apultra_optimize_forward(apultra_compressor *pCompressor, const unsi
nRepMatchArrivalIdx[nNumRepMatchArrivals] = -1;
for (m = 0; m < NMATCHES_PER_INDEX && match[m].length; m++) {
- const int nOrigMatchLen = match[m].length;
+ int nOrigMatchLen = match[m].length;
const int nOrigMatchOffset = match[m].offset;
const unsigned int nOrigMatchDepth = match_depth[m] & 0x3fff;
const int nScorePenalty = 3 + ((match_depth[m] & 0x8000) >> 15);
unsigned int d;
+ if ((i + nOrigMatchLen) > nEndOffset)
+ nOrigMatchLen = nEndOffset - i;
+
for (d = 0; d <= nOrigMatchDepth; d += (nOrigMatchDepth ? nOrigMatchDepth : 1)) {
+ const int nMatchLen = nOrigMatchLen - d;
const int nMatchOffset = nOrigMatchOffset - d;
- int nMatchLen = nOrigMatchLen - d;
-
- if ((i + nMatchLen) > nEndOffset)
- nMatchLen = nEndOffset - i;
if (nInsertForwardReps) {
apultra_insert_forward_match(pCompressor, pInWindow, i, nMatchOffset, nStartOffset, nEndOffset, nArrivalsPerPosition, 0);
@@ -542,9 +544,8 @@ 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) {
- const int nPrevCost = cur_arrival[j].cost & 0x3fffffff;
const int nMatchCmdCost = nNoRepMatchMatchLenCost + nNoRepMatchOffsetCostForLit[nFollowsLiteral];
- const int nCodingChoiceCost = nPrevCost + nMatchCmdCost;
+ const int nCodingChoiceCost = cur_arrival[j].cost + nMatchCmdCost;
if (nCodingChoiceCost <= (pDestSlots[nArrivalsPerPosition - 1].cost + 1)) {
const int nScore = cur_arrival[j].score + nScorePenalty;
@@ -552,7 +553,7 @@ static void apultra_optimize_forward(apultra_compressor *pCompressor, const unsi
if (nCodingChoiceCost < pDestSlots[nArrivalsPerPosition - 2].cost ||
(nCodingChoiceCost == pDestSlots[nArrivalsPerPosition - 2].cost && nScore < pDestSlots[nArrivalsPerPosition - 2].score &&
(nCodingChoiceCost != pDestSlots[nArrivalsPerPosition - 1].cost || nMatchOffset != pDestSlots[nArrivalsPerPosition - 1].rep_offset))) {
- int exists = 0;
+ int exists = 0, n;
for (n = 0;
pDestSlots[n].cost < nCodingChoiceCost;
@@ -640,15 +641,14 @@ static void apultra_optimize_forward(apultra_compressor *pCompressor, const unsi
for (nCurRepMatchArrival = 0; (j = nRepMatchArrivalIdx[nCurRepMatchArrival]) >= 0; nCurRepMatchArrival += 2) {
if (nRepMatchArrivalIdx[nCurRepMatchArrival + 1] >= k) {
- const int nPrevCost = cur_arrival[j].cost & 0x3fffffff;
- const int nRepCodingChoiceCost = nPrevCost + nRepMatchCmdCost;
+ const int nRepCodingChoiceCost = cur_arrival[j].cost + nRepMatchCmdCost;
const int nScore = cur_arrival[j].score + 2;
const int nRepOffset = cur_arrival[j].rep_offset;
if (nRepCodingChoiceCost < pDestSlots[nArrivalsPerPosition - 1].cost ||
(nRepCodingChoiceCost == pDestSlots[nArrivalsPerPosition - 1].cost && nScore < pDestSlots[nArrivalsPerPosition - 1].score &&
nRepOffset != pDestSlots[nArrivalsPerPosition - 1].rep_offset)) {
- int exists = 0;
+ int exists = 0, n;
for (n = 0;
pDestSlots[n].cost < nRepCodingChoiceCost;
@@ -733,10 +733,7 @@ static void apultra_optimize_forward(apultra_compressor *pCompressor, const unsi
while (end_arrival->from_slot > 0 && end_arrival->from_pos >= 0 && (int)end_arrival->from_pos < nEndOffset) {
pBestMatch[end_arrival->from_pos].length = end_arrival->match_len;
- if (end_arrival->match_len >= 2)
- pBestMatch[end_arrival->from_pos].offset = end_arrival->rep_offset;
- else
- pBestMatch[end_arrival->from_pos].offset = end_arrival->short_offset;
+ pBestMatch[end_arrival->from_pos].offset = (end_arrival->match_len >= 2) ? end_arrival->rep_offset : end_arrival->short_offset;
end_arrival = &arrival[(end_arrival->from_pos * nArrivalsPerPosition) + (end_arrival->from_slot - 1)];
}
@@ -811,7 +808,6 @@ static int apultra_reduce_commands(apultra_compressor *pCompressor, const unsign
(i + pMatch->length) < nEndOffset /* Don't consider the last match in the block, we can only reduce a match inbetween other tokens */) {
int nNextIndex = i + pMatch->length;
int nNextFollowsLiteral = 0;
- int nCannotEncode = 0;
while (nNextIndex < nEndOffset && pBestMatch[nNextIndex].length < 2) {
nNextIndex++;
@@ -819,6 +815,8 @@ static int apultra_reduce_commands(apultra_compressor *pCompressor, const unsign
}
if (nNextIndex < nEndOffset && pBestMatch[nNextIndex].length >= 2) {
+ int nCannotEncode = 0;
+
if (nRepMatchOffset && nRepMatchOffset != pMatch->offset && pBestMatch[nNextIndex].offset && pMatch->offset != pBestMatch[nNextIndex].offset &&
nNextFollowsLiteral) {
/* Try to gain a match forward */
@@ -965,7 +963,7 @@ static int apultra_reduce_commands(apultra_compressor *pCompressor, const unsign
/* Join large matches */
const int nMatchLen = pMatch->length;
- int nNextIndex = i + pMatch->length + pBestMatch[i + pMatch->length].length;
+ int nNextIndex = i + nMatchLen + pBestMatch[i + nMatchLen].length;
int nNextFollowsLiteral = 0;
int nCannotEncode = 0;
int nCurCommandSize, nReducedCommandSize;
@@ -976,10 +974,10 @@ static int apultra_reduce_commands(apultra_compressor *pCompressor, const unsign
}
if (pMatch->offset == nRepMatchOffset && nFollowsLiteral) {
- nCurCommandSize = TOKEN_SIZE_LARGE_MATCH + 2 /* apultra_get_gamma2_size(2) */ + apultra_get_gamma2_size(pMatch->length);
+ nCurCommandSize = TOKEN_SIZE_LARGE_MATCH + 2 /* apultra_get_gamma2_size(2) */ + apultra_get_gamma2_size(nMatchLen);
}
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(nMatchLen, pMatch->offset, nFollowsLiteral) + apultra_get_match_varlen_size(nMatchLen, 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);
@@ -994,10 +992,10 @@ static int apultra_reduce_commands(apultra_compressor *pCompressor, const unsign
}
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);
+ nReducedCommandSize = TOKEN_SIZE_LARGE_MATCH + 2 /* apultra_get_gamma2_size(2) */ + apultra_get_gamma2_size(nMatchLen + 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);
+ nReducedCommandSize = apultra_get_offset_varlen_size(nMatchLen + pBestMatch[i + nMatchLen].length, pMatch->offset, nFollowsLiteral) + apultra_get_match_varlen_size(nMatchLen + pBestMatch[i + nMatchLen].length, pMatch->offset);
}
if (nNextIndex < nEndOffset && pBestMatch[nNextIndex].length >= 2) {
@@ -1017,8 +1015,8 @@ static int apultra_reduce_commands(apultra_compressor *pCompressor, const unsign
if (!nCannotEncode) {
if (nCurCommandSize >= nReducedCommandSize) {
pMatch->length += pBestMatch[i + nMatchLen].length;
+ pBestMatch[i + nMatchLen].length = 0;
pBestMatch[i + nMatchLen].offset = 0;
- pBestMatch[i + nMatchLen].length = -1;
nDidReduce = 1;
continue;
}
@@ -1060,29 +1058,31 @@ static int apultra_reduce_commands(apultra_compressor *pCompressor, const unsign
*
* @return size of compressed data in output buffer, or -1 if the data is uncompressible
*/
-static int apultra_write_block(apultra_compressor *pCompressor, apultra_final_match *pBestMatch, const unsigned char *pInWindow, const int nStartOffset, const int nEndOffset, unsigned char *pOutData, int nOutOffset, const int nMaxOutDataSize, int *nCurBitsOffset, int *nCurBitShift, int *nFollowsLiteral, int *nCurRepMatchOffset, const int nBlockFlags) {
+static int apultra_write_block(apultra_compressor *pCompressor, apultra_final_match *pBestMatch, const unsigned char *pInWindow, const int nStartOffset, const int nEndOffset, unsigned char *pOutData, const int nMaxOutDataSize, int *nCurBitsOffset, int *nCurBitShift, int *nFollowsLiteral, int *nCurRepMatchOffset, const int nBlockFlags) {
int i;
int nRepMatchOffset = *nCurRepMatchOffset;
+ int nCurFollowsLiteral = *nFollowsLiteral;
+ int nOutOffset = 0;
const int nMaxOffset = pCompressor->max_offset;
if (nBlockFlags & 1) {
- if (nOutOffset < 0 || nOutOffset >= nMaxOutDataSize)
+ if (nMaxOutDataSize <= 0)
return -1;
pOutData[nOutOffset++] = pInWindow[nStartOffset];
- *nFollowsLiteral = 1;
+ nCurFollowsLiteral = 1;
}
for (i = nStartOffset + ((nBlockFlags & 1) ? 1 : 0); i < nEndOffset; ) {
const apultra_final_match *pMatch = pBestMatch + i;
if (pMatch->length >= 2) {
- const int nMatchOffset = pMatch->offset;
const int nMatchLen = pMatch->length;
+ const int nMatchOffset = pMatch->offset;
if (nMatchOffset < MIN_OFFSET || nMatchOffset > nMaxOffset)
return -1;
- if (nMatchOffset == nRepMatchOffset && *nFollowsLiteral) {
+ if (nMatchOffset == nRepMatchOffset && nCurFollowsLiteral) {
/* Rep-match */
nOutOffset = apultra_write_bits(pOutData, nOutOffset, nMaxOutDataSize, TOKEN_CODE_LARGE_MATCH, TOKEN_SIZE_LARGE_MATCH, nCurBitsOffset, nCurBitShift);
nOutOffset = apultra_write_bits(pOutData, nOutOffset, nMaxOutDataSize, 0 /* length of 2 encoded as gamma 2 */, 2, nCurBitsOffset, nCurBitShift);
@@ -1091,7 +1091,7 @@ static int apultra_write_block(apultra_compressor *pCompressor, apultra_final_ma
nOutOffset = apultra_write_gamma2_value(pOutData, nOutOffset, nMaxOutDataSize, nMatchLen, nCurBitsOffset, nCurBitShift);
if (nOutOffset < 0) return -1;
- *nFollowsLiteral = 0;
+ nCurFollowsLiteral = 0;
pCompressor->stats.num_rep_matches++;
}
@@ -1104,7 +1104,7 @@ static int apultra_write_block(apultra_compressor *pCompressor, apultra_final_ma
return -1;
pOutData[nOutOffset++] = ((nMatchOffset) & 0x7f) << 1 | (nMatchLen - 2);
- *nFollowsLiteral = 0;
+ nCurFollowsLiteral = 0;
nRepMatchOffset = nMatchOffset;
pCompressor->stats.num_7bit_matches++;
@@ -1112,14 +1112,12 @@ static int apultra_write_block(apultra_compressor *pCompressor, apultra_final_ma
else {
/* 8+n bits offset */
nOutOffset = apultra_write_bits(pOutData, nOutOffset, nMaxOutDataSize, TOKEN_CODE_LARGE_MATCH, TOKEN_SIZE_LARGE_MATCH, nCurBitsOffset, nCurBitShift);
+ nOutOffset = apultra_write_gamma2_value(pOutData, nOutOffset, nMaxOutDataSize, (nMatchOffset >> 8) + 2 + (nCurFollowsLiteral & 1), nCurBitsOffset, nCurBitShift);
+ const unsigned char nLowMatchBits = nMatchOffset & 0xff;
if (nOutOffset < 0 || nOutOffset >= nMaxOutDataSize)
return -1;
- if (*nFollowsLiteral)
- nOutOffset = apultra_write_gamma2_value(pOutData, nOutOffset, nMaxOutDataSize, (nMatchOffset >> 8) + 3, nCurBitsOffset, nCurBitShift);
- else
- nOutOffset = apultra_write_gamma2_value(pOutData, nOutOffset, nMaxOutDataSize, (nMatchOffset >> 8) + 2, nCurBitsOffset, nCurBitShift);
- pOutData[nOutOffset++] = nMatchOffset & 0xff;
+ pOutData[nOutOffset++] = nLowMatchBits;
/* The match length isn't encoded in the command, emit elias gamma value */
@@ -1131,7 +1129,7 @@ static int apultra_write_block(apultra_compressor *pCompressor, apultra_final_ma
nOutOffset = apultra_write_gamma2_value(pOutData, nOutOffset, nMaxOutDataSize, nMatchLen - 1, nCurBitsOffset, nCurBitShift);
if (nOutOffset < 0) return -1;
- *nFollowsLiteral = 0;
+ nCurFollowsLiteral = 0;
nRepMatchOffset = nMatchOffset;
pCompressor->stats.num_variable_matches++;
@@ -1188,7 +1186,7 @@ static int apultra_write_block(apultra_compressor *pCompressor, apultra_final_ma
pCompressor->stats.commands_divisor++;
i++;
- *nFollowsLiteral = 1;
+ nCurFollowsLiteral = 1;
}
else {
/* Literal */
@@ -1202,7 +1200,7 @@ static int apultra_write_block(apultra_compressor *pCompressor, apultra_final_ma
pCompressor->stats.num_literals++;
pCompressor->stats.commands_divisor++;
i++;
- *nFollowsLiteral = 1;
+ nCurFollowsLiteral = 1;
}
const int nCurSafeDist = (i - nStartOffset) - nOutOffset;
@@ -1227,6 +1225,8 @@ static int apultra_write_block(apultra_compressor *pCompressor, apultra_final_ma
}
*nCurRepMatchOffset = nRepMatchOffset;
+ *nFollowsLiteral = nCurFollowsLiteral;
+
return nOutOffset;
}
@@ -1248,7 +1248,6 @@ static int apultra_write_block(apultra_compressor *pCompressor, apultra_final_ma
* @return size of compressed data in output buffer, or -1 if the data is uncompressible
*/
static int apultra_optimize_and_write_block(apultra_compressor *pCompressor, const unsigned char *pInWindow, const int nPreviousBlockSize, const int nInDataSize, unsigned char *pOutData, const int nMaxOutDataSize, int *nCurBitsOffset, int *nCurBitShift, int *nCurFollowsLiteral, int *nCurRepMatchOffset, const int nBlockFlags) {
- int nOutOffset = 0;
const int nEndOffset = nPreviousBlockSize + nInDataSize;
const int nArrivalsPerPosition = pCompressor->max_arrivals;
int *rle_len = (int*)pCompressor->intervals /* reuse */;
@@ -1314,11 +1313,12 @@ static int apultra_optimize_and_write_block(apultra_compressor *pCompressor, con
i = 0;
while (i < nEndOffset) {
int nRangeStartIdx = i;
- unsigned char c = pInWindow[nRangeStartIdx];
+ const unsigned char c = pInWindow[nRangeStartIdx];
+
do {
i++;
- }
- while (i < nEndOffset && pInWindow[i] == c);
+ } while (i < nEndOffset && pInWindow[i] == c);
+
while (nRangeStartIdx < i) {
rle_len[nRangeStartIdx] = i - nRangeStartIdx;
nRangeStartIdx++;
@@ -1396,7 +1396,7 @@ static int apultra_optimize_and_write_block(apultra_compressor *pCompressor, con
if (nGotMatch) {
int nMatchLen = 2;
- while (nMatchLen < 16 && nPosition < (nEndOffset - nMatchLen) && pInWindow[nMatchPos + nMatchLen] == pInWindow[nPosition + nMatchLen])
+ while (nMatchLen < 16 && (nPosition + nMatchLen) < nEndOffset && pInWindow[nMatchPos + nMatchLen] == pInWindow[nPosition + nMatchLen])
nMatchLen++;
match[m].length = nMatchLen;
match[m].offset = nMatchOffset;
@@ -1433,7 +1433,7 @@ static int apultra_optimize_and_write_block(apultra_compressor *pCompressor, con
/* Write compressed block */
- return apultra_write_block(pCompressor, pCompressor->best_match - nPreviousBlockSize, pInWindow, nPreviousBlockSize, nEndOffset, pOutData, nOutOffset, nMaxOutDataSize, nCurBitsOffset, nCurBitShift, nCurFollowsLiteral, nCurRepMatchOffset, nBlockFlags);
+ return apultra_write_block(pCompressor, pCompressor->best_match - nPreviousBlockSize, pInWindow, nPreviousBlockSize, nEndOffset, pOutData, nMaxOutDataSize, nCurBitsOffset, nCurBitShift, nCurFollowsLiteral, nCurRepMatchOffset, nBlockFlags);
}
/* Forward declaration */