📄 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_BUILDGLOBAL(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}//#endifGLOBAL(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 + -