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

📄 jpeg.asm

📁 这是一个JPEG解码器,里面使用了MMX,SSE等汇编指令集
💻 ASM
📖 第 1 页 / 共 2 页
字号:
;// JPEG decoding

.686P
.MODEL FLAT, STDCALL
OPTION CASEMAP:NONE
OPTION PROLOGUE:NONE
OPTION EPILOGUE:NONE
.XMM

INCLUDE jpeg.inc
INCLUDE jpeg_dec.inc

.CODE

;//=========================================================================
;// Init decoder
;// params : eax : decoding options
;//=========================================================================

JPG_InitDecoder PROC 

        ;// save options
        mov         [Ctx].Options, eax
        call        CPUID_Init
        cmp         eax, CPU_MIN
        jl          ErrorCpu
        mov         [Ctx].CpuSupport, eax

        ;// init IDCT
        call        IDCT_Init

        ;// init RGB conversion
        call        RGB_Init
Done:
        ret        

ErrorCpu:
        mov         BPTR [Ctx].LastError, JPEG_CPUNOTSUPPORTED
        sub         eax, eax
        jmp         Done

JPG_InitDecoder  ENDP

;//=========================================================================
;// Get a marker from the bitstream
;// returns : 0 : error, !=0 : success
;//=========================================================================

JPG_GetMarker PROC

        ;// search for ff
FFLoop:
        mov         eax, 8
        call        BS_GetBits
        jc          Eof
        cmp         al, 0FFh
        jne         FFLoop

        ;// skip ff
SkipFF:
        mov         eax, 8
        call        BS_GetBits
        jc          Eof
        cmp         al, 0FFh
        je          SkipFF

        ;// accept if > mRESe
        cmp         al, mRESe
        jna         FFLoop

        DBG_MARKER

        ;// set all application markers to mAPPs :
        ;// if (eax >= mAPPs) eax = mAPPs
        cmp         al, mAPPs
        jb          NoApp
        mov         al, mAPPs
NoApp:

        ;// set all restart markers to mRST0 :
        ;// if (eax >= mRST0) && (eax <= mRST7) eax = mRST0
        cmp         al, mRST0
        jb          NoRST
        cmp         al, mRST7
        ja          NoRST
        mov         al, mRST0
NoRST:

        mov         [Ctx].CurrentMarker, eax

        mov         al, 1
Done:
        ret
Eof:
        mov         BPTR [Ctx].LastError, JPEG_EOF
        sub         eax, eax
        jmp         Done

JPG_GetMarker ENDP

;//=========================================================================
;// Process current marker
;// returns : 0 : error, !=0 : success
;//=========================================================================

JPG_ProcessMarker PROC

        ;// get the list of transitions for the current state
        mov         eax, [Ctx].State
        mov         eax, TBL_TransList[4*eax]
        ;// find the transition
        mov         edx, [Ctx].CurrentMarker
@@:
        mov         ecx, [eax]
        cmp         cl, dl
        je          Found
        cmp         cl, 0FFh
        je          Found
        add         eax, 4
        jmp         @B
Found:
        ;// transition found :
        ;// func << 16 | newstate << 8 | marker
        shr         ecx, 8
        ;// new state
        mov         BPTR [Ctx].State, cl
        shr         ecx, 8
        ;// execute transition
        call        TBL_TransFunc[4*ecx-4]

        ret

JPG_ProcessMarker ENDP

;//=========================================================================
;// Test the length of a segment
;// returns : segment length
;// returns : JNLE : end of bitstream
;//=========================================================================

JPG_TestLength PROC

        mov         eax, 16
        call        BS_GetBits
        jc          Done
        sub         eax, 2
        call        BS_Test
Done:
        ret

JPG_TestLength ENDP

;//=========================================================================
;// Process SOI marker (Start Of Image)
;// returns : 0 : error, != 0 : success
;//=========================================================================

JPG_SOI PROC

        mov         al, 1
        ret

JPG_SOI ENDP

;//=========================================================================
;// Process SOF0/SOF1 marker (Start of Frame, Baseline/Extended DCT)
;// returns : 0 : error, != 0 : success
;//=========================================================================

JPG_SOF PROC

        sub         esp, 4

HMAX  TEXTEQU <edi>
VMAX  TEXTEQU <ebx>
CINFO TEXTEQU <esi>
NFSAV TEXTEQU <DPTR [esp]>

        call        JPG_TestLength
        jnle        ErrorEof

        ;// free memory
        mov         eax, [Ctx].AllocMem
        call        MEM_Free
        mov         [Ctx].AllocMem, eax

        ;// set number of bits per pixel
        mov         eax, 32
        mov         [Ctx].Image.bitsPixel, eax

        ;// read sample precision, Y high, Y low, X high
        call        BS_GetBits
        mov         ecx, eax
        mov         esi, eax
        shr         ecx, 24
        shr         eax, 8
        and         esi, 0FFh

        ;// Y must be > 0
        and         eax, 0FFFFh
        jz          ErrorY

        ;// save Y
        mov         [Ctx].Image.height, eax

        ;// P-8 must be 0 or 4
        ;// 00000000
        ;// 00000100          
        sub         cl, 8
        test        cl, NOT(4)
        jnz         ErrorPrec

        ;// calculate constant used in RGB conversion
        ;// S = 2^(P-1)
        add         ecx, 7
        sub         eax, eax
        bts         eax, ecx
        cvtsi2ss    xmm0, eax
        shufps      xmm0, xmm0, 000000000b
        movaps      [Ctx].FrameInfo.S, xmm0

        ;// read X low, Nf
        mov         eax, 16
        call        BS_GetBits
        mov         edi, eax
        shl         esi, 8
        and         edi, 011b
        shr         eax, 8

        ;// Nf must be 1 or 3
        bt          edi, 0
        jnc         ErrorNf

        ;// X must be > 0
        or          eax, esi
        jz          ErrorX

        ;// save X and Nf          
        mov         [Ctx].Image.width, eax
        mov         [Ctx].Image.Nf, edi

        ;// init RGB conversion function
        mov         eax, [Ctx].RGBConv
        mov         eax, [eax][4*edi-4]
        mov         [Ctx].FrameInfo.RGBConv, eax

        ;// fill component information
        mov         NFSAV, edi
        sub         HMAX, HMAX
        mov         VMAX, HMAX
        lea         CINFO, [Ctx].FrameInfo.CompInfo
        ASSUME      CINFO:PTR COMPINFO
PLoop:
        ;// read Ci,HiVi,Tq1
        mov         eax, 8*3
        call        BS_GetBits
        mov         ecx, eax
        mov         edx, eax
        and         eax, 011b
        shr         ecx, 8
        shr         edx, 12
        and         ecx, 0Fh
        jz          ErrorV
        and         edx, 0Fh
        jz          ErrorH
        mov         [CINFO].V, ecx
        mov         [CINFO].H, edx
        ;// update Hmax, Vmax
        cmp         ecx, VMAX
        cmova       VMAX, ecx
        cmp         edx, HMAX
        cmova       HMAX, edx
        ;// init pointer to quantization table (index*64*sizeof(dword))
        shl         eax, 6+2
        lea         eax, [Ctx].QuantTable0[eax]
        mov         [CINFO].QuantTable, eax
        ;// calculate HiVi
        imul        ecx, edx
        mov         [CINFO].NbDU, ecx
        add         CINFO, sizeof(COMPINFO)
        dec         NFSAV
        jnz         PLoop

        ;// save Hmax,Vmax
        mov         [Ctx].FrameInfo.Hmax, HMAX
        mov         [Ctx].FrameInfo.Vmax, VMAX

        ;// verify Hmax,Vmax <= MAX_SAMPLEFACTOR
        cmp         HMAX, MAX_SAMPLEFACTOR
        ja          ErrorH
        cmp         VMAX, MAX_SAMPLEFACTOR
        ja          ErrorV

        ;// round X to the next multiple of 8*Hmax
        ;// Xr = 8*Hmax * [ (X + 8*Hmax - 1) / 8*Hmax ]
        shl         HMAX, 3
        mov         eax, [Ctx].Image.width
        sub         edx, edx
        lea         eax, [eax + HMAX - 1]
        div         HMAX

        ;// save NbHmaxRow = Xr/8*Hmax
        ;// set HmaxCount to NbHmaxRow
        mov         [Ctx].FrameInfo.NbHmaxRow, eax
        mov         [Ctx].FrameInfo.HmaxCount, eax
        imul        HMAX
        ;// save Xr
        mov         [Ctx].Image.scanlength, eax

        ;// calculate delta in RGB buffer after converting 8*Vmax*Xr pixels
        ;// DeltaRGB = 4*Scanlength*(8*Vmax - 1)
        shl         VMAX, 3
        lea         ecx, [4*VMAX-4]
        imul        eax, ecx
        mov         [Ctx].FrameInfo.DeltaRGB, eax
  
        ;// round Y to the next multiple of 8*Vmax
        ;// Yr = 8*Vmax * [ (Y + 8*Vmax - 1) / 8*Vmax ]        
        mov         eax, [Ctx].Image.height
        lea         eax, [eax + VMAX - 1]
        div         VMAX
        imul        VMAX

        ;// calculate NbMCU = (Xr * Yr) / (64 * Hmax * Vmax)
        imul        HMAX, VMAX
        imul        eax, [Ctx].Image.scanlength
        jo          ErrorDim
        ;// ecx = 4*XrYr
        mov         ecx, eax
        shl         ecx, 2
        jz          ErrorDim
        div         HMAX
        mov         [Ctx].FrameInfo.NbMCU, eax

        ;// allocate a block of memory to store
        ;// - decompressed samples : 4*(Nf*64*Hmax*Vmax)
        ;// - pointer table used in rgb conversion : 4*(Nf+1)*8*Hmax*Vmax
        ;// - rgb output : 4*XrYr for 8-bit precision, 6*XrYr for 12-bit precision
        ;// (+15 bytes for alignment)

        ;// eax = 64*Hmax*Vmax
        mov         eax, HMAX
        ;// calculate 4*64*HmaxVmax
        shl         HMAX, 2
        mov         [Ctx].FrameInfo.HmaxVmax64, HMAX          
        ;// ebx = Nf
        mov         ebx, [Ctx].Image.Nf
        ;// HMAX = 4*(Nf*64*Hmax*Vmax)
        imul        HMAX, ebx
        ;// ebx = 4*(Nf+1)*8*Hmax*Vmax
        lea         ebx, [4*ebx+4]
        shr         eax, 3
        imul        ebx, eax

        ;// eax = 4*(Nf*64*Hmax*Vmax) + 4*(Nf+1)*8*Hmax*Vmax + 15 + 4*XrYr
        lea         eax, [ebx+HMAX+15]
        add         eax, ecx
        jo          ErrorDim
        call        MEM_Alloc
        jz          ErrorMem
        mov         [Ctx].AllocMem, eax

        ;// align memory
        and         eax, NOT(15)
        mov         [Ctx].Mem, eax

        ;// init start of RGB buffer and end of pointer table
        ;// = & Mem[4*(Nf*64*Hmax*Vmax) + 4*(Nf+1)*8*Hmax*Vmax]
        lea         ecx, [eax+ebx]
        add         ecx, HMAX
        mov         [Ctx].Image.pRGB, ecx
        mov         [Ctx].FrameInfo.cRGB, ecx
        mov         [Ctx].FrameInfo.PointerTable, ecx

        ;// component initialization :
        ;// - init idct/resampling function for each component.
        ;//   the decoder supports :
        ;//   H = Hmax, V = Vmax (8x8->8x8)
        ;//   2*H = Hmax, 2*V = Vmax (8x8->16x16)
        ;//   H = Hmax, 2*V = Vmax (8x8->8x16)
        ;//   2*H = Hmax, V = Vmax (8x8->16x8)
        ;// - init pointers that will be used during rgb conversion

        SAMPLEBUF   TEXTEQU <ebx>
        PTABLE      TEXTEQU <edi>
        
        ;// PTABLE = & Mem[4*(Nf*64*Hmax*Vmax)]
        ;// SAMPLEBUF = & Mem[0]
        add         PTABLE, eax
        mov         SAMPLEBUF, eax
        mov         NFSAV, 0          
        lea         CINFO, [Ctx].FrameInfo.CompInfo[0]
CompInit:          
        mov         eax, [Ctx].FrameInfo.Hmax
        div         BPTR [CINFO].H
        ;// al = Hmax/H, ah=Hmax%H
        bswap       eax
        mov         ax, WPTR [Ctx].FrameInfo.Vmax
        div         BPTR [CINFO].V
        ;// eax = Hmax/H Hmax%H Vmax%V Vmax/V
        ;// H = Hmax, V = Vmax (no resampling)
        ;// ecx = 001000001h
        mov         ecx, 001000001h
        mov         edx, IDCT_8x8
        cmp         eax, ecx
        je          Supp
        ;// H = Hmax/2, V = Vmax/2 (8x8 -> 16x16)
        ;// ecx = 002000002h
        shl         ecx, 1
        dec         edx
        cmp         eax, ecx
        je          Supp
        dec         edx
        ;// H = Hmax/2, V = Vmax (8x8 -> 16x8 resampling)
        ;// ecx = 002000001h
        dec         ecx
        cmp         eax, ecx
        je          Supp
        ;// H = Hmax, V = Vmax/2 (8x8 -> 8x16 resampling)
        ;// ecx = 001000002h          
        dec         edx
        bswap       ecx
        cmp         eax, ecx
        jne         ErrorSampl

Supp:
        ;// save pointer to idct
        shl         edx, 2
        mov         ecx, [Ctx].Idct
        mov         ecx, [ecx][edx]
        mov         [CINFO].Idct, ecx

        ;// generate deltas in sample buffer
        push        0
        call        RGB_GenPointer

        ;// SAMPLEBUF += 4*64*Hmax*Vmax
        ;// PTABLE += 4
        add         SAMPLEBUF, [Ctx].FrameInfo.HmaxVmax64
        add         PTABLE, 4
        ;// next component
        add         CINFO, sizeof(COMPINFO)
        mov         eax, NFSAV
        inc         eax
        mov         NFSAV, eax          
        cmp         eax, [Ctx].Image.Nf
        jnz         CompInit

        ;// generate deltas in RGB buffer
        mov         edx, 4*IDCT_8x8
        push        1
        call        RGB_GenPointer

        mov         al, 1
        DBG_SOF
Done:
        add         esp, 4
        ret

        ;// errors
ErrorX:
ErrorY:
ErrorV:
ErrorH:
ErrorNf:
ErrorSampl:
ErrorPrec:
ErrorDim:
        mov         al, JPEG_FORMATNOTSUPPORTED
        jmp         Error
ErrorMem:

⌨️ 快捷键说明

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