More experimentation.

This commit is contained in:
Martin Haye 2016-12-28 08:00:28 -08:00
parent ccdbbb970b
commit 1d421aacf2
2 changed files with 30 additions and 39 deletions

View File

@ -1212,6 +1212,8 @@ class A2PackPartitions
fonts[name] = [num:num, buf:readBinary(path)] fonts[name] = [num:num, buf:readBinary(path)]
} }
static int lx47Uncomp = 0
static int lx47Comp = 0
static int lx47Savings = 0 static int lx47Savings = 0
// Transform the LZ4 format to something we call "LZ4M", where the small offsets are stored // Transform the LZ4 format to something we call "LZ4M", where the small offsets are stored
@ -1292,8 +1294,11 @@ class A2PackPartitions
lx47.decompress(outputData, uncomp) lx47.decompress(outputData, uncomp)
assert uncomp == inputData assert uncomp == inputData
def savings = inLen - outputData.length def savings = inLen - outputData.length
lx47Uncomp += uncompLen
lx47Comp += (uncompLen - outputData.length)
lx47Savings += savings lx47Savings += savings
println String.format("lz47 savings=%d total=%d", savings, lx47Savings) println String.format("lz47 savings=%d total_uncomp=%d total_comp=%d total_savings=%d",
savings, lx47Uncomp, lx47Comp, lx47Savings)
} }
// Transform the LZ4 format to something we call "LZ4M", where the small offsets are stored // Transform the LZ4 format to something we call "LZ4M", where the small offsets are stored
@ -1411,8 +1416,8 @@ class A2PackPartitions
assert compressedLen > 0 assert compressedLen > 0
// Then recompress to LZ4M (pretty much always smaller) // Then recompress to LZ4M (pretty much always smaller)
testLx47(compressedData, compressedLen, uncompressedData, uncompressedLen)
def recompressedLen = recompress(compressedData, compressedLen, uncompressedData, uncompressedLen) def recompressedLen = recompress(compressedData, compressedLen, uncompressedData, uncompressedLen)
testLx47(compressedData, recompressedLen, uncompressedData, uncompressedLen)
// If we saved at least 20 bytes, take the compressed version. // If we saved at least 20 bytes, take the compressed version.
if ((uncompressedLen - recompressedLen) >= 20) { if ((uncompressedLen - recompressedLen) >= 20) {

View File

@ -37,6 +37,10 @@ public class Lx47Algorithm
return bits; return bits;
} }
int elias_exp_gamma_bits(int value, int exp) {
return elias_gamma_bits((value >> exp) + 1) + exp;
}
int count_bits(int offset, int len) { int count_bits(int offset, int len) {
return 1 + (offset > 128 ? 12 : 8) + elias_gamma_bits(len-1); return 1 + (offset > 128 ? 12 : 8) + elias_gamma_bits(len-1);
} }
@ -108,8 +112,6 @@ public class Lx47Algorithm
return optimal; return optimal;
} }
static int nBigLits = 0;
static int nBigMatches = 0;
static int nOffsets = 0; static int nOffsets = 0;
static int nPrevOffsets = 0; static int nPrevOffsets = 0;
static int nPrev2Offsets = 0; static int nPrev2Offsets = 0;
@ -153,25 +155,14 @@ public class Lx47Algorithm
void writeEliasExpGamma(int value, int exp) { void writeEliasExpGamma(int value, int exp) {
assert value > 0; assert value > 0;
writeEliasGamma(((value-1) >> exp) + 1); writeEliasGamma((value >> exp) + 1);
for (int i=exp-1; i>=0; i--) for (int i=exp-1; i>=0; i--) {
writeBit(value & (1<<i)); writeBit(value & (1<<i));
} }
void writeLiteralLen(int value) {
writeEliasExpGamma(value, 1);
while (value > 255) {
nBigLits++;
value -= 255;
}
} }
void writeMatchLen(int value) { void writeMatchLen(int value) {
writeEliasExpGamma(value, 1); writeEliasGamma(value);
while (value > 255) {
nBigMatches++;
value -= 255;
}
} }
void write2byte(int offset) { void write2byte(int offset) {
@ -187,21 +178,8 @@ public class Lx47Algorithm
} }
} }
int prevOff = -1;
int prevOff2 = -1;
void writeOffset(int offset) { void writeOffset(int offset) {
write2byte(offset); write2byte(offset);
if (offset >= 126) {
++nOffsets;
if (offset == prevOff)
++nPrevOffsets;
else if (offset == prevOff2)
++nPrev2Offsets;
prevOff2 = prevOff;
prevOff = offset;
}
//writeEliasExpGamma(offset, 7) // same; other values worse
} }
} }
@ -248,11 +226,10 @@ public class Lx47Algorithm
w.writeBit(1); w.writeBit(1);
/* sequence length */ /* sequence length */
w.writeEliasGamma(optimal[input_index].len-1); w.writeMatchLen(optimal[input_index].len-1);
/* sequence offset */ /* sequence offset */
offset1 = optimal[input_index].offset-1; w.writeOffset(optimal[input_index].offset-1);
w.writeOffset(offset1);
} }
} }
@ -310,8 +287,17 @@ public class Lx47Algorithm
return out; return out;
} }
int readLiteralLen() { int readEliasExpGamma(int exp) {
return readEliasGamma(); int val = readEliasGamma();
if (val < 0)
return val;
val = (val-1) << exp;
for (int i=exp-1; i>=0; i--) {
int bit = readBit();
if (bit > 0)
val |= (1<<i);
}
return val;
} }
int readMatchLen() { int readMatchLen() {
@ -362,12 +348,12 @@ public class Lx47Algorithm
} }
// Not a literal, so it's a sequence. First get the length. // Not a literal, so it's a sequence. First get the length.
int len = r.readEliasGamma() + 1; int len = r.readMatchLen() + 1;
if (len < 0) // EOF mark? if (len < 0) // EOF mark?
break; break;
// Then get offset, and copy data // Then get offset, and copy data
int off = r.read2byte() + 1; int off = r.readOffset() + 1;
chkDebug(String.format("seq l=%d o=%d", len, off)); chkDebug(String.format("seq l=%d o=%d", len, off));
while (len-- > 0) { while (len-- > 0) {
output_data[outPos] = output_data[outPos - off]; output_data[outPos] = output_data[outPos - off];