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

📄 jpeg.asm

📁 这是一个JPEG解码器,里面使用了MMX,SSE等汇编指令集
💻 ASM
📖 第 1 页 / 共 2 页
字号:
        mov         al, JPEG_OUTOFMEM
        jmp         Error
ErrorEof:
        mov         al, JPEG_EOF
Error:
        mov         BPTR [Ctx].LastError, al
        sub         eax, eax
        jmp         Done

HMAX  TEXTEQU <>
VMAX  TEXTEQU <>
NF    TEXTEQU <>
CINFO TEXTEQU <>
NFSAV TEXTEQU <>

JPG_SOF ENDP

;//=========================================================================
;// Process SOS marker (Start of scan)
;// returns : 0 : error, != 0 : success
;//=========================================================================

JPG_SOS PROC

        CINFO TEXTEQU <ebx>
        NS    TEXTEQU <esi>

        call        JPG_TestLength
        jnle        ErrorEof

        ;// read Ns
        mov         eax, 8
        call        BS_GetBits
        mov         NS, eax
        ;// Ns must be equal to Nf
        cmp         eax, [Ctx].Image.Nf
        jne         ErrorNf

        ;// read scan info
        lea         CINFO, [Ctx].FrameInfo.CompInfo
SLoop:
        ;// Cs,TdTa
        ;// Cs is ignored
        mov         eax, 16
        call        BS_GetBits
        mov         ecx, eax
        shr         eax, 4
        and         ecx, 011b
        and         eax, 011b

        ;// init pointer to huffman table
        imul        eax, 2*sizeof(HUFFTABLE)
        imul        ecx, 2*sizeof(HUFFTABLE)
        lea         eax, [Ctx].HufTable0[eax]
        lea         ecx, [Ctx].HufTable0[ecx + sizeof(HUFFTABLE)]
        mov         [CINFO].COMPINFO.DCTable, eax
        mov         [CINFO].COMPINFO.ACTable, ecx
        add         CINFO, sizeof(COMPINFO)
        dec         NS
        jnz         SLoop

        ;// skip Ss, Se, AhAl
        mov         eax, 8*3
        call        BS_GetBits

        DBG_SOS

        ;// decode entropy coded segment
        call        JPG_ECS
Done:
        ret

        ;// errors
ErrorEof:
        mov         al, JPEG_EOF
        jmp         Error
ErrorNf:
        mov         al, JPEG_FORMATNOTSUPPORTED
Error:
        mov         BPTR [Ctx].LastError, al
        sub         eax, eax
        jmp         Done

        CINFO TEXTEQU <>
        NS  TEXTEQU <>

JPG_SOS ENDP

;//=========================================================================
;// Process DQT marker (Quantization table)
;// returns : 0 : error, != 0 : success
;//=========================================================================

JPG_DQT PROC

        sub         esp, 4

L TEXTEQU <DPTR [esp]>
P TEXTEQU <esi>

        call        JPG_TestLength
        jnle        ErrorEof

        mov         L, eax

        ;// read quantization table
RLoop:
        ;// read precision (0:8bits,1:16 bits) | Tq (table index)
        mov         eax, 8
        call        BS_GetBits

        ;// read quantization value
        mov         ebx, eax
        shr         eax, 4
        and         ebx, 011b
        and         eax, 01b
        shl         ebx, 6+2
        lea         P, [8*eax+8]
        mov         edi, -64
        lea         ebx, [Ctx].QuantTable0[ebx]
QLoop:
        mov         eax, P
        call        BS_GetBits
        movzx       ecx, TBL_jpeg_natural_order[edi+64]
        ;// convert to float
        cvtsi2ss    xmm0, eax
        inc         edi
        movss       [ebx][4*ecx], xmm0
        jnz         QLoop
NextTable:
        DBG_QTABLE
        shl         P, 3
        inc         P
        sub         L, P
        jg          RLoop

        mov         al, 1
Done:
        add         esp, 4
        ret

        ;// errors
ErrorEof:
        mov         al, JPEG_EOF
Error:
        mov         BPTR [Ctx].LastError, al
        sub         eax, eax
        jmp         Done

P TEXTEQU <>

JPG_DQT ENDP

;//=========================================================================
;// Process DHT marker (Huffman table)
;// returns : 0 : error, != 0 : success
;//=========================================================================

JPG_DHT PROC

        call        JPG_TestLength
        jnle        ErrorEof

        ;// save segment length
        mov         ebx, eax

        ;// pointer to the start of the segment
        call        BS_GetPtr
        mov         esi, eax

        ;// move the bitstream pointer to the end of the segment
        mov         eax, ebx
        call        BS_SkipBytes

        ;// generate table
        call        HUF_GenTable

        mov         al, 1
Done:
        ret

        ;// errors
ErrorEof:
        mov         BPTR [Ctx].LastError, JPEG_EOF
        sub         eax, eax
        jmp         Done

JPG_DHT ENDP

;//=========================================================================
;// Process DRI marker (Define Restart Interval)
;// returns : 0 : error, != 0 : success
;//=========================================================================

JPG_DRI PROC

        call        JPG_TestLength
        jnle        ErrorEof
        mov         eax, 16
        call        BS_GetBits
        mov         [Ctx].FrameInfo.Ri, eax
        mov         al, 1
        DBG_DRI
Done:
        ret

        ;// errors
ErrorEof:
        mov         BPTR [Ctx].LastError, JPEG_EOF
        sub         eax, eax
        jmp         Done

JPG_DRI ENDP

;//=========================================================================
;// Process RST marker (Restart)
;// returns : 0 : error, != 0 : success
;//=========================================================================

JPG_RST PROC

        ;// reset DC value for all components
        sub         eax, eax
        lea         ecx, [Ctx].FrameInfo.CompInfo
        mov         edx, [Ctx].Image.Nf
CLoop:
        mov         [ecx].COMPINFO.DCPred, eax
        add         ecx, sizeof(COMPINFO)
        dec         edx
        jnz         CLoop

        ;// decode next ECS
        call        JPG_ECS

        ret

JPG_RST ENDP

;//=========================================================================
;// Decode entropy coded segment
;// returns : 0 : error, != 0 : success
;//=========================================================================

        EXTEND MACRO T
        ;// extend T bits, input/output in eax
        ;// if (V < 2^(T-1))
        ;//   V += (-1) << T +  1
        ;// branchless code written with bitRAKE
        mov         ecx, T
        mov         edx, eax    ;// edx = V
        shr         eax, cl     ;// V < 2^(T-1) ? CF = 0 : CF = 1
        sbb         eax, eax    ;// V < 2^(T-1) ? eax = 0 : eax = -1
        not         eax         ;// V < 2^(T-1) ? eax = -1 : eax = 0
        shl         eax, cl     ;// V < 2^(T-1) ? eax = (-1) << T, CF = 1 : eax = 0
        adc         eax, edx    ;// V < 2^(T-1) ? eax = V + (-1) << T + 1 : eax = V
        DBG_EXTEND
        ENDM

JPG_ECS PROC

        .data
        espsav dword ?
        .code

K       TEXTEQU <ebx>
CINFO   TEXTEQU <esi>
UPPTR   TEXTEQU <edi>
ZZ      TEXTEQU <DPTR [esp]>
NBCOMP  TEXTEQU <DPTR [esp+64*4+4*0]>
NBDU    TEXTEQU <DPTR [esp+64*4+4*1]>
NBMCU   TEXTEQU <DPTR [esp+64*4+4*2]>
T       TEXTEQU <DPTR [esp+64*4+4*3]>

        ;// save esp
        mov         espsav, esp
        sub         esp, 64*4+4*4+15
        and         esp, NOT(15)

        ;// read min(Ri,NbMCU) MCUs
        sub         edx, edx
        mov         ecx, [Ctx].FrameInfo.NbMCU
        add         edx, [Ctx].FrameInfo.Ri
        jnz         Ri
        mov         edx, ecx
Ri:
        MIN         edx, ecx
        jz          DoneOk

        mov         NBMCU, edx
        sub         [Ctx].FrameInfo.NbMCU, edx

        ;// reset bitstream ptr
        call        BS_GetPtr

        ;// init return adress from IDCT
        mov         [Ctx].RetIdct, RetIdct

        ;// decode MCUs
MCULoop:
        mov         eax, [Ctx].Image.Nf
        mov         NBCOMP, eax
        lea         CINFO, [Ctx].FrameInfo.CompInfo[0]
        ASSUME      CINFO:PTR COMPINFO

        ;// init pointer in the resampling buffer
        mov         UPPTR, [Ctx].Mem

        ;// decode components
CLoop:
        ;// init number of data units
        mov         eax, [CINFO].NbDU
        mov         NBDU, eax

DuLoop:
        ;// reset ZZ buffer
        lea         edx, ZZ
        mov         ecx, 64*4
        pxor        mm1, mm1
        call        MEM_Set

        ;// decode DC coefficient
        mov         eax, [CINFO].DCTable
        call        HUF_Decode
        jc          ErrorEof
        mov         ebx, [CINFO].DCPred
        test        eax, eax
        jz          NoRecv
        ;// get bits
        mov         T, eax
        call        BS_GetBitsECS
        jc          ErrorEof
        EXTEND      T
        add         ebx, eax
        mov         [CINFO].DCPred, ebx
NoRecv:
        mov         ZZ[0], ebx

        ;// decode AC coefficients
        mov         K, -62
ACLoop:         
        mov         eax, [CINFO].ACTable
        call        HUF_Decode
        jc          ErrorEof
R TEXTEQU <eax>
S TEXTEQU <T>
        ;// eax = RS
        mov         S, eax
        shr         R, 4
        ;// K += R
        add         K, R
        and         S, 0Fh
        jz          NoS
        ;// receive and extend S bits        
        mov         eax, S
        call        BS_GetBitsECS
        jc          ErrorEof
        EXTEND      S
        ;// save coefficient
        movzx       ecx, TBL_jpeg_natural_order[K+63]
        mov         ZZ[4*ecx], eax
        mov         R, 15
NoS:
        ;// if (R == 15)
        ;//   break;
        ;// else
        ;//   k++;
        ;//   if (k <= 0)
        ;//     continue
        cmp         R, 15
        sbb         eax, eax
        not         eax
        and         K, eax
        inc         K
        jle         ACLoop

        ;// perform dequantization, IDCT and resampling on the data unit
        ;// a jmp is used because esp must remain 16-byte aligned
        mov         eax, [CINFO].QuantTable
        jmp         [CINFO].Idct
RetIdct:
        ;// next data unit
        dec         NBDU
        jnz         DuLoop

        ;// next component
        add         CINFO, sizeof(COMPINFO)
        dec         NBCOMP
        jnz         CLoop

        ;// convert to RGB
        call        [Ctx].FrameInfo.RGBConv

        ;// next MCU
        dec         NBMCU
        jnz         MCULoop

        ;// reset bitstream ptr
        call        BS_GetPtr

DoneOk:
        mov         al, 1
Done:
        mov         esp, espsav
        ret

        ;// errors
ErrorEof:
        mov         BPTR [Ctx].LastError, JPEG_EOF
        sub         eax, eax
        jmp         Done

R     TEXTEQU <>
S     TEXTEQU <>
K     TEXTEQU <>
CINFO TEXTEQU <>
ZZ    TEXTEQU <>
NS    TEXTEQU <>
NBDU  TEXTEQU <>
NBMCU TEXTEQU <>

JPG_ECS ENDP

;//=========================================================================
;// Process EOI marker (End Of Image)
;// returns : 0 to exit the decoding loop
;//=========================================================================

JPG_EOI PROC

        mov         BPTR [Ctx].LastError, JPEG_SUCCESS
        sub         eax, eax
        ret

JPG_EOI ENDP

;//=========================================================================
;// Skip a segment
;// returns : 0 : error, != 0 : success
;//=========================================================================

JPG_SKIP PROC

        call        JPG_TestLength
        jnle        ErrorEof
        call        BS_SkipBytes
        mov         al, 1
Done:
        ret
        ;// errors
ErrorEof:
        mov         BPTR [Ctx].LastError, JPEG_EOF
        sub         eax, eax
        jmp         Done

JPG_SKIP ENDP

;//=========================================================================
;// Marker not supported
;// returns : 0 : error
;//=========================================================================

JPG_UNSUPP PROC

        mov         BPTR [Ctx].LastError, JPEG_FORMATNOTSUPPORTED
        sub         eax, eax
        ret

JPG_UNSUPP ENDP          

END

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -