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

📄 jdhuff.c

📁 基于Linux的ffmepg decoder
💻 C
📖 第 1 页 / 共 3 页
字号:
      
	  r = s >> 4;
	  s &= 15;
      
	  if (s) {
	    k += r;
	    CHECK_BIT_BUFFER(br_state, s, return FALSE);
	    DROP_BITS(s);
	  } else {
	    if (r != 15)
	      break;
	    k += 15;
	  }
	}

      }
    }

    /* Completed MCU, so update state */
    BITREAD_SAVE_STATE(cinfo,entropy->bitstate);
    ASSIGN_STATE(entropy->saved, state);
  }

  /* Account for restart interval (no-op if not using restarts) */
  entropy->restarts_to_go--;

  return TRUE;
}


/*
 * Module initialization routine for Huffman entropy decoding.
 */

GLOBAL(void)
jinit_huff_decoder (j_decompress_ptr cinfo)
{
  huff_entropy_ptr entropy;
  int i;

  entropy = (huff_entropy_ptr)
    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
				SIZEOF(huff_entropy_decoder));
  cinfo->entropy = (struct jpeg_entropy_decoder *) entropy;
  entropy->pub.start_pass = start_pass_huff_decoder;
  entropy->pub.decode_mcu = decode_mcu;

  /* Mark tables unallocated */
  for (i = 0; i < NUM_HUFF_TBLS; i++) {
    entropy->dc_derived_tbls[i] = entropy->ac_derived_tbls[i] = NULL;
  }
}


//#ifdef HUFFTBL_BUILD
GLOBAL(void) ftmcp100_store_multilevel_huffman_table (j_decompress_ptr cinfo)
//void ftmcp100_store_multilevel_huffman_table (j_decompress_ptr cinfo)
{
  FTMCP100_CODEC *pCodec=(FTMCP100_CODEC *)cinfo->pCodec;
  d_derived_tbl *dtbl[4];
  unsigned int tbladdr[4];
  int di;
  huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy;  
  
  unsigned int mcubr_reg=0; // the MCUBR register
  unsigned int scode_reg=0; // to store the Huffman First LookAhead Table Bitlength


  #ifdef VPE_OUTPUT      
    RTL_DEBUG_OUT(0x94000000 | 4) // begin to store huffman multi-level table
  #endif
  
  // I got non-constant initialiser error message if I use array initialization
  // to initlaize the following variables in ARM Compiler.. So I use kind of 
  // silly way to initialze the following array of variables....*sigh*...
  dtbl[0]=(d_derived_tbl *) entropy->ac_derived_tbls[0]; // AC0
  dtbl[1]=(d_derived_tbl *) entropy->ac_derived_tbls[1]; // AC1
  dtbl[2]=(d_derived_tbl *) entropy->dc_derived_tbls[0]; // DC0
  dtbl[3]=(d_derived_tbl *) entropy->dc_derived_tbls[1]; // DC1
  
  tbladdr[0]=(unsigned int)HUFTBL0_AC;
  tbladdr[1]=(unsigned int)HUFTBL1_AC;
  tbladdr[2]=(unsigned int)HUFTBL0_DC;
  tbladdr[3]=(unsigned int)HUFTBL1_DC;  
	                      
  for(di=0;di<4;di++)
	{
	  register struct huft *t; // the header entry for table  
      register struct huft *p; // the first data entry for table
      unsigned int c; // used as counter
      unsigned int e=0; // current relative word address
      unsigned int v1,v2; // the encoded value for each entry to be output
      //unsigned int offset; // the offset in word address
      unsigned int twsize; // the table size in word
	  d_derived_tbl *d=dtbl[di];
      unsigned int *s=(unsigned int *)tbladdr[di]; // the base address for each table
      //unsigned int *qq;
      

      if(d) // if the table is not empty
        {
          p=d->tl; // the first data entry
          while (p != (struct huft *)NULL)
		  {
            t=p-1;
            //offset=(t->data.offset)>>1; // to get this table's starting word address by shift right the t->data.offset
            e=(t->data.offset)>>1;
            twsize=(t->tblsize)>>1; // to get the table size in word
            for(c=0;c<twsize;c++,e++) // the t->tblsize is in half-word size
              {
                //if(e<offset)
                //  {
                    // we store zero if the current address is less than the starting offset
		            // s[e] = v2;
                //  }                  
                //else
                //  {
                    v1=(p->tbl<<15)|(p->valid<<14)|(p->codelen<<11);
                    // it's table entry or data entry
                    v1|=((p->tbl)? p->data.offset:p->data.value);

                    //#ifdef VPE_OUTPUT      
                      //RTL_DEBUG_OUT(0x95000000 | v1) // dump v1 value
                    //#endif

                    p++; // advance to next half-word entry

                    v2=(p->tbl<<15)|(p->valid<<14)|(p->codelen<<11);
                    // it's table entry or data entry
                    v2|=((p->tbl)? p->data.offset:p->data.value);

                    //#ifdef VPE_OUTPUT      
                      //RTL_DEBUG_OUT(0x95000000 | v2) // dump v2 value
                    //#endif

                    v2=v1<<16 | v2;                    
                    s[e] = v2;
                    p++; // advance to next half-word entry
                //  }
              }
            p=t->nextpt;
		  } 
          // fill the remaining blank area
          /*
          v2=0;
          for(c=e;c<tblsize[di];c++)
            {                
		        s[c] = v2;
		    } 
          */
		}
      /*
	  else // the table is empty
		{
          v2=0;
          for(c=0;c<tblsize[di];c++)
		  {  
              s[c] = v2;
		  }
		}
      */
	}

  // to set the MCU number register
  mcubr_reg=(unsigned int)cinfo->blocks_in_MCU;  
  // after storing the Huffman Multi-Level Table into the Local Memory, we starts to 
  // store the Huffamn First LookAhead Bit Length for each table in the register SCODE  
  //scode_reg|=( (dtbl[2]->bl? (dtbl[2]->bl-1):0)     | (dtbl[0]->bl? (dtbl[0]->bl-1)<<4:0)
  //            |(dtbl[3]->bl? (dtbl[3]->bl-1)<<8:0)  | (dtbl[1]->bl? (dtbl[1]->bl-1)<<12:0) );
  scode_reg|=(  ((dtbl[2])?(dtbl[2]->bl? (dtbl[2]->bl-1):0):0)     | ((dtbl[0])?(dtbl[0]->bl? (dtbl[0]->bl-1)<<4:0):0)
              | ((dtbl[3])?(dtbl[3]->bl? (dtbl[3]->bl-1)<<8:0):0)  | ((dtbl[1])?(dtbl[1]->bl? (dtbl[1]->bl-1)<<12:0):0) );
  SET_MCUBR(mcubr_reg)
  SET_SCODE(scode_reg)

  #ifdef VPE_OUTPUT
    RTL_DEBUG_OUT(0x94000000 | 5) // end of storing huffman multi-level table
  #endif
}
//#endif

GLOBAL(boolean) processing_restart_marker (j_decompress_ptr cinfo)
{
  huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy;

  /* Process restart marker if needed; may have to suspend */
  if (cinfo->restart_interval) {
    if (entropy->restarts_to_go == 0)
      return process_restart(cinfo);
  }
      
  return FALSE;
}

GLOBAL(void) decrement_restart_interval (j_decompress_ptr cinfo)
{
  huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy;
  /* Account for restart interval (no-op if not using restarts) */
  entropy->restarts_to_go--;
}

GLOBAL(int) check_restart_marker (j_decompress_ptr cinfo)
{
  FTMCP100_CODEC *pCodec=(FTMCP100_CODEC *)cinfo->pCodec;
  huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy;
  int action=0;

  /* Process restart marker if needed; may have to suspend */
  if (cinfo->restart_interval)
    {
      if (entropy->restart_flag)
        {
          action=get_restart_action(cinfo);
          // to reset the previous DC here...
          SET_PYDCR(0)  // set JPEG Previous Y DC Value Register to zero
          SET_PUVDCR(0) // set JPEG Previous UV DC Value Register to zero
        }
    }
  return action;
}

GLOBAL(void) update_next_restart_number (j_decompress_ptr cinfo)
{
  huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy;
  if (cinfo->restart_interval)
    {
      if (entropy->restart_flag)
        {
          entropy->restart_flag=FALSE;
          /* Update next-restart state */
          cinfo->marker->next_restart_num = (cinfo->marker->next_restart_num + 1) & 7;          
        }
    }
}

GLOBAL(int) get_restart_action (j_decompress_ptr cinfo)
{
  FTMCP100_CODEC *pCodec=(FTMCP100_CODEC *)cinfo->pCodec;
  unsigned int vldsts_reg;
  int marker_msb,marker_lsb;
  int desired;
  int action=0;
  // to read the restart marker from register
  READ_VLDSTS(vldsts_reg)
  marker_msb=(vldsts_reg&0x0ff000000)>>24;
  marker_lsb=(vldsts_reg&0x000ff0000)>>16;
  // and we process invalid next restart marker here..
  if(marker_msb==0xff)
    {
      //if(marker_lsb != ((int) M_RST0 + cinfo->marker->next_restart_num)) 
      if(marker_lsb != (0xd0 + cinfo->marker->next_restart_num)) 
      /* Uh-oh, the restart markers have been messed up. */
      /* Let the data source manager determine how to resync. */
      //if (! (*cinfo->src->resync_to_restart) (cinfo,cinfo->marker->next_restart_num))
      //  return FALSE;
      {
        // we take the approach by forcing dequantization to process an empty segment 
        // and stop the entry decoder                  
        desired=cinfo->marker->next_restart_num;    
        if (marker_lsb < (int)0xc0 ) //(int) M_SOF0)
          action=2;  // invalid marker               
        else if (marker_lsb < (int) 0xd0 || marker_lsb > (int) 0xd7)
          action = 3; // valid non-restart marker
        else 
          {
            if (marker_lsb == ((int) 0xd0 + ((desired+1) & 7)) ||
   	            marker_lsb == ((int) 0xd0 + ((desired+2) & 7)))
 	          { 
 	            action=3;// cinfo->invalid_next_restart_marker=TRUE; 
 	          }
    	    else if ( marker_lsb == ((int) 0xd0 + ((desired-1) & 7)) ||
              	      marker_lsb == ((int) 0xd0 + ((desired-2) & 7)))
              action=2;		// a prior restart, so advance
            else
              action=1; // desired restart or too far away
          }
      }
    }
  return action;
                  /*
                  desired=cinfo->marker->next_restart_num;                  
                  if (marker_lsb < (int) M_SOF0)
                    action = 2;		// invalid marker
                  else if (marker_lsb < (int) M_RST0 || marker_lsb > (int) M_RST7)
                    action = 3;		// valid non-restart marker
                  else {
                    if (marker_lsb == ((int) M_RST0 + ((desired+1) & 7)) ||
    	                marker_lsb == ((int) M_RST0 + ((desired+2) & 7)))
   	                  action = 3;		// one of the next two expected restarts
                    else if (marker_lsb == ((int) M_RST0 + ((desired-1) & 7)) ||
            	             marker_lsb == ((int) M_RST0 + ((desired-2) & 7)))
 	                  action = 2;		// a prior restart, so advance
                    else
	                  action = 1;		// desired restart or too far away
                  } 
                  
                  action 1: discard marker and let entropy decoder resume processing
                  action 2: search next marker, to advance
                  action 3: return without advancing past this marker. Entropy decoder
                            will be forced to process an empty segment.
                  */
              
}

GLOBAL(void) reset_previous_DC (j_decompress_ptr cinfo)
{
  FTMCP100_CODEC *pCodec=(FTMCP100_CODEC *)cinfo->pCodec;
  huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy;

  // Process restart marker if needed; may have to suspend
  if (cinfo->restart_interval)
    {
      if (entropy->restart_flag)
        {
          entropy->restart_flag=FALSE;
          SET_PYDCR(0)  // set JPEG Previous Y DC Value Register to zero
          SET_PUVDCR(0) // set JPEG Previous UV DC Value Register to zero
        }
    }
}

⌨️ 快捷键说明

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