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)]
}
static int lx47Uncomp = 0
static int lx47Comp = 0
static int lx47Savings = 0
// 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)
assert uncomp == inputData
def savings = inLen - outputData.length
lx47Uncomp += uncompLen
lx47Comp += (uncompLen - outputData.length)
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
@ -1411,8 +1416,8 @@ class A2PackPartitions
assert compressedLen > 0
// Then recompress to LZ4M (pretty much always smaller)
testLx47(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 ((uncompressedLen - recompressedLen) >= 20) {

View File

@ -36,6 +36,10 @@ public class Lx47Algorithm
}
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) {
return 1 + (offset > 128 ? 12 : 8) + elias_gamma_bits(len-1);
@ -108,8 +112,6 @@ public class Lx47Algorithm
return optimal;
}
static int nBigLits = 0;
static int nBigMatches = 0;
static int nOffsets = 0;
static int nPrevOffsets = 0;
static int nPrev2Offsets = 0;
@ -153,25 +155,14 @@ public class Lx47Algorithm
void writeEliasExpGamma(int value, int exp) {
assert value > 0;
writeEliasGamma(((value-1) >> exp) + 1);
for (int i=exp-1; i>=0; i--)
writeEliasGamma((value >> exp) + 1);
for (int i=exp-1; i>=0; i--) {
writeBit(value & (1<<i));
}
void writeLiteralLen(int value) {
writeEliasExpGamma(value, 1);
while (value > 255) {
nBigLits++;
value -= 255;
}
}
void writeMatchLen(int value) {
writeEliasExpGamma(value, 1);
while (value > 255) {
nBigMatches++;
value -= 255;
}
writeEliasGamma(value);
}
void write2byte(int offset) {
@ -187,21 +178,8 @@ public class Lx47Algorithm
}
}
int prevOff = -1;
int prevOff2 = -1;
void writeOffset(int 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);
/* sequence length */
w.writeEliasGamma(optimal[input_index].len-1);
w.writeMatchLen(optimal[input_index].len-1);
/* sequence offset */
offset1 = optimal[input_index].offset-1;
w.writeOffset(offset1);
w.writeOffset(optimal[input_index].offset-1);
}
}
@ -309,9 +286,18 @@ public class Lx47Algorithm
out = (out << 1) | readBit();
return out;
}
int readLiteralLen() {
return readEliasGamma();
int readEliasExpGamma(int exp) {
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() {
@ -362,12 +348,12 @@ public class Lx47Algorithm
}
// 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?
break;
// 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));
while (len-- > 0) {
output_data[outPos] = output_data[outPos - off];