📄 jpeg.asm
字号:
;// 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 + -