📄 jdhuff.c
字号:
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 + -