Better encoding of offset=64

This commit is contained in:
Martin Haye 2017-01-02 09:06:11 -08:00
parent 0e4c7df743
commit 917a6561f7
2 changed files with 60 additions and 61 deletions

View File

@ -50,9 +50,10 @@ public class Lx47Algorithm
}
int countCodePair(int prevLits, int matchLen, int offset) {
assert offset >= 1;
int nBits = (prevLits>0 ? 0 : 1)
+ 8 // 8 for the byte that's always emitted
+ (offset>=64 ? countGammaBits(offset>>6) : 0)
+ ((offset-1)>=64 ? countGammaBits((offset-1)>>6) : 0)
+ (matchLen>2 ? countGammaBits(matchLen-2) : 0);
return nBits;
}
@ -60,10 +61,10 @@ public class Lx47Algorithm
int countLitBits(int lits) {
if (lits == 0)
return 0;
int bits = lits * 8;
int bits = (lits * 8) + 1;
while (lits > 0) {
int n = Math.min(255, lits);
bits += 1 + countGammaBits(n);
bits += countGammaBits(n);
lits -= n;
}
return bits;
@ -203,16 +204,12 @@ public class Lx47Algorithm
}
void writeLiteralLen(int value) {
if (value == 0)
writeBit(0);
else {
writeBit(1);
writeGamma(value);
}
writeGamma(value);
}
void writeCodePair(int matchLen, int offset)
{
offset -= 1;
int data = offset & 63; // 6 bits
if (offset >= 64)
@ -271,6 +268,7 @@ public class Lx47Algorithm
// Literal string
int pos = input_index - optimal[input_index].lits + 1;
w.writeBit((optimal[input_index].lits > 0) ? 1 : 0);
while (optimal[input_index].lits > 0) {
int n = Math.min(255, optimal[input_index].lits);
addDebug("lits l=%d", n);
@ -288,7 +286,7 @@ public class Lx47Algorithm
// Sequence. If two in a row, insert a zero-length lit str
if (!prevIsLit) {
addDebug("lits l=0");
w.writeLiteralLen(0);
w.writeBit(0);
}
// Now write sequence info
@ -304,7 +302,7 @@ public class Lx47Algorithm
// EOF marker
if (!prevIsLit) {
addDebug("lits l=0");
w.writeLiteralLen(0);
w.writeBit(0);
}
addDebug("EOF");
@ -349,8 +347,7 @@ public class Lx47Algorithm
}
int readLiteralLen() {
int b = readBit();
return (b==0) ? 0 : readGamma();
return readGamma();
}
int readCodePair()
@ -360,9 +357,10 @@ public class Lx47Algorithm
int matchLen = 2;
if ((data & 64) == 64)
offset |= readGamma() << 6;
offset++;
if ((data & 128) == 128)
matchLen += readGamma();
return matchLen | (offset<<16);
return matchLen | (offset<<16); // pack both vals into a single int
}
}
@ -386,16 +384,20 @@ public class Lx47Algorithm
while (true)
{
// Check for literal string
while (true) {
len = r.readLiteralLen();
chkDebug("lits l=%d", len);
for (int i=0; i<len; i++) {
output_data[outPos++] = (byte) r.readByte();
chkDebug("lit $%x", output_data[outPos-1]);
if (r.readBit() != 0) {
while (true) {
len = r.readLiteralLen();
chkDebug("lits l=%d", len);
for (int i=0; i<len; i++) {
output_data[outPos++] = (byte) r.readByte();
chkDebug("lit $%x", output_data[outPos-1]);
}
if (len != 255)
break;
}
if (len != 255)
break;
}
else
chkDebug("lits l=0");
// Check for EOF at the end of each literal string
if (outPos == outStart+outLen)

View File

@ -34,12 +34,13 @@ pDst = $E ; len 2
; before it gets used.
decomp ldy #0 ; invariant: Y=0 unless we're mid-copy
sty bits
beq .lits
.lits jsr rdGamma
.lits lsr bits
bne +
jsr getBits
+ bcc .seq
.lits2 jsr rdGamma
tax
dex
beq +
- lda (pSrc),y
sta (pDst),y
iny
@ -47,49 +48,49 @@ decomp ldy #0 ; invariant: Y=0 unless we're mid-copy
bne -
jsr advSrc
jsr advDst
cpy #254 ; special case: long literal string
beq .lits
iny ; special case: long literal string marked by len=255
beq .lits2
ldy #0 ; back to invariant
.endchk cmp pEnd
.endchk cmp pEnd ; check for done at end of each literal string
bcc .seq
lda pDst+1
sbc pEnd+1
cmp pEnd+1
bcc .seq
rts
.seq lda (pSrc),y
iny
asl
inc pSrc
bne +
inc pSrc+1
+ asl
php ; save high bit for later len check
asl
bcs .bigoff
lsr
bmi .bigoff
lsr
sta tmp
ldx #0
beq .gotoff ; always taken
.bigoff sta tmp
sty tmp+1 ; zero
bcc .gotoff ; always taken
.bigoff asl
sta tmp
jsr rdGamma
lsr
rol tmp
lsr
rol tmp
tax
sta tmp+1
.gotoff lda pDst
sec
clc ; effectively add 1 to offset.
sbc tmp
sta pTmp
txa
eor #$FF
adc pDst+1
sta pDst+1
lda pDst+1
sbc tmp+1
sta pTmp+1
.len ldx #2
plp
bcc .gotlen
jsr rdGamma ; A>=1 + sec + 1 => final len 3 or more
adc #1
jsr rdGamma
adc #1 ; A>=1 + sec + 1 => final len 3 or more
tax
.gotlen jsr advSrc
ldy #0
.gotlen
- lda (pTmp),y
sta (pDst),y
iny
@ -113,25 +114,21 @@ rdGamma lda #1
getBits pha
lda (pSrc),y
iny
sec
inc pSrc
bne +
inc pSrc+1
+ sec
rol
sta bits
pla
rts
advDst inx
inx
advSrc tya
clc
adc pSrc
sta pSrc
adc pSrc,x
sta pSrc,x
bcc +
inc pSrc+1
+ rts
advDst tya
clc
adc pDst
sta pDst
bcc +
inc pDst+1
inc pSrc+1,x
+ rts