2002-08-06 15:03:06 +00:00
|
|
|
zpage equ $f0 ; 11 bytes
|
|
|
|
inflate equ $b600
|
|
|
|
|
|
|
|
* 'Inflate'
|
2000-08-14 15:26:04 +00:00
|
|
|
; Written by Piotr Fusik (a.k.a. Fox/Taquart)
|
|
|
|
; Purpose: to uncompress Deflate format compressed data on 6502-based system.
|
|
|
|
|
|
|
|
* const
|
|
|
|
; Maximum length of a Huffman code
|
2002-08-06 15:03:06 +00:00
|
|
|
MAX_BITS equ 15
|
|
|
|
; Index in bitsCount, bitsPointer_l and bitsPointer_h
|
|
|
|
; for temporary tree and literal/length tree
|
|
|
|
PRIMARY_TREE equ 0
|
2000-08-14 15:26:04 +00:00
|
|
|
; Index in bitsCount, bitsPointer_l and bitsPointer_h for distance tree
|
2002-08-06 15:03:06 +00:00
|
|
|
DISTANCE_TREE equ MAX_BITS
|
2000-08-14 15:26:04 +00:00
|
|
|
; Size of each of bitsCount, bitsPointer_l and bitsPointer_h
|
2002-08-06 15:03:06 +00:00
|
|
|
TREES_SIZE equ 2*MAX_BITS
|
2000-08-14 15:26:04 +00:00
|
|
|
|
|
|
|
* page zero
|
|
|
|
; (public) Pointer to compressed data
|
2002-08-06 15:03:06 +00:00
|
|
|
inputPointer equ zpage ; 2 bytes
|
2000-08-14 15:26:04 +00:00
|
|
|
; (public) Pointer to uncompressed data
|
2002-08-06 15:03:06 +00:00
|
|
|
outputPointer equ zpage+2 ; 2 bytes
|
|
|
|
; Local variables
|
|
|
|
getBit_hold equ zpage+10 ; 1 byte
|
|
|
|
|
|
|
|
inflateDynamicBlock_cnt equ zpage+4 ; 1 byte
|
|
|
|
inflateCodes_src equ zpage+4 ; 2 bytes
|
|
|
|
buildHuffmanTree_src equ zpage+4 ; 2 bytes
|
|
|
|
getNextLength_last equ zpage+4 ; 1 byte
|
|
|
|
getNextLength_index equ zpage+5 ; 1 byte
|
|
|
|
|
|
|
|
buildHuffmanTree_ptr equ zpage+6 ; 2 bytes
|
|
|
|
fetchCode_ptr equ zpage+6 ; 2 bytes
|
|
|
|
getBits_tmp equ zpage+6 ; 1 byte
|
|
|
|
|
|
|
|
moveBlock_len equ zpage+8 ; 2 bytes
|
|
|
|
inflateDynamicBlock_np equ zpage+8 ; 1 byte
|
|
|
|
inflateDynamicBlock_nd equ zpage+9 ; 1 byte
|
2000-08-14 15:26:04 +00:00
|
|
|
|
|
|
|
* code
|
|
|
|
org inflate
|
|
|
|
* (public) inflate
|
2002-08-06 15:03:06 +00:00
|
|
|
; Decompress Deflate data pointed by inputPointer
|
2000-08-14 15:26:04 +00:00
|
|
|
; to memory at outputPointer
|
2002-08-06 15:03:06 +00:00
|
|
|
mvy #1 getBit_hold
|
|
|
|
bne inflate_2 !
|
|
|
|
inflate_1
|
|
|
|
jsr inflate_3
|
|
|
|
inflate_2
|
2000-08-14 15:26:04 +00:00
|
|
|
; Get a bit of EOF and two bits of block type
|
2002-08-06 15:03:06 +00:00
|
|
|
ldx #3
|
2000-08-14 15:26:04 +00:00
|
|
|
lda #0
|
|
|
|
jsr getBits
|
|
|
|
lsr @
|
2002-08-06 15:03:06 +00:00
|
|
|
bcc inflate_1
|
|
|
|
inflate_3
|
|
|
|
bne inflateCompressedBlock
|
2000-08-14 15:26:04 +00:00
|
|
|
|
|
|
|
* inflateCopyBlock
|
2002-08-06 15:03:06 +00:00
|
|
|
; Decompress 'stored' data block
|
2000-08-14 15:26:04 +00:00
|
|
|
inflateCopyBlock
|
|
|
|
; Ignore bits until byte boundary
|
2002-08-06 15:03:06 +00:00
|
|
|
mvy #1 getBit_hold
|
2000-08-14 15:26:04 +00:00
|
|
|
; Get 16-bit length
|
2002-08-06 15:03:06 +00:00
|
|
|
ldx #inputPointer
|
|
|
|
mva (0,x) moveBlock_len
|
|
|
|
mva (inputPointer),y moveBlock_len+1
|
|
|
|
; Skip length and one's complement length
|
2000-08-14 15:26:04 +00:00
|
|
|
lda #4
|
|
|
|
add:sta inputPointer
|
|
|
|
scc:inc inputPointer+1
|
|
|
|
|
|
|
|
* moveBlock
|
2002-08-06 15:03:06 +00:00
|
|
|
; Copy block of length moveBlock_len from (0,x) to output
|
2000-08-14 15:26:04 +00:00
|
|
|
moveBlock
|
2002-08-06 15:03:06 +00:00
|
|
|
ldy moveBlock_len
|
|
|
|
beq moveBlock_1
|
2000-08-14 15:26:04 +00:00
|
|
|
ldy #0
|
2002-08-06 15:03:06 +00:00
|
|
|
inc moveBlock_len+1
|
|
|
|
moveBlock_1
|
|
|
|
mva (0,x) (outputPointer),y
|
2000-08-14 15:26:04 +00:00
|
|
|
inw 0,x
|
|
|
|
inw outputPointer
|
2002-08-06 15:03:06 +00:00
|
|
|
dec moveBlock_len
|
|
|
|
bne moveBlock_1
|
|
|
|
dec moveBlock_len+1
|
|
|
|
bne moveBlock_1
|
2000-08-14 15:26:04 +00:00
|
|
|
rts
|
|
|
|
|
2002-08-06 15:03:06 +00:00
|
|
|
* inflateCompressedBlock
|
|
|
|
; Decompress Huffman-coded data block
|
|
|
|
; A = 1: fixed, A = 2: dynamic
|
|
|
|
inflateCompressedBlock
|
|
|
|
lsr @
|
|
|
|
bne inflateDynamicBlock
|
|
|
|
|
2000-08-14 15:26:04 +00:00
|
|
|
* inflateFixedBlock
|
2002-08-06 15:03:06 +00:00
|
|
|
; Decompress Huffman-coded data block with default Huffman trees:
|
2000-08-14 15:26:04 +00:00
|
|
|
; literalCodeLength :144 dta 8
|
|
|
|
; :112 dta 9
|
|
|
|
; endCodeLength :24 dta 7
|
|
|
|
; :6 dta 8
|
2002-08-06 15:03:06 +00:00
|
|
|
; distanceCodeLength :30 dta 5+DISTANCE_TREE
|
|
|
|
; :2 dta 8
|
|
|
|
; (two 8-bit codes from primary tree are not used)
|
2000-08-14 15:26:04 +00:00
|
|
|
inflateFixedBlock
|
|
|
|
ldx #159
|
|
|
|
stx distanceCodeLength+32
|
|
|
|
lda #8
|
2002-08-06 15:03:06 +00:00
|
|
|
inflateFixedBlock_1
|
|
|
|
sta literalCodeLength-1,x
|
2000-08-14 15:26:04 +00:00
|
|
|
sta literalCodeLength+159-1,x-
|
2002-08-06 15:03:06 +00:00
|
|
|
bne inflateFixedBlock_1
|
2000-08-14 15:26:04 +00:00
|
|
|
ldx #112
|
2002-08-06 15:03:06 +00:00
|
|
|
inc:rne literalCodeLength+144-1,x-
|
2000-08-14 15:26:04 +00:00
|
|
|
ldx #24
|
2002-08-06 15:03:06 +00:00
|
|
|
dec:rne endCodeLength-1,x-
|
2000-08-14 15:26:04 +00:00
|
|
|
ldx #30
|
|
|
|
lda #5+DISTANCE_TREE
|
|
|
|
sta:rne distanceCodeLength-1,x-
|
2002-08-06 15:03:06 +00:00
|
|
|
beq inflateCodes !
|
2000-08-14 15:26:04 +00:00
|
|
|
|
|
|
|
* inflateDynamicBlock
|
2002-08-06 15:03:06 +00:00
|
|
|
; Decompress Huffman-coded data block, reading Huffman trees first
|
2000-08-14 15:26:04 +00:00
|
|
|
inflateDynamicBlock
|
2002-08-06 15:03:06 +00:00
|
|
|
; numberOfPrimaryCodes = 257 + getBits(5)
|
2000-08-14 15:26:04 +00:00
|
|
|
ldx #5
|
2002-08-06 15:03:06 +00:00
|
|
|
; lda #1
|
2000-08-14 15:26:04 +00:00
|
|
|
jsr getBits
|
2002-08-06 15:03:06 +00:00
|
|
|
sta inflateDynamicBlock_np
|
|
|
|
; numberOfDistanceCodes = 1 + getBits(5)
|
2000-08-14 15:26:04 +00:00
|
|
|
ldx #5
|
2002-08-06 15:03:06 +00:00
|
|
|
lda #1+29+1
|
2000-08-14 15:26:04 +00:00
|
|
|
jsr getBits
|
2002-08-06 15:03:06 +00:00
|
|
|
sta inflateDynamicBlock_nd
|
|
|
|
; numberOfTemporaryCodes = 4 + getBits(4)
|
2000-08-14 15:26:04 +00:00
|
|
|
lda:tax #4
|
|
|
|
jsr getBits
|
2002-08-06 15:03:06 +00:00
|
|
|
sta inflateDynamicBlock_cnt
|
|
|
|
; Get lengths of temporary codes in order stored in tempCodeLengthOrder
|
|
|
|
lda:tay #0
|
|
|
|
inflateDynamicBlock_1
|
|
|
|
ldx #3 ; A = 0
|
|
|
|
jsr getBits ; does not change Y
|
|
|
|
inflateDynamicBlock_2
|
|
|
|
ldx tempCodeLengthOrder,y
|
2000-08-14 15:26:04 +00:00
|
|
|
sta literalCodeLength,x
|
2002-08-06 15:03:06 +00:00
|
|
|
lda #0
|
2000-08-14 15:26:04 +00:00
|
|
|
iny
|
2002-08-06 15:03:06 +00:00
|
|
|
cpy inflateDynamicBlock_cnt
|
|
|
|
bcc inflateDynamicBlock_1
|
|
|
|
cpy #19
|
|
|
|
bcc inflateDynamicBlock_2
|
2000-08-14 15:26:04 +00:00
|
|
|
ror literalCodeLength+19 +
|
|
|
|
; Build tree for temporary codes
|
|
|
|
jsr buildHuffmanTree
|
|
|
|
|
2002-08-06 15:03:06 +00:00
|
|
|
; Use temporary codes to get lengths for literal/length and distance codes
|
|
|
|
ldx #0
|
2000-08-14 15:26:04 +00:00
|
|
|
ldy #1
|
2002-08-06 15:03:06 +00:00
|
|
|
stx getNextLength_last
|
|
|
|
inflateDynamicBlock_3
|
|
|
|
jsr getNextLength
|
|
|
|
sta literalCodeLength,x+
|
|
|
|
bne inflateDynamicBlock_3
|
|
|
|
inflateDynamicBlock_4
|
|
|
|
jsr getNextLength
|
|
|
|
sta endCodeLength,x+
|
|
|
|
cpx inflateDynamicBlock_np
|
|
|
|
bcc inflateDynamicBlock_4
|
2000-08-14 15:26:04 +00:00
|
|
|
lda #0
|
2002-08-06 15:03:06 +00:00
|
|
|
bcs inflateDynamicBlock_6 !
|
|
|
|
inflateDynamicBlock_5
|
|
|
|
sta endCodeLength,x+
|
|
|
|
inflateDynamicBlock_6
|
|
|
|
cpx #1+29
|
|
|
|
bcc inflateDynamicBlock_5
|
|
|
|
inflateDynamicBlock_7
|
|
|
|
jsr getNextLength
|
|
|
|
cmp #0
|
|
|
|
seq:adc #DISTANCE_TREE-1 +
|
|
|
|
sta endCodeLength,x+
|
|
|
|
cpx inflateDynamicBlock_nd
|
|
|
|
bcc inflateDynamicBlock_7
|
|
|
|
ror endCodeLength,x +
|
2000-08-14 15:26:04 +00:00
|
|
|
|
|
|
|
* inflateCodes
|
2002-08-06 15:03:06 +00:00
|
|
|
; Decompress data block basing on given Huffman trees
|
2000-08-14 15:26:04 +00:00
|
|
|
inflateCodes
|
|
|
|
jsr buildHuffmanTree
|
2002-08-06 15:03:06 +00:00
|
|
|
inflateCodes_1
|
|
|
|
jsr fetchPrimaryCode
|
|
|
|
bcs inflateCodes_2
|
2000-08-14 15:26:04 +00:00
|
|
|
; Literal code
|
|
|
|
sta (outputPointer),0
|
2002-08-06 15:03:06 +00:00
|
|
|
inc outputPointer
|
|
|
|
bne inflateCodes_1
|
|
|
|
inc outputPointer+1
|
|
|
|
bcc inflateCodes_1 !
|
2000-08-14 15:26:04 +00:00
|
|
|
; End of block
|
2002-08-06 15:03:06 +00:00
|
|
|
inflateCodes_ret
|
|
|
|
rts
|
|
|
|
inflateCodes_2
|
|
|
|
beq inflateCodes_ret
|
2000-08-14 15:26:04 +00:00
|
|
|
; Repeat block
|
|
|
|
jsr getValue
|
2002-08-06 15:03:06 +00:00
|
|
|
sta moveBlock_len
|
2000-08-14 15:26:04 +00:00
|
|
|
tya
|
|
|
|
jsr getBits
|
2002-08-06 15:03:06 +00:00
|
|
|
sta moveBlock_len+1
|
2000-08-14 15:26:04 +00:00
|
|
|
ldx #DISTANCE_TREE
|
|
|
|
jsr fetchCode
|
|
|
|
jsr getValue
|
2002-08-06 15:03:06 +00:00
|
|
|
sec
|
|
|
|
eor #$ff
|
|
|
|
adc outputPointer
|
|
|
|
sta inflateCodes_src
|
|
|
|
php
|
2000-08-14 15:26:04 +00:00
|
|
|
tya
|
|
|
|
jsr getBits
|
2002-08-06 15:03:06 +00:00
|
|
|
plp
|
|
|
|
eor #$ff
|
|
|
|
adc outputPointer+1
|
|
|
|
sta inflateCodes_src+1
|
|
|
|
ldx #inflateCodes_src
|
2000-08-14 15:26:04 +00:00
|
|
|
jsr moveBlock
|
2002-08-06 15:03:06 +00:00
|
|
|
beq inflateCodes_1 !
|
2000-08-14 15:26:04 +00:00
|
|
|
|
|
|
|
* buildHuffmanTree
|
2002-08-06 15:03:06 +00:00
|
|
|
; Build Huffman trees basing on code lengths.
|
|
|
|
; Lengths (in bits) are stored in *CodeLength tables.
|
2000-08-14 15:26:04 +00:00
|
|
|
; A byte with highest bit set marks end of length table.
|
|
|
|
buildHuffmanTree
|
2002-08-06 15:03:06 +00:00
|
|
|
mwa #literalCodeLength buildHuffmanTree_src
|
|
|
|
; Clear bitsCount and bitsPointer_l
|
|
|
|
ldy #2*TREES_SIZE+1
|
2000-08-14 15:26:04 +00:00
|
|
|
lda #0
|
2002-08-06 15:03:06 +00:00
|
|
|
sta:rne bitsCount-1,y-
|
|
|
|
beq buildHuffmanTree_3 !
|
2000-08-14 15:26:04 +00:00
|
|
|
; Count number of codes of each length
|
2002-08-06 15:03:06 +00:00
|
|
|
buildHuffmanTree_2
|
|
|
|
tax
|
|
|
|
inc bitsPointer_l,x
|
|
|
|
iny
|
|
|
|
bne buildHuffmanTree_3
|
|
|
|
inc buildHuffmanTree_src+1
|
|
|
|
buildHuffmanTree_3
|
|
|
|
lda (buildHuffmanTree_src),y
|
|
|
|
bpl buildHuffmanTree_2
|
2000-08-14 15:26:04 +00:00
|
|
|
; Calculate pointer for each length
|
2002-08-06 15:03:06 +00:00
|
|
|
ldx #0
|
|
|
|
lda #<sortedCodes
|
|
|
|
ldy #>sortedCodes
|
|
|
|
clc
|
|
|
|
buildHuffmanTree_4
|
|
|
|
sta bitsPointer_l,x
|
2000-08-14 15:26:04 +00:00
|
|
|
tya:sta bitsPointer_h,x
|
2002-08-06 15:03:06 +00:00
|
|
|
lda bitsPointer_l+1,x
|
|
|
|
adc bitsPointer_l,x -
|
2000-08-14 15:26:04 +00:00
|
|
|
scc:iny
|
|
|
|
inx
|
|
|
|
cpx #TREES_SIZE
|
2002-08-06 15:03:06 +00:00
|
|
|
bcc buildHuffmanTree_4
|
|
|
|
mva #>literalCodeLength buildHuffmanTree_src+1
|
|
|
|
ldy #0
|
|
|
|
bcs buildHuffmanTree_9 !
|
2000-08-14 15:26:04 +00:00
|
|
|
; Put codes into their place in sorted table
|
2002-08-06 15:03:06 +00:00
|
|
|
buildHuffmanTree_6
|
|
|
|
beq buildHuffmanTree_7
|
|
|
|
tax
|
|
|
|
mva bitsPointer_l-1,x buildHuffmanTree_ptr
|
|
|
|
mva bitsPointer_h-1,x buildHuffmanTree_ptr+1
|
|
|
|
tya
|
|
|
|
ldy:inc bitsCount-1,x
|
|
|
|
sta (buildHuffmanTree_ptr),y
|
|
|
|
tay
|
|
|
|
buildHuffmanTree_7
|
|
|
|
iny
|
|
|
|
bne buildHuffmanTree_9
|
|
|
|
inc buildHuffmanTree_src+1
|
|
|
|
ldx #MAX_BITS-1
|
|
|
|
mva:rpl bitsCount,x literalCount,x-
|
|
|
|
buildHuffmanTree_9
|
|
|
|
lda (buildHuffmanTree_src),y
|
|
|
|
bpl buildHuffmanTree_6
|
|
|
|
rts
|
|
|
|
|
|
|
|
* getNextLength
|
|
|
|
; Get next code length basing on temporary codes
|
|
|
|
getNextLength
|
|
|
|
stx getNextLength_index
|
|
|
|
dey
|
|
|
|
bne getNextLength_1
|
|
|
|
; Fetch a temporary code
|
|
|
|
jsr fetchPrimaryCode
|
|
|
|
; Temporary code 0..15: put this length
|
|
|
|
ldy #1
|
|
|
|
cmp #16
|
|
|
|
bcc getNextLength_2
|
|
|
|
; Temporary code 16: repeat last length 3 + getBits(2) times
|
|
|
|
; Temporary code 17: put zero length 3 + getBits(3) times
|
|
|
|
; Temporary code 18: put zero length 11 + getBits(7) times
|
|
|
|
tay
|
|
|
|
ldx tempExtraBits-16,y
|
|
|
|
lda tempBaseValue-16,y
|
|
|
|
jsr getBits
|
|
|
|
cpy #17
|
|
|
|
tay
|
|
|
|
lda #0
|
|
|
|
bcs getNextLength_2
|
|
|
|
getNextLength_1
|
|
|
|
lda getNextLength_last
|
|
|
|
getNextLength_2
|
|
|
|
sta getNextLength_last
|
|
|
|
ldx getNextLength_index
|
2000-08-14 15:26:04 +00:00
|
|
|
rts
|
|
|
|
|
2002-08-06 15:03:06 +00:00
|
|
|
* fetchPrimaryCode
|
|
|
|
; Read code basing on primary tree
|
|
|
|
fetchPrimaryCode
|
|
|
|
ldx #PRIMARY_TREE
|
2000-08-14 15:26:04 +00:00
|
|
|
|
|
|
|
* fetchCode
|
2002-08-06 15:03:06 +00:00
|
|
|
; Read code from input stream basing on tree given in X.
|
|
|
|
; Return low byte of code in A.
|
|
|
|
; For literal/length tree C is set if non-literal code.
|
2000-08-14 15:26:04 +00:00
|
|
|
fetchCode
|
|
|
|
lda #0
|
2002-08-06 15:03:06 +00:00
|
|
|
fetchCode_1
|
|
|
|
jsr getBit
|
2000-08-14 15:26:04 +00:00
|
|
|
rol @
|
|
|
|
inx
|
2002-08-06 15:03:06 +00:00
|
|
|
sub bitsCount-1,x
|
|
|
|
bcs fetchCode_1
|
|
|
|
adc bitsCount-1,x -
|
|
|
|
cmp literalCount-1,x
|
|
|
|
sta fetchCode_ptr
|
|
|
|
ldy bitsPointer_l-1,x
|
|
|
|
mva bitsPointer_h-1,x fetchCode_ptr+1
|
|
|
|
lda (fetchCode_ptr),y
|
2000-08-14 15:26:04 +00:00
|
|
|
rts
|
|
|
|
|
|
|
|
* getValue
|
2002-08-06 15:03:06 +00:00
|
|
|
; Read low byte of value (length or distance), basing on code A
|
2000-08-14 15:26:04 +00:00
|
|
|
getValue
|
|
|
|
tay
|
2002-08-06 15:03:06 +00:00
|
|
|
ldx lengthExtraBits-1,y
|
|
|
|
lda:pha lengthBaseValue_l-1,y
|
|
|
|
lda:tay lengthBaseValue_h-1,y
|
2000-08-14 15:26:04 +00:00
|
|
|
pla
|
|
|
|
|
|
|
|
* getBits
|
2002-08-06 15:03:06 +00:00
|
|
|
; Read X-bit number from input stream and add it to A.
|
2000-08-14 15:26:04 +00:00
|
|
|
; In case of carry, Y is incremented.
|
|
|
|
; If X > 8, only 8 bits are read.
|
|
|
|
; On return X holds number of unread bits: X = (X > 8 ? X - 8 : 0);
|
|
|
|
getBits
|
|
|
|
cpx #0
|
2002-08-06 15:03:06 +00:00
|
|
|
beq getBits_ret
|
2000-08-14 15:26:04 +00:00
|
|
|
pha
|
2002-08-06 15:03:06 +00:00
|
|
|
mva #1 getBits_tmp
|
2000-08-14 15:26:04 +00:00
|
|
|
pla
|
2002-08-06 15:03:06 +00:00
|
|
|
getBits_1
|
|
|
|
jsr getBit
|
|
|
|
bcc getBits_2
|
|
|
|
add getBits_tmp
|
2000-08-14 15:26:04 +00:00
|
|
|
scc:iny
|
2002-08-06 15:03:06 +00:00
|
|
|
getBits_2
|
|
|
|
dex
|
|
|
|
beq getBits_ret
|
|
|
|
asl getBits_tmp
|
|
|
|
bcc getBits_1
|
|
|
|
getBits_ret
|
|
|
|
rts
|
2000-08-14 15:26:04 +00:00
|
|
|
|
|
|
|
* getBit
|
2002-08-06 15:03:06 +00:00
|
|
|
; Read single bit from input stream, returns it in C flag
|
2000-08-14 15:26:04 +00:00
|
|
|
getBit
|
2002-08-06 15:03:06 +00:00
|
|
|
lsr getBit_hold
|
|
|
|
bne getBit_ret
|
2000-08-14 15:26:04 +00:00
|
|
|
pha
|
|
|
|
tya:pha
|
|
|
|
lda (inputPointer),0
|
|
|
|
inw inputPointer
|
|
|
|
ror @ +
|
2002-08-06 15:03:06 +00:00
|
|
|
sta getBit_hold
|
2000-08-14 15:26:04 +00:00
|
|
|
pla:tay
|
|
|
|
pla
|
2002-08-06 15:03:06 +00:00
|
|
|
getBit_ret
|
|
|
|
rts
|
2000-08-14 15:26:04 +00:00
|
|
|
|
2002-08-06 15:03:06 +00:00
|
|
|
* Tables for temporary codes
|
|
|
|
; Value is BaseValue + getBits(ExtraBits)
|
|
|
|
|
|
|
|
; Order, in which lengths of temporary codes are stored
|
|
|
|
tempCodeLengthOrder
|
|
|
|
dta b(16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15)
|
|
|
|
|
|
|
|
; Base values
|
|
|
|
tempBaseValue
|
|
|
|
dta b(3,3,11)
|
2000-08-14 15:26:04 +00:00
|
|
|
|
2002-08-06 15:03:06 +00:00
|
|
|
; Number of extra bits to read
|
|
|
|
tempExtraBits
|
|
|
|
dta b(2,3,7)
|
2000-08-14 15:26:04 +00:00
|
|
|
|
|
|
|
* Tables for length and distance codes
|
2002-08-06 15:03:06 +00:00
|
|
|
; Value is BaseValue + getBits(ExtraBits)
|
|
|
|
|
2000-08-14 15:26:04 +00:00
|
|
|
; Base values
|
2002-08-06 15:03:06 +00:00
|
|
|
lengthBaseValue_l
|
2000-08-14 15:26:04 +00:00
|
|
|
dta l(3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43)
|
|
|
|
dta l(51,59,67,83,99,115,131,163,195,227,258)
|
2002-08-06 15:03:06 +00:00
|
|
|
distanceBaseValue_l
|
2000-08-14 15:26:04 +00:00
|
|
|
dta l(1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385)
|
|
|
|
dta l(513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577)
|
2002-08-06 15:03:06 +00:00
|
|
|
lengthBaseValue_h
|
2000-08-14 15:26:04 +00:00
|
|
|
dta h(3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43)
|
|
|
|
dta h(51,59,67,83,99,115,131,163,195,227,258)
|
2002-08-06 15:03:06 +00:00
|
|
|
distanceBaseValue_h
|
2000-08-14 15:26:04 +00:00
|
|
|
dta h(1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385)
|
|
|
|
dta h(513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577)
|
2002-08-06 15:03:06 +00:00
|
|
|
|
2000-08-14 15:26:04 +00:00
|
|
|
; Number of extra bits to read
|
|
|
|
lengthExtraBits
|
|
|
|
dta b(0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4)
|
|
|
|
dta b(4,4,5,5,5,5,0)
|
|
|
|
distanceExtraBits
|
|
|
|
dta b(0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10)
|
|
|
|
dta b(11,11,12,12,13,13)
|
|
|
|
|
2002-08-06 15:03:06 +00:00
|
|
|
; Number of literal codes of each length in primary tree
|
|
|
|
; (MAX_BITS bytes, overlap with literalCodeLength)
|
|
|
|
literalCount
|
|
|
|
|
|
|
|
* Data for building primary tree
|
|
|
|
; Lengths of literal codes
|
|
|
|
literalCodeLength
|
|
|
|
org *+256
|
|
|
|
; Length of end code
|
|
|
|
endCodeLength
|
|
|
|
org *+1
|
|
|
|
; Lengths of length codes
|
|
|
|
lengthCodeLength
|
|
|
|
org *+29
|
|
|
|
|
2000-08-14 15:26:04 +00:00
|
|
|
* Data for building distance tree
|
2002-08-06 15:03:06 +00:00
|
|
|
; Lengths of distance codes
|
|
|
|
distanceCodeLength
|
|
|
|
org *+30
|
|
|
|
; For two unused codes in fixed trees and end-of-table flag
|
|
|
|
org *+3
|
2000-08-14 15:26:04 +00:00
|
|
|
|
|
|
|
* Huffman tree structure
|
2002-08-06 15:03:06 +00:00
|
|
|
|
2000-08-14 15:26:04 +00:00
|
|
|
; Number of codes of each length
|
2002-08-06 15:03:06 +00:00
|
|
|
bitsCount
|
|
|
|
org *+TREES_SIZE
|
2000-08-14 15:26:04 +00:00
|
|
|
; Pointer to sorted codes of each length
|
2002-08-06 15:03:06 +00:00
|
|
|
bitsPointer_l
|
|
|
|
org *+TREES_SIZE+1
|
|
|
|
bitsPointer_h
|
|
|
|
org *+TREES_SIZE
|
|
|
|
|
2000-08-14 15:26:04 +00:00
|
|
|
; Sorted codes
|
2002-08-06 15:03:06 +00:00
|
|
|
sortedCodes
|
|
|
|
org *+256+1+29+30+2
|
2000-08-14 15:26:04 +00:00
|
|
|
|
|
|
|
end
|