You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
727 lines
27 KiB
727 lines
27 KiB
/* *************************************************************************
|
|
** INTEL Corporation Proprietary Information
|
|
**
|
|
** This listing is supplied under the terms of a license
|
|
** agreement with INTEL Corporation and may not be copied
|
|
** nor disclosed except in accordance with the terms of
|
|
** that agreement.
|
|
**
|
|
** Copyright (c) 1996 Intel Corporation.
|
|
** All Rights Reserved.
|
|
**
|
|
** *************************************************************************
|
|
*/
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// $Author:$
|
|
// $Date:$
|
|
// $Archive:$
|
|
// $Header:$
|
|
// $Log:$
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
//--------------------------------------------------------------------------
|
|
//
|
|
// d1bvriq.cpp
|
|
//
|
|
// Description:
|
|
// This routine performs run length decoding and inverse quantization
|
|
// of transform coefficients for one non-empty block.
|
|
//
|
|
// Routines:
|
|
// VLD_RLD_IQ_Block
|
|
//
|
|
// Inputs (dwords pushed onto stack by caller):
|
|
// lpBlockAction pointer to Block action stream for current blk.
|
|
//
|
|
// lpSrc The input bitstream.
|
|
//
|
|
// uBitsInOut Number of bits already read.
|
|
//
|
|
// pIQ_INDEX Pointer to coefficients and indices.
|
|
//
|
|
// pN Pointer to number of coefficients read.
|
|
//
|
|
// Returns:
|
|
// 0 on bit stream error, otherwise total number of bits read
|
|
// (including number read prior to call).
|
|
//
|
|
// Note:
|
|
// This has not been verfied as layout!!!
|
|
// The structure of gTAB_TCOEFF_MAJOR is as follows:
|
|
// bits name: description
|
|
// ---- ----- -----------
|
|
// 25-18 bits: number of bitstream bits used
|
|
// 17 last: flag for last coefficient
|
|
// 16-9 run: number of preceeding 0 coefficients plus 1
|
|
// 8-2 level: absolute value of coefficient
|
|
// 1 sign: sign of coefficient
|
|
// 0 hit: 1 = major table miss, 0 = major table hit
|
|
//
|
|
// The structure of gTAB_TCOEFF_MINOR is the same, right shifted by 1 bit.
|
|
// A gTAB_TCOEFF_MAJOR value of 00000001h indicates the escape code.
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
//Block level decoding for H.261 decoder
|
|
#include "precomp.h"
|
|
|
|
#define HIGH_FREQ_CUTOFF 6 + 4
|
|
|
|
// local variable definitions
|
|
#define FRAMEPOINTER esp
|
|
#define L_BITSUSED FRAMEPOINTER + 0 // 4 byte
|
|
#define L_QUANT L_BITSUSED + 4
|
|
#define L_RUNCUM L_QUANT + 4
|
|
#define L_EVENT L_RUNCUM + 4
|
|
#define L_BLOCKTYPE L_EVENT + 4
|
|
#define L_COEFFINDEX L_BLOCKTYPE + 4
|
|
#define L_INPUTSRC L_COEFFINDEX + 4
|
|
#define L_LPACTION L_INPUTSRC + 4
|
|
#define L_ecx L_LPACTION + 4
|
|
#define L_NUMOFBYTES L_ecx + 4
|
|
#define L_NUMOFBITS L_NUMOFBYTES + 4
|
|
|
|
#ifdef CHECKSUM_MACRO_BLOCK
|
|
#define L_SAVEREG L_NUMOFBITS + 4
|
|
#define L_SAVEREG2 L_SAVEREG + 4
|
|
#define L_CHECKSUM L_SAVEREG2 + 4
|
|
#define L_CHECKSUMADDR L_CHECKSUM + 4
|
|
#define L_COEFFCOUNT L_CHECKSUMADDR + 4
|
|
#define L_COEFFVALUE L_COEFFCOUNT + 4
|
|
#else
|
|
#define L_COEFFCOUNT L_NUMOFBITS + 4
|
|
#define L_COEFFVALUE L_COEFFCOUNT + 4
|
|
#endif
|
|
|
|
|
|
#define L_END_OF_FRAME FRAMEPOINTER + 128 // nothing
|
|
#define LOCALSIZE ((128+3)&~3) // keep aligned
|
|
|
|
#define HUFFMAN_ESCAPE 0x5f02 // Huffman escape code
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
// Decode a none empty block
|
|
//
|
|
////////////////////////////////////////////////////////////////
|
|
|
|
#pragma code_seg("IACODE1")
|
|
extern "C" __declspec(naked)
|
|
U32 VLD_RLD_IQ_Block(T_BlkAction *lpBlockAction,
|
|
U8 *lpSrc,
|
|
U32 uBitsread,
|
|
U32 *pN,
|
|
U32 *pIQ_INDEX)
|
|
{
|
|
__asm {
|
|
push ebp // save callers frame pointer
|
|
mov ebp, esp // make parameters accessible
|
|
push esi // assumed preserved
|
|
push edi
|
|
push ebx
|
|
xor eax, eax
|
|
xor edx, edx
|
|
|
|
sub esp, LOCALSIZE // reserve local storage
|
|
mov esi, lpSrc
|
|
|
|
#ifdef CHECKSUM_MACRO_BLOCK
|
|
mov edi, uCheckSum
|
|
;
|
|
mov ecx, [edi]
|
|
mov [L_CHECKSUMADDR], edi
|
|
;
|
|
mov [L_CHECKSUM], ecx
|
|
#endif
|
|
// zero out the BLOCKSTORE , 64*2 /32 load, 64*2/4 writes
|
|
// it is very likely that the cache has been loaded for
|
|
// the stack. Need to find out this later.
|
|
|
|
mov edi, lpBlockAction //pair with operation above
|
|
xor ecx, ecx
|
|
|
|
mov [L_INPUTSRC], esi
|
|
mov eax, uBitsread
|
|
|
|
mov [L_LPACTION], edi
|
|
|
|
mov [L_COEFFCOUNT], ecx // zero out coefficient counter
|
|
mov [L_COEFFVALUE], ecx // zero out coefficient value
|
|
mov [L_NUMOFBYTES], ecx // zero out number of bytes used
|
|
|
|
mov dl, [edi]T_BlkAction.u8Quant
|
|
mov cl, al // init cl to no. of bits used
|
|
|
|
shl edx, 6 // leave room for val later,
|
|
// quant*32 shift by 6 because,
|
|
// 5-bits for quant look up &
|
|
// it's a word table. Don't need
|
|
// to multiply by 2 later
|
|
mov [L_BITSUSED], eax // init the counter
|
|
mov bl, [edi]T_BlkAction.u8BlkType
|
|
mov edi, pIQ_INDEX // Load edi with address of output
|
|
// array
|
|
mov [L_QUANT], edx // save quant for this block;
|
|
mov [L_BLOCKTYPE], ebx // save block type
|
|
;
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// registers:
|
|
// eax: 4 bytes input bits
|
|
// ebx: block type
|
|
// ecx: bits count
|
|
// edx: quant*64
|
|
// esi: input source
|
|
// edi: output array address
|
|
// ebp: bits count >>4
|
|
|
|
mov DWORD PTR [L_RUNCUM], 0ffh // Adjust total run for INTER Blocks
|
|
|
|
cmp bl, 1 // bl has block type
|
|
ja ac_coeff // jump if not INTRA coded
|
|
|
|
//decode DC first, and invserse quanitzation, 13 clocks
|
|
mov ah,[esi]
|
|
xor ebx, ebx
|
|
mov al,[esi+1]
|
|
mov DWORD PTR [L_RUNCUM], ebx
|
|
shl eax, cl
|
|
;
|
|
and eax, 0ffffh
|
|
;
|
|
shr eax, 8
|
|
;
|
|
|
|
#ifdef CHECKSUM_MACRO_BLOCK
|
|
mov [L_SAVEREG], eax // save eax in temp
|
|
mov edi, [L_CHECKSUM]
|
|
shl eax, 8
|
|
and eax, 0000ff00h // just get DC
|
|
;
|
|
cmp eax, 0000ff00h // special case when INTRADC==ff, use 80
|
|
jne not_255_chk
|
|
mov eax, 00008000h
|
|
|
|
not_255_chk:
|
|
add edi, eax // add to DC checksum
|
|
;
|
|
mov [L_CHECKSUM], edi // save updated checksum
|
|
mov eax, [L_SAVEREG] // restore eax
|
|
#endif
|
|
|
|
shl eax, 3 // INTRADC*8
|
|
xor ecx, ecx
|
|
cmp eax, 7f8h // take out 11111111 code word.
|
|
jne not_255
|
|
mov eax, 0400h
|
|
|
|
not_255:
|
|
mov ebx, eax // inversed quantized DC
|
|
|
|
// save in output array value and index
|
|
mov [edi], eax // DC inversed quantized value
|
|
mov [edi+4], ecx // index 0
|
|
add edi, 8 // increment output address
|
|
|
|
mov ecx,[L_COEFFCOUNT] // get coefficient counter
|
|
mov ebx,[L_BLOCKTYPE]
|
|
inc ecx
|
|
mov [L_COEFFCOUNT], ecx // save updated coef counter
|
|
mov ecx,[L_BITSUSED]
|
|
test bl,bl
|
|
jz done_dc // jump if only the INTRADC present
|
|
add cl, 8 // Add 8 to bits used counter for DC
|
|
jmp vld_code // Skip around 1s special case
|
|
|
|
ac_coeff:
|
|
nop
|
|
mov ah,[esi]
|
|
mov al,[esi+1]
|
|
mov dh,[esi+2]
|
|
shl eax,16
|
|
mov dl,[esi+3]
|
|
mov ax, dx
|
|
shl eax, cl
|
|
mov [L_ecx], ecx
|
|
mov edx, eax //save in edx
|
|
shr eax, 24 //mask of high order 24 bits
|
|
;
|
|
; // agi
|
|
;
|
|
mov bh, gTAB_TCOEFF_tc1a[eax*2] //get the codewords
|
|
mov bl, gTAB_TCOEFF_tc1a[eax*2+1] //get the codewords
|
|
jmp InFrom1stac
|
|
|
|
vld_code:
|
|
mov ah,[esi]
|
|
mov dh,[esi+2]
|
|
mov al,[esi+1]
|
|
mov dl,[esi+3]
|
|
shl eax,16
|
|
mov ax, dx
|
|
shl eax, cl
|
|
mov [L_ecx], ecx
|
|
mov edx, eax //save in edx
|
|
shr eax, 24 //mask of high order 24 bits
|
|
;
|
|
; // agi
|
|
;
|
|
mov bh, gTAB_TCOEFF_tc1[eax*2] //get the codewords
|
|
mov bl, gTAB_TCOEFF_tc1[eax*2+1] //get the codewords
|
|
|
|
InFrom1stac:
|
|
mov ax, bx
|
|
cmp bx, HUFFMAN_ESCAPE
|
|
mov [L_EVENT], eax // 3-bits lenght-1,1-bit if code>8bits,
|
|
// 4-bits run,8-bits val
|
|
je Handle_Escapes
|
|
|
|
sar ax, 12 // if 12th bit NOT set, code <= 8-bits
|
|
mov [L_NUMOFBITS], ax // save for later the number of bits
|
|
js Gt8bits // jump
|
|
|
|
mov eax, [L_EVENT]
|
|
mov ebx, [L_QUANT] //bx:4::8 quant has val
|
|
and eax, 0ffh
|
|
movsx eax, al //sign extend level
|
|
add eax, eax
|
|
jns AROUND // if positive jump
|
|
neg eax // convert neg to positive
|
|
inc eax // increment
|
|
|
|
#ifdef CHECKSUM_MACRO_BLOCK
|
|
/* add in sign to checksum */
|
|
|
|
mov [L_SAVEREG2], edi // save edi in temp
|
|
mov edi, [L_CHECKSUM]
|
|
inc edi // add 1 to checksum when sign negative
|
|
|
|
/* add in level, shift left 8 and add to checksum */
|
|
|
|
mov [L_SAVEREG], eax // save eax in temp
|
|
mov eax, [L_EVENT]
|
|
and eax, 0ffh
|
|
neg eax
|
|
and eax, 0ffh
|
|
shl eax, 8 // shift level left 8
|
|
add edi, eax // add to level checksum
|
|
mov eax, [L_SAVEREG] // restore eax
|
|
mov [L_CHECKSUM], edi // save updated checksum
|
|
mov edi, [L_SAVEREG2] // restore edi
|
|
jmp NEG_AROUND
|
|
#endif
|
|
|
|
AROUND:
|
|
|
|
#ifdef CHECKSUM_MACRO_BLOCK
|
|
/* add in level, shift left 8 and add to checksum */
|
|
|
|
mov [L_SAVEREG], eax // save eax in temp
|
|
mov [L_SAVEREG2], edi // save edi in temp
|
|
mov eax, [L_EVENT]
|
|
shl eax, 8 // shift level left 8
|
|
mov edi, [L_CHECKSUM]
|
|
and eax, 0000ff00h // just get level
|
|
;
|
|
add edi, eax // add to level checksum
|
|
mov eax, [L_SAVEREG] // restore eax
|
|
mov [L_CHECKSUM], edi // save updated checksum
|
|
mov edi, [L_SAVEREG2] // restore edi
|
|
NEG_AROUND:
|
|
#endif
|
|
|
|
mov bx, gTAB_INVERSE_Q[2*eax+ebx] //ebx has the inverse quant
|
|
mov eax, [L_EVENT]
|
|
shr eax, 8 //leave RUN at al
|
|
;
|
|
and eax, 0fh // RUN is just 4-bits
|
|
|
|
#ifdef CHECKSUM_MACRO_BLOCK
|
|
/* add in run, shift left 24 and add to checksum */
|
|
|
|
mov [L_SAVEREG], eax // save eax in temp
|
|
mov [L_SAVEREG2], edi // save edi in temp
|
|
shl eax, 24 // shift run left 24
|
|
mov edi, [L_CHECKSUM]
|
|
add edi, eax // add run to checksum
|
|
mov eax, [L_SAVEREG] // restore eax
|
|
mov [L_CHECKSUM], edi // save updated checksum
|
|
mov edi, [L_SAVEREG2] // restore edi
|
|
#endif
|
|
|
|
mov edx, [L_RUNCUM] // Zig-zag and run length decode
|
|
inc al // run+1
|
|
add dl, al // dl cumulated run
|
|
mov [L_RUNCUM], edx // update the cumulated run ;
|
|
mov ecx, gTAB_ZZ_RUN[edx*4]
|
|
mov edx, [L_EVENT] // restore run, level to temp
|
|
movsx ebx,bx
|
|
and edx, 0ffh // get just level
|
|
add edx, edx // For EOB level will be zero
|
|
jz last_coeff // jump to last_coeff if EOB
|
|
|
|
// save in output array value and index
|
|
mov [edi], ebx // save inversed quantized value
|
|
mov [edi+4], ecx // save index
|
|
|
|
mov ecx,[L_COEFFCOUNT] // get coefficient counter
|
|
inc ecx
|
|
mov [L_COEFFCOUNT], ecx // save updated coef counter
|
|
|
|
mov ecx, [L_ecx]
|
|
mov eax, [L_NUMOFBITS] // fetch num of bits-1
|
|
inc al
|
|
add edi, 8 // increment output address
|
|
add cl, al //adjust bits used,
|
|
mov ebx, [L_NUMOFBYTES] // fetch number of bytes used
|
|
test al, al
|
|
jz error
|
|
cmp cl, 16
|
|
jl vld_code //if needs to save ebx, and edx, jump
|
|
add esi, 2 //to vld_code to reload
|
|
inc ebx // increment number of bytes used
|
|
mov [L_NUMOFBYTES], ebx // store updated number of bytes used
|
|
;
|
|
sub cl, 16
|
|
jmp vld_code
|
|
|
|
/////////
|
|
Gt8bits:
|
|
|
|
// code > 8-bits
|
|
|
|
neg ax // -(no of bits -1)
|
|
shl edx, 8 // shift of just used 8 bits
|
|
add ecx, 8 // Update bit counter by 8
|
|
add cx, ax // Update by extra bits
|
|
and ebx, 0ffh
|
|
dec ecx // dec because desired value is no of
|
|
// bits -1
|
|
mov [L_ecx], ecx // store
|
|
mov cl, 32 // 32
|
|
sub cl, al // get just the extra bits
|
|
shr edx, cl
|
|
add bx, dx
|
|
xor ecx, ecx
|
|
movzx ebx, bx
|
|
shl edx, 3 //do this even if hit major
|
|
mov [L_NUMOFBITS], ecx // set num of bits for codes > 8 to 0
|
|
// because already updated ecx.
|
|
mov ah,gTAB_TCOEFF_tc2[ebx*2]//use minor table with 10 bits
|
|
mov al, gTAB_TCOEFF_tc2[ebx*2+1]
|
|
mov ebx, [L_QUANT] //bx:4::8 quant has val
|
|
mov [L_EVENT], eax
|
|
// RLD+ ZZ and Inverse quantization
|
|
and eax, 0ffh
|
|
movsx eax, al //sign extend level
|
|
add eax, eax
|
|
jns AROUND1 // if positive jump
|
|
neg eax // convert neg to positive
|
|
inc eax // increment
|
|
|
|
#ifdef CHECKSUM_MACRO_BLOCK
|
|
/* add in sign to checksum */
|
|
|
|
mov [L_SAVEREG2], edi // save edi in temp
|
|
mov edi, [L_CHECKSUM]
|
|
inc edi // add 1 to checksum when sign negative
|
|
|
|
/* add in level, shift left 8 and add to checksum */
|
|
|
|
mov [L_SAVEREG], eax // save eax in temp
|
|
mov eax, [L_EVENT]
|
|
and eax, 0ffh
|
|
neg eax
|
|
and eax, 0ffh
|
|
shl eax, 8 // shift level left 8
|
|
add edi, eax // add to level checksum
|
|
mov eax, [L_SAVEREG] // restore eax
|
|
mov [L_CHECKSUM], edi // save updated checksum
|
|
mov edi, [L_SAVEREG2] // restore edi
|
|
jmp NEG_AROUND1
|
|
#endif
|
|
|
|
AROUND1:
|
|
|
|
#ifdef CHECKSUM_MACRO_BLOCK
|
|
/* add in level, shift left 8 and add to checksum */
|
|
|
|
mov [L_SAVEREG], eax // save eax in temp
|
|
mov [L_SAVEREG2], edi // save edi in temp
|
|
mov eax, [L_EVENT]
|
|
shl eax, 8 // shift level left 8
|
|
mov edi, [L_CHECKSUM]
|
|
and eax, 0000ff00h // just get level
|
|
;
|
|
add edi, eax // add to level checksum
|
|
mov eax, [L_SAVEREG] // restore eax
|
|
mov [L_CHECKSUM], edi // save updated checksum
|
|
mov edi, [L_SAVEREG2] // restore edi
|
|
NEG_AROUND1:
|
|
#endif
|
|
|
|
mov bx, gTAB_INVERSE_Q[2*eax+ebx] //ebx has the inverse quant
|
|
mov eax, [L_EVENT]
|
|
shr eax, 8 //leave RUN at al
|
|
and eax, 01fh // RUN is just 5-bits
|
|
|
|
#ifdef CHECKSUM_MACRO_BLOCK
|
|
/* add in run, shift left 24 and add to checksum */
|
|
|
|
mov [L_SAVEREG], eax // save eax in temp
|
|
mov [L_SAVEREG2], edi // save edi in temp
|
|
shl eax, 24 // shift run left 24
|
|
mov edi, [L_CHECKSUM]
|
|
add edi, eax // add run to checksum
|
|
mov eax, [L_SAVEREG] // restore eax
|
|
mov [L_CHECKSUM], edi // save updated checksum
|
|
mov edi, [L_SAVEREG2] // restore edi
|
|
#endif
|
|
|
|
mov edx, [L_RUNCUM] //Zig-zag and run length decode
|
|
inc al // run+1
|
|
add dl, al //dl cumulated run
|
|
movsx ebx,bx
|
|
mov [L_RUNCUM], edx //update the cumulated run ;
|
|
mov ecx, gTAB_ZZ_RUN[edx*4]
|
|
mov edx, [L_EVENT] // restore run, level to temp
|
|
and edx, 0ffh // get just level
|
|
add edx, edx // For EOB level will be zero
|
|
jz last_coeff // jump to last_coeff if EOB
|
|
|
|
// save in output array value and index
|
|
mov [edi], ebx // store inversed quantized value
|
|
mov [edi+4], ecx // store index
|
|
|
|
mov ecx,[L_COEFFCOUNT] // get coefficient counter
|
|
inc ecx
|
|
mov [L_COEFFCOUNT], ecx // save updated coef counter
|
|
|
|
mov ecx, [L_ecx]
|
|
mov eax, [L_NUMOFBITS] // fetch num of bits-1
|
|
inc al
|
|
add edi, 8 // increment output address
|
|
add cl, al //adjust bits used,
|
|
mov ebx, [L_NUMOFBYTES] // fetch num of bytes used
|
|
test al, al
|
|
jz error
|
|
cmp cl, 16
|
|
jl vld_code //if needs to save ebx, and edx, jump
|
|
add esi, 2 //to vld_code to reload
|
|
inc ebx // increment number of bytes used
|
|
mov [L_NUMOFBYTES], ebx // store updated number of bytes used
|
|
;
|
|
sub cl, 16
|
|
jmp vld_code
|
|
|
|
last_coeff: //need to tell it is INTRA or INTER coded
|
|
mov ecx, [L_ecx] // restore no of bits used
|
|
mov eax, [L_NUMOFBITS] // get no of bits-1
|
|
inc al
|
|
add cl,al //update bits used count
|
|
mov [L_ecx], ecx
|
|
|
|
#ifdef CHECKSUM_MACRO_BLOCK
|
|
mov ecx, [L_CHECKSUM]
|
|
mov edi, [L_CHECKSUMADDR]
|
|
mov [edi], ecx
|
|
#endif
|
|
// Add in High Frequency Cutoff check
|
|
//
|
|
mov eax, [L_RUNCUM] // Total run
|
|
mov edx, [L_LPACTION] //pair with operation above
|
|
cmp eax, HIGH_FREQ_CUTOFF
|
|
jg No_set
|
|
|
|
mov bl, [edx]T_BlkAction.u8BlkType
|
|
or bl, 80h // set hi bit
|
|
mov [edx]T_BlkAction.u8BlkType, bl
|
|
|
|
//
|
|
No_set:
|
|
mov eax, pN
|
|
mov ecx,[L_COEFFCOUNT] // get coefficient counter
|
|
mov [eax], ecx // return number of coef
|
|
//akk
|
|
mov edi,[L_NUMOFBYTES]
|
|
mov eax,[L_ecx]
|
|
shl edi, 4 // convert bytes used to bits used
|
|
add esp,LOCALSIZE // free locals
|
|
add eax,edi // add bits used to last few bits used
|
|
pop ebx
|
|
pop edi
|
|
pop esi
|
|
pop ebp
|
|
ret
|
|
|
|
error:
|
|
#ifdef CHECKSUM_MACRO_BLOCK
|
|
mov ecx, [L_CHECKSUM]
|
|
mov edi, [L_CHECKSUMADDR]
|
|
mov [edi], ecx
|
|
#endif
|
|
xor eax,eax
|
|
add esp,LOCALSIZE // free locals
|
|
pop ebx
|
|
pop edi
|
|
pop esi
|
|
pop ebp
|
|
ret
|
|
|
|
//NOTES: 1. the following codes need to be optimized later.
|
|
// 2. the codes will be rarely used.
|
|
// at this point: eax has 32bits - cl valid bits
|
|
// first cl+7 bits
|
|
Handle_Escapes: //process escape code separately
|
|
add cl, 6 // escape 6-bit code
|
|
mov ebx, [L_NUMOFBYTES] // fetch number of bytes used
|
|
cmp cl, 16
|
|
jl less_16
|
|
add esi, 2
|
|
sub cl, 16
|
|
inc ebx // increment number of bytes used
|
|
mov [L_NUMOFBYTES], ebx // store updated number of bytes used
|
|
less_16:
|
|
mov ah,[esi] // these codes will be further
|
|
mov dh,[esi+2]
|
|
mov al,[esi+1]
|
|
mov dl,[esi+3]
|
|
shl eax,16
|
|
mov ebx, [L_RUNCUM]
|
|
mov ax, dx
|
|
inc bl //increae the total run
|
|
shl eax, cl
|
|
mov edx,eax
|
|
shr eax, 32-6 //al has run
|
|
|
|
#ifdef CHECKSUM_MACRO_BLOCK
|
|
/* add in run, shift left 24 and add to checksum */
|
|
|
|
mov [L_SAVEREG], eax // save eax in temp
|
|
mov [L_SAVEREG2], edi // save edi in temp
|
|
shl eax, 24 // shift run left 24
|
|
mov edi, [L_CHECKSUM]
|
|
add edi, eax // add run to checksum
|
|
mov eax, [L_SAVEREG] // restore eax
|
|
mov [L_CHECKSUM], edi // save updated checksum
|
|
mov edi, [L_SAVEREG2] // restore edi
|
|
#endif
|
|
|
|
shl edx, 6 // cl < 6, cl+6 < 16
|
|
add al,bl
|
|
sar edx, 32-8 //8 bits level, keep the sign
|
|
mov [L_RUNCUM], eax
|
|
; // agi
|
|
;
|
|
mov ebx, gTAB_ZZ_RUN[eax*4] //run length decode
|
|
mov eax, [L_QUANT] //bx:4::8 quant has val
|
|
shr eax, 6 //recover quant
|
|
mov [L_COEFFINDEX], ebx
|
|
|
|
#ifdef CHECKSUM_MACRO_BLOCK
|
|
/* add in level, shift left 8 and add to checksum */
|
|
|
|
mov [L_SAVEREG], edx // save edx in temp
|
|
mov [L_SAVEREG2], edi // save edi in temp
|
|
mov edi, [L_CHECKSUM]
|
|
cmp edx, 0 // test level
|
|
jns Pos_Level
|
|
neg edx
|
|
inc edi // add 1 when sign negative
|
|
Pos_Level:
|
|
shl edx, 8 // shift level left 8
|
|
and edx, 0000ff00h // just get level
|
|
;
|
|
add edi, edx // add to level checksum
|
|
mov edx, [L_SAVEREG] // restore edx
|
|
mov [L_CHECKSUM], edi // save updated checksum
|
|
mov edi, [L_SAVEREG2] // restore edi
|
|
#endif
|
|
|
|
// new code
|
|
test edx, 7fh // test for invalid codes
|
|
jz error
|
|
imul edx, eax // edx = L*Q
|
|
;
|
|
dec eax // Q-1
|
|
mov ebx, edx // mask = LQ
|
|
sar ebx, 31 // -l if L neq, else 0
|
|
or eax, 1 // Q-1 if Even, else Q
|
|
xor eax, ebx // -Q[-1] if L neg, else = Q[-1]
|
|
add edx, edx // 2*L*Q
|
|
sub eax, ebx // -(Q[-1]) if L neg, else = Q[-1]
|
|
add edx, eax // 2LQ +- Q[-1]
|
|
|
|
// now clip to -2048 ... +2047 (12 bits: 0xfffff800 <= res <= 0x000007ff)
|
|
cmp edx, -2048
|
|
jge skip1
|
|
mov edx, -2048
|
|
jmp run_zz_q_fixed
|
|
skip1:
|
|
cmp edx, +2047
|
|
jle run_zz_q_fixed
|
|
mov edx, +2047
|
|
|
|
run_zz_q_fixed:
|
|
mov ebx, [L_COEFFINDEX]
|
|
|
|
// save in output array value and index
|
|
mov [edi], edx // save inversed quantized value
|
|
mov [edi+4], ebx // save index
|
|
|
|
mov ebx,[L_COEFFCOUNT] // get coefficient counter
|
|
inc ebx
|
|
mov [L_COEFFCOUNT], ebx // save updated coef counter
|
|
|
|
add cl, 14
|
|
add edi, 8 // increment output address
|
|
mov ebx, [L_NUMOFBYTES] // fetch number of bytes used
|
|
cmp cl, 16
|
|
jl vld_code
|
|
add esi, 2
|
|
sub cl, 16
|
|
inc ebx // increment number of bytes used
|
|
mov [L_NUMOFBYTES], ebx // store updated number of bytes used
|
|
jmp vld_code
|
|
|
|
// 18 clocks without cache misses in the inner loop for
|
|
// the most frequenctly used events 8/2/95
|
|
// the above numbers changed becuase of integration with
|
|
// bitstream parsing and IDCT. 8/21/95
|
|
|
|
done_dc://intra coded block
|
|
add ecx, 8
|
|
|
|
#ifdef CHECKSUM_MACRO_BLOCK
|
|
mov ecx, [L_CHECKSUM]
|
|
mov edi, [L_CHECKSUMADDR]
|
|
mov [edi], ecx
|
|
#endif
|
|
// Add in High Frequency Cutoff check
|
|
//
|
|
mov edx, [L_RUNCUM] // Total run
|
|
mov eax, lpBlockAction //pair with operation above
|
|
cmp edx, HIGH_FREQ_CUTOFF
|
|
jg No_set_Intra
|
|
|
|
mov bl, [eax]T_BlkAction.u8BlkType
|
|
or bl, 80h // set hi bit
|
|
mov [eax]T_BlkAction.u8BlkType, bl
|
|
|
|
//
|
|
No_set_Intra:
|
|
mov eax, pN
|
|
mov ebx,[L_COEFFCOUNT] // get coefficient counter
|
|
mov [eax], ebx // return number of coef
|
|
|
|
add esp,LOCALSIZE // free locals
|
|
mov eax,ecx
|
|
pop ebx
|
|
pop edi
|
|
pop esi
|
|
pop ebp
|
|
ret
|
|
} //end of asm
|
|
|
|
} // end of VLD_RLD_IQ_Block
|
|
#pragma code_seg()
|