/* *************************************************************************
**    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()