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