⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 huffman.asm

📁 这是一个JPEG解码器,里面使用了MMX,SSE等汇编指令集
💻 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 + -