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

📄 rgbconv.asm

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

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

INCLUDE jpeg.inc
INCLUDE jpeg_dec.inc

.CODE

;//=========================================================================
;// Init RGB conversion
;// params : eax : cpu type
;// return : eax : cpu type
;//=========================================================================

RGB_Init PROC

        mov         ecx, TBL_RGBConv[4*eax-4*CPU_MIN]
        mov         [Ctx].RGBConv, ecx
        ret

RGB_Init ENDP

;//=========================================================================
;// Generate :
;//   - a table of pointer in the sample buffer if [esp+4] = 0 
;//   - a table of deltas for the rgb pointer if [esp+4] = 1
;// Params :
;// esi : pointer to component info
;// eax : component index
;// ebx : pointer to first sample for the component
;// edi : start of pointer table for the component
;// edx : 4*IdctType
;//=========================================================================

RGB_GenPointer PROC

        COMMENT ^/*
        for (j = V; j > 0; j--) {
            for (n = 8*Vmax/V; n > 0; n--) {
                ROWSTART = PSAMPLE
                for (i = H; i > 0; i--) {
                    t = PSAMPLE
                    for (k = Hmax/H; k > 0; k++) {
                        PSAVE[0] = 4*8
                        if ( ! forRGB)
                            PSAVE[0] = t
                        PSAVE += DELTAPSAV
                        t += ROWSIZE
                    }
                    PSAMPLE += 8*(Hmax/H)*(Vmax/V)*ROWSIZE
                }              
                if (n == 8*Vmax/V)
                NEXTV = PSAMPLE              
                PSAMPLE = ROWSTART + (Hmax/H)*ROWSIZE
                if (forRGB)
                    PSAVE[-DELTAPSAV] = 4*Scanlength - (Hmax-1)*ROWSIZE
            }
            PSAMPLE = NEXTV
        }
        if (forRGB)
            PSAVE[-DELTAPSAV] = - 4*(8*Vmax-1)*ScanLength + ROWSIZE
        */^

COMP        TEXTEQU <esi>
ASSUME COMP: PTR COMPINFO
PSAVE       TEXTEQU <edi>
PSAMPLE     TEXTEQU <ebx>
K           TEXTEQU <ecx>
I           TEXTEQU <edx>
C0          TEXTEQU <[esp+4*0]>
C1          TEXTEQU <[esp+4*1]>
C2          TEXTEQU <[esp+4*2]>
C3          TEXTEQU <[esp+4*3]>
C4          TEXTEQU <[esp+4*4]>
J           TEXTEQU <DPTR [esp+4*5]>
N           TEXTEQU <DPTR [esp+4*6]>
ROWSTART    TEXTEQU <[esp+4*7]>
NEXTV       TEXTEQU <[esp+4*8]>
EDISAV      TEXTEQU <[esp+4*9]>
EBXSAV      TEXTEQU <[esp+4*10]>
NBH         TEXTEQU <[esp+4*11]>
NBV         TEXTEQU <[esp+4*12]>
DELTAPSAV   TEXTEQU <[esp+4*13]>
LOCALSIZE = 4*14
FORRGB      TEXTEQU <DPTR [esp+LOCALSIZE][4]>

        sub         esp, LOCALSIZE
          
        mov         EDISAV, edi
        mov         EBXSAV, ebx

        ;// C0 = 8*(Vmax/V)
        shr         edx, 2
        movzx       eax, TBL_C0[edx]
        mov         C0, eax
        ;// C1 = ROWSIZE*(Hmax/H)
        movzx       ecx, TBL_C1[edx]
        mov         C1, ecx
        ;// C2 = 8*ROWSIZE*(Hmax/H)*(Vmax/V) = C0*C1
        imul        eax, ecx
        mov         C2, eax
        ;// C3 = 4*Scanlength - (Hmax-1)*ROWSIZE
        mov         ecx, [Ctx].Image.scanlength
        shl         ecx, 2
        mov         eax, [Ctx].FrameInfo.Hmax
        mov         NBH, eax
        dec         eax
        shl         eax, 3+2
        neg         eax
        add         eax, ecx
        mov         C3, eax
        ;// C4 = - 4*(8*Vmax - 1)*ScanLength + ROWSIZE
        ;//    = ROWSIZE - DeltaRGB
        mov         eax, [Ctx].FrameInfo.Vmax
        mov         NBV, eax
        mov         eax, ROWSIZE
        sub         eax, [Ctx].FrameInfo.DeltaRGB
        mov         C4, eax
        
        ;// DELTAPSAV = 4*(Nf+1)
        mov         eax, [Ctx].Image.Nf
        lea         eax, [4*eax+4]
        mov         DELTAPSAV, eax

        cmp         FORRGB, 1
        je          @F
        mov         eax, [COMP].H
        mov         NBH, eax
        mov         eax, [COMP].V
        mov         NBV, eax
@@:                    
        mov         eax, NBV
        mov         J, eax
JLoop:
        mov         eax, C0
        mov         N, eax
NLoop:
        mov         ROWSTART, PSAMPLE
        mov         I, NBH
ILoop:
        mov         K, C1
        mov         eax, PSAMPLE
KLoop:
        mov         DPTR [PSAVE], 4*8
        cmp         FORRGB, 1
        je          @F
        mov         [PSAVE], eax
        add         eax, ROWSIZE
@@:
        add         PSAVE, DELTAPSAV
        sub         K, ROWSIZE
        jnz         KLoop
        ;// PSAMPLE += 8*(Hmax/H)*(Vmax/V)*ROWSIZE (C2)
        add         PSAMPLE, C2
        dec         I
        jnz         ILoop
        mov         eax, C0
        cmp         N, eax
        jne         @F
        mov         NEXTV, PSAMPLE
@@:
        ;// PSAMPLE = ROWSTART + (Hmax/H)*ROWSIZE (C1)
        mov         eax, C1
        add         eax, ROWSTART
        mov         PSAMPLE, eax          
        cmp         FORRGB, 1
        jne         @F
        ;// PSAVE[-4] =  4*Scanlength - (Hmax-1)*ROWSIZE (C3)
        mov         ecx, DELTAPSAV
        neg         ecx
        mov         eax, C3
        mov         [PSAVE][ecx], eax
@@:
        dec         N
        jnz         NLoop
        mov         PSAMPLE, NEXTV
        dec         J
        jnz         JLoop

        cmp         FORRGB, 1
        jne         Done
        ;// PSAVE[-1] = - 4*(8*Vmax - 1)*ScanLength + ROWSIZE (C4)
        mov         ecx, DELTAPSAV
        neg         ecx        
        mov         eax, C4
        mov         [PSAVE][ecx], eax         
Done:
        mov         edi, EDISAV
        mov         ebx, EBXSAV
        add         esp, LOCALSIZE
        ret         4
RGB_GenPointer ENDP

;//=========================================================================
;// Convert YCbCr to RGB (SSE2)
;//=========================================================================

RGB_YCbCrConv_SSE2 PROC

Y     TEXTEQU <edi>
CB    TEXTEQU <ebx>
CR    TEXTEQU <ecx>
DST   TEXTEQU <edx>
I     TEXTEQU <eax>
PTBL  TEXTEQU <DPTR esi>

        PROFILE_IN

        push        esi
        push        edi
        push        ebx
                            
        ;// DST = pRGB;
        ;// Y = &SampleY0;
        ;// CB = &SampleCB;
        ;// CR = &SampleCR;
        ;// PTBL = &PointerTable[0]
        ;// for (i = 0; i < 8*Vmax*Hmax; i++) {
        ;//   ConvertRow(DST,Y,CB,CR)
        ;//   Y = PTBL[4*i]
        ;//   CB = PTBL[4*i+1]
        ;//   CR = PTBL[4*i+2]
        ;//   DST += PTBL[4*i+3]
        ;// }
          
        mov         DST, [Ctx].FrameInfo.cRGB
        mov         I, [Ctx].FrameInfo.HmaxVmax64
        mov         PTBL, [Ctx].FrameInfo.PointerTable
        shr         I, 1
        neg         I
        movaps      xmm7, TBL_MultCR
ILoop:          
        mov         Y, [PTBL][I]
        mov         CB, [PTBL][I+4]
        mov         CR, [PTBL][I+8]
        ;// convert a row
        ;// R = (Y+S)              + 1.402   Cr
        ;// G = (Y+S) - 0.34414 Cb - 0.71414 Cr
        ;// B = (Y+S) + 1.772   Cb
        ;// S = 128 for 8-bit precision, 2048 for 12-bit precision
        movaps      xmm6, TBL_MultCB            ;// TBL_MultCB
        movaps      xmm0, [Y]                   ;// Y3  Y2  Y1  Y0
        movaps      xmm1, [CB]                  ;// CB3 CB2 CB1 CB0  
        movaps      xmm2, [CR]                  ;// CR3 CR2 CR1 CR0
        addps       xmm0, [Ctx].FrameInfo.S     ;// Y+S
        pshufd      xmm3, xmm0, 0               ;// Y0 Y0 Y0 Y0
        pshufd      xmm4, xmm1, 0               ;// CB0 CB0 CB0 CB0
        pshufd      xmm5, xmm2, 0               ;// CR0 CR0 CR0 CR0
        mulps       xmm4, xmm6                  ;// 1.772*CB0 -0.34414*CB0 0 0
        mulps       xmm5, xmm7                  ;// 0 -0.71414*CR0 1.402*CR0 0
        addps       xmm3, xmm4                  ;// Y0+1.772*CB0 Y0-0.34414*CB0 Y0 Y0
        addps       xmm3, xmm5                  ;// B0 G0 R0 Y0
        pshufd      xmm4, xmm0, 01010101b       ;// Y1 Y1 Y1 Y1
        pshufd      xmm5, xmm1, 01010101b       ;// CB1 CB1 CB1 CB1

⌨️ 快捷键说明

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