📄 huffman.asm
字号:
;// Huffman decoding
.686P
.MODEL FLAT, STDCALL
OPTION CASEMAP:NONE
OPTION PROLOGUE:NONE
OPTION EPILOGUE:NONE
.MMX
INCLUDE jpeg.inc
.CODE
;//=========================================================================
;// Generate tables used in huffman decoding
;// params : ESI : pointer to start of huffman table segment
;// params : EBX : segment length
;//=========================================================================
HUF_GenTable PROC
LG TEXTEQU <DPTR [esp]>
CTXSAV TEXTEQU <DPTR [esp+4*1]>
ENTRY TEXTEQU <DPTR [esp+4*2]>
NBCOD_1 TEXTEQU <DPTR [esp+4*3]>
COD TEXTEQU <DPTR [esp+4*4]>
SRC TEXTEQU <esi>
VPTR TEXTEQU <edi>
HT TEXTEQU <ebx>
I TEXTEQU <Ctx>
sub esp, 4*5
mov LG, ebx
TLoop:
;// read table type (dc or ac) and table index
movzx eax, BPTR [SRC]
inc SRC
mov edx, eax
shr eax, 4
and edx, 011b
and eax, 01b
DBG_HTABLE
;// point to the start of the huffman table
lea eax, [2*edx+eax]
imul eax, sizeof(HUFFTABLE)
dec LG
lea HT, [Ctx].HufTable0[eax]
ASSUME HT:PTR HUFFTABLE
;// save context
mov CTXSAV, Ctx
;// set lookup table to FF
lea edx, [HT].Lookup
mov ecx, LOOKUP_SIZE
pcmpeqd mm1, mm1
call MEM_Set
;// generate table used in Huffman decoding
;// MinCode, MaxCode, ValPtr and lookup table
;// Code = 0;
;// for (i = 0; i < 16; i++) {
;// NbCode = BITS[i];
;// MaxCode[i] = -1;
;// if (NbCode != 0) {
;// ValPtr[i] = vptr;
;// MinCode[i] = Code;
;// if (i <= 8) {
;// do {
;// entry = MAKE_ENTRY(i, *vptr);
;// index = Code << (8-i)
;// for (k = 0; k < 1 << (8-i); k++)
;// Lookup[index + k] = entry;
;// Code++;
;// vptr++;
;// } while (--NbCode);
;// }
;// Code += NbCode - 1;
;// vptr += NbCode;
;// MaxCode[i] = Code++;
;// }
;// Code <<= 1;
;// }
mov I, -16
mov COD, 0
;// VPTR points to the first symbol
lea VPTR, [SRC + 16]
ILoop:
movzx eax, BPTR [SRC][I+16]
dec eax
mov [HT].MaxCode[4*I+4*16], eax
js NextCode
mov NBCOD_1, eax
mov ecx, COD
mov [HT].MinCode[4*I+4*16], ecx
mov [HT].ValPtr[4*I+4*16], VPTR
cmp I, -8
jge NoLook
LookLoop:
;// make entry
;// 0000 0LLL VVVV VVVV
lea eax, [16+I+1]
shl eax, 8
movzx ecx, BPTR [VPTR]
or eax, ecx
mov ENTRY, eax
;// edx = Code << (8-I)
mov ecx, 7-16
sub ecx, I
mov edx, COD
shl edx, cl
;// eax = 1 << (8-I)
mov eax, 1
shl eax, cl
;// set table entries
lea edx, [HT].Lookup[2*edx]
mov cx, WPTR ENTRY
KLoop:
mov [edx][2*eax-2], cx
dec eax
jnz KLoop
inc VPTR
inc COD
dec NBCOD_1
jns LookLoop
;// eax = -1
dec eax
NoLook:
mov edx, COD
add edx, eax
lea VPTR, [VPTR+eax+1]
mov [HT].MaxCode[4*I+4*16], edx
inc edx
mov COD, edx
NextCode:
shl COD, 1
inc I
jnz ILoop
;// restore context
mov Ctx, CTXSAV
;// LG -= (VPTR - ESI)
sub LG, VPTR
add LG, SRC
mov SRC, VPTR
jg TLoop
add esp, 4*5
ret
ASSUME edi:NOTHING
LG TEXTEQU <>
CTXSAV TEXTEQU <>
ENTRY TEXTEQU <>
NBCOD TEXTEQU <>
SRC TEXTEQU <>
VPTR TEXTEQU <>
HT TEXTEQU <>
I TEXTEQU <>
COD TEXTEQU <>
HUF_GenTable ENDP
;//=========================================================================
;// Decode a value
;// params : EAX : huffman table
;// returns : decoded value
;// returns : JC if end of bitstream
;//=========================================================================
HUF_Decode PROC
PROFILE_IN
;// try to read 8 bits
cmp [Ctx].Bs.Bits, 8
jl SlowMeth
movq mm2, mm0
psrlq mm2, 64-8
movd ecx, mm2
;// read entry in the lookup table
;// valid entry : 0000 0LLL SSSS SSSS
;// invalid entry : 0FFFFh
movzx ecx, [eax].HUFFTABLE.Lookup[2*ecx]
cmp ecx, 0FFFFh
je SlowMeth
;// entry found, update bitstream
mov eax, ecx
shr ecx, 8
movd mm1, ecx
and eax, 0FFh
sub BS.Bits, ecx
psllq mm0, mm1
PROFILE_OUT "HUF_Decode (lookup)"
DBG_DECODE
ret
SlowMeth:
;// slow method
;// i = -1;
;// code = 0;
;// do {
;// i++;
;// code = code << 1 + nextbit();
;// } while (code > maxcode[i])
PROFILE_IN
I TEXTEQU <esi>
COD TEXTEQU <edi>
HT TEXTEQU <ebx>
push ebx
push esi
push edi
mov HT, eax
ASSUME HT:PTR HUFFTABLE
mov I, -1
sub COD, COD
CLoop:
inc I
mov eax, 1
call BS_GetBitsECS
jc DoneSlow
lea COD, [2*COD + eax]
cmp COD, [HT].MaxCode[4*I]
jg CLoop
mov eax, [HT].ValPtr[4*I]
sub COD, [HT].MinCode[4*I]
movzx eax, BPTR [eax][COD]
DoneSlow:
pop edi
pop esi
pop ebx
PROFILE_OUT "HUF_Decode (loop)"
DBG_DECODE
ret
I TEXTEQU <>
COD TEXTEQU <>
HT TEXTEQU <>
HUF_Decode ENDP
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -