📄 jpg_header.c
字号:
#include "..\SysLib_Basic\SPCE3200_Register.h"
#include "..\SysLib_Basic\Sys_Global.h"
#include "mpeg4.h"
//#define PRINT_JPG_HEADER_INFO
#ifdef UART_EN
void print1(char* x);
void print3(char x [],int type,unsigned long y);
#ifdef PRINT_JPG_HEADER_INFO
void print2(char x [],int type,unsigned int y);
#endif
#endif //UART_EN
unsigned int Extract_JPG_Header(unsigned int JPG_SA);
unsigned char *find_marker(unsigned char *jpg_ptr,unsigned char* jpg_end_ptr);
unsigned char *bypass_jpg_segment(unsigned char *jpg_ptr);
unsigned int get_jpg_segment_length(unsigned char *jpg_ptr);
void set_jpg_mode(unsigned char *jpg_ptr);
void set_mcuno_reg(unsigned char *jpg_ptr);
void fill_quantize_sram(unsigned char *jpg_ptr);
void fill_huffman_reg(unsigned char *jpg_ptr);
void Get_Huffman_cs_cw(unsigned char *cs, unsigned int *cw, unsigned char *pointer);
void set_jpg_huffman_cw_reg(unsigned char htype,unsigned int *cw);
void set_jpg_huffman_dcs_reg(int chrominance,unsigned char *cs);
void set_jpg_huffman_acs_reg(int chrominance,unsigned char *cs);
void set_jpg_huffman_dcv_reg(int chrominance ,unsigned char *cv);
void set_jpg_huffman_acv_sram(int chrominance,unsigned char *cv);
void set_Huff_sram_mode(int Page);
void decompress_picture(unsigned int JPG_SA) //JPG_SA == 0xa0c0_0000
{
unsigned int vlc_sa,a;
vlc_sa = JPG_SA;
*P_MPEG4_QTABLE_CTRL = QValue_Ori | QTable_Soft; // Enable user-defined QTable 0x88220604
*P_MPEG4_BUFFER_CTRL = Buffer_2_Dis; // Disable 2 Buffer control 0x88220084
*P_MPEG4_MODE_CTRL3 = SOP_Trig_CPU; // SOP is triggered by CPU 0x88220064
*P_MPEG4_JFIF_COMPATIBLE = JFIF_En; // JFIF compatible 0x88220610
*P_MPEG4_TRUNCATE_CTRL = Q_Truncate; // Truncated after quantization 0x88220614
*P_MPEG4_THUMB_BURSTLENGTH = TNB_Len_5 | MESRAM_Dis | YUV422_Map_En; // Thumb nail burst length = 5, Disable ME SRAM
//0x8822008c
vlc_sa=Extract_JPG_Header(JPG_SA);
a=vlc_sa&0x00000001;
// Decode VLC Bit Stream Starting Offset, Low/Middle/High is Byte Boundard.
*P_MPEG4_DECVLCOFFSET_SALOW = vlc_sa; // 0x88220110
vlc_sa=vlc_sa>>8;
*P_MPEG4_DECVLCOFFSET_SAMID = vlc_sa;
vlc_sa=vlc_sa>>8;
*P_MPEG4_DECVLCOFFSET_SAHIGH = vlc_sa;
*P_MPEG4_COMPRESS_CTRL = Start_Decode_Write; // Start decoding 0x882200a0
while ((*P_MPEG4_COMPRESS_CTRL & MJPG_Decoding) != 0);
}
///////////////////////////////////////////////////////////////////////////////
void set_Huff_sram_mode(int Page)
{
if(Page==0)
*P_MPEG4_TSRAM_CTRL=0x00000001;
else if(Page==1)
*P_MPEG4_TSRAM_CTRL=0x00000005;
else if(Page==2)
*P_MPEG4_TSRAM_CTRL=0x00000009;
else if(Page==3)
*P_MPEG4_TSRAM_CTRL=0x0000000d;
else if(Page==4)
*P_MPEG4_TSRAM_CTRL=0x00000011;
else if(Page==5)
*P_MPEG4_TSRAM_CTRL=0x00000015;
else if(Page==6)
*P_MPEG4_TSRAM_CTRL=0x00000019;
else if(Page==7)
*P_MPEG4_TSRAM_CTRL=0x0000001d;
else
*P_MPEG4_TSRAM_CTRL=0x00000002; // Turn off CPU access Huffman SRAM
// The address map to Huffman Registers
}
////////////////////////////////////////////////////////////////////////////////
unsigned int Extract_JPG_Header(unsigned int JPG_SA)
{
unsigned char *jpg_ptrs;
unsigned char *jpg_ptrc;
unsigned char *jpg_end_ptr;
unsigned int vlc_sa=0;
unsigned char word;
jpg_ptrc = (unsigned char *)JPG_SA;
jpg_ptrs = find_marker(jpg_ptrc,jpg_end_ptr);
word = *jpg_ptrs;
if(word==0xd8) //jpg start markder
{
*P_MPEG4_SRAM_EN=0x00000001;//turn on sram
while(jpg_ptrc)
{
jpg_ptrc=find_marker(jpg_ptrs,jpg_end_ptr);
word=*jpg_ptrc;
jpg_ptrc++;
if((word>0xc0)&&(word<=0xcf)&&(word!=0xc4))
while(1); //I can't decode this JPG file
switch(word)
{
case 0xd9 : // jpg file end
jpg_ptrs=0;
break;
case 0xdb : // Quantization table
fill_quantize_sram(jpg_ptrc);
jpg_ptrs=bypass_jpg_segment(jpg_ptrc);
vlc_sa=(unsigned int)jpg_ptrs;
break;
case 0xc4 : // Huffman table
fill_huffman_reg(jpg_ptrc);
jpg_ptrs=bypass_jpg_segment(jpg_ptrc);
vlc_sa=(unsigned int)jpg_ptrs;
break;
case 0xda : // Start of scan
jpg_ptrs=bypass_jpg_segment(jpg_ptrc);
vlc_sa=(unsigned int)jpg_ptrs;
break;
case 0xc0 : // Start of frame
set_jpg_mode(jpg_ptrc);
jpg_ptrs=bypass_jpg_segment(jpg_ptrc);
vlc_sa=(unsigned int)jpg_ptrs;
break;
case 0xdd : // Restart_Interval mcu_no
set_mcuno_reg(jpg_ptrc);
jpg_ptrs=(jpg_ptrc+4);
vlc_sa=(unsigned int)jpg_ptrs;
break;
case 0x00 : // jpg_ptrs=jpg_ptrc+1;//append
jpg_ptrs=0;// i suppose there is no segment behind the vlc
break;
default :jpg_ptrs=bypass_jpg_segment(jpg_ptrc);
vlc_sa=(unsigned int)jpg_ptrs;
}
jpg_ptrc=jpg_ptrs;
}
}//if(word==0xd8)//jpg start markder
return vlc_sa;
}
/////////////////////////////////////////////////////////
unsigned char *find_marker(unsigned char *jpg_ptr,unsigned char* jpg_end_ptr)
{
unsigned char *pointer;
unsigned char word;
pointer=jpg_ptr;
word=*jpg_ptr;
while(word!=0xff)
{
pointer++;
word=*pointer;
if(pointer==jpg_end_ptr)
return 0;
}
return ++pointer;
}
/////////////////////////////////////////////////////////////////////////
void fill_quantize_sram(unsigned char *jpg_ptr){
const unsigned int jpeg_natural_order[64] = {
0, 1, 8, 16, 9, 2, 3, 10,
17, 24, 32, 25, 18, 11, 4, 5,
12, 19, 26, 33, 40, 48, 41, 34,
27, 20, 13, 6, 7, 14, 21, 28,
35, 42, 49, 56, 57, 50, 43, 36,
29, 22, 15, 23, 30, 37, 44, 51,
58, 59, 52, 45, 38, 31, 39, 46,
53, 60, 61, 54, 47, 55, 62, 63
};
unsigned int i,k;
unsigned int length,counter;
unsigned char qtable[64];
unsigned char word;
unsigned char *pointer;
unsigned int *ptr;
length=get_jpg_segment_length(jpg_ptr);
counter=2;
pointer=jpg_ptr+2;
*P_MPEG4_QTABLE_SRAM=0x00000001;//enable CPU access Q Sram
while(counter<length)
{
word=*pointer;
counter++;
pointer++;
word=word&0x0f;
if(word==0x00)
{
ptr=(unsigned int *)P_MPEG4_QTABLE1_START; //fill Y Q table
}
else
{
ptr=(unsigned int *)P_MPEG4_QTABLE2_START; //fill C Q table
}
//Fill C0 Enable CPU Write Q Table
for(i=0; i<64; i++)
{
counter++;
word = *pointer;
pointer++;
k=jpeg_natural_order[i];
qtable[k]=word;
}
//Fill Q Table SRAM C
for(i=0;i<64;i++)
{
//word=qtable[i];
*ptr=(unsigned int)qtable[i];
ptr++;
}
//Fill Q Table SRAM C
}//while(counter<length)
//Fill C0 disable CPU Write Q Table
*P_MPEG4_QTABLE_SRAM =0x00000000;//disable CPU access Q Sram
}
/////////////////////////////////////////////////////////////////////////
void set_jpg_mode(unsigned char *jpg_ptr){
unsigned char *pointer;
unsigned char word;
unsigned int width;
pointer=jpg_ptr+3;
word=*pointer;
pointer++;
*P_MPEG4_DECHEIGHT_HIGH=(unsigned int)word;
word=*pointer;
pointer++;
*P_MPEG4_DECHEIGHT_LOW=(unsigned int)word;
word=*pointer;
pointer++;
*P_MPEG4_DECWIDTH_HIGH=(unsigned int)word;
width=(unsigned int)word;
width=width<<8;
word=*pointer;
pointer++;
*P_MPEG4_DECWIDTH_LOW=(unsigned int)word;
width=width+(unsigned int)word;
*P_MPEG4_FRAMEBUFFER_HSIZE = width;
//////////////////////////////////////////////////////////////
word=*pointer;
pointer++;
pointer++;//bypass component1
if(word==0x01){ *P_MPEG4_YUV_SEL=0x00000000;// 0 : {yuv420,yuv422}, 1 : {yuv411,yuv444}
*P_MPEG4_MODE_CTRL1=0x00000019;
// bit 2:0 : optmode/000=jpg encode/001=jpg decode
// bit 3 : yuv422
// bit 4 : bwmode
// bit 5 : jpgbwmode
// bit 6 : Y fullrange
// bit 7 : UV fullrange
word=*pointer;
}//bwmode
else {
word=*pointer;
switch(word){
case 0x11://yuv444
*P_MPEG4_YUV_SEL=0x00000001;// 0 : {yuv420,yuv422}, 1 : {yuv411,yuv444}
*P_MPEG4_MODE_CTRL1=0x00000009;
#ifdef PRINT_JPG_HEADER_INFO
print1(" yuv444\n");
#endif
break;
case 0x21://yuv422
*P_MPEG4_YUV_SEL=0x00000000;// 0 : {yuv420,yuv422}, 1 : {yuv411,yuv444}
*P_MPEG4_MODE_CTRL1=0x00000009;
#ifdef PRINT_JPG_HEADER_INFO
print1(" yuv422\n");
#endif
break;
case 0x41://yuv411
*P_MPEG4_YUV_SEL=0x00000001;// 0 : {yuv420,yuv422}, 1 : {yuv411,yuv444}
*P_MPEG4_MODE_CTRL1=0x00000001;
#ifdef PRINT_JPG_HEADER_INFO
print1(" yuv411\n");
#endif
break;
case 0x22://yuv420
*P_MPEG4_YUV_SEL=0x00000000;// 0 : {yuv420,yuv422}, 1 : {yuv411,yuv444}
*P_MPEG4_MODE_CTRL1=0x00000001;
*P_MPEG4_YUV_MODE=0x30;
#ifdef PRINT_JPG_HEADER_INFO
print1(" yuv420\n");
#endif
break;
}
}//color mode
}
/////////////////////////////////////////////////////////////////////////
void set_mcuno_reg(unsigned char *jpg_ptr){
unsigned int mcuno;
unsigned char word;
unsigned char* pointer;
pointer=jpg_ptr+2;
word=*pointer;
mcuno=(unsigned int)word;
*P_MPEG4_RESETMCU_HIGH=mcuno;
mcuno=mcuno<<8;
pointer++;
word=*pointer;
//mcuno=(unsigned int)word;
mcuno=mcuno+(unsigned int)word;
*P_MPEG4_RESETMCU_LOW=(unsigned int)word;
#ifdef PRINT_JPG_HEADER_INFO
print2("set mcuno = ",1,mcuno);
#endif
}
/////////////////////////////////////////////////////////////////////////
unsigned char *bypass_jpg_segment(unsigned char *jpg_ptr)
{
unsigned char *pointer;
unsigned int length;
length=get_jpg_segment_length(jpg_ptr);
pointer=jpg_ptr+length;
return pointer;
}
/////////////////////////////////////////////////////////////////////////
unsigned int get_jpg_segment_length(unsigned char *jpg_ptr)
{
unsigned char word;
unsigned char *pointer;
unsigned int length;
word=*jpg_ptr;
pointer=jpg_ptr+1;
length=(unsigned int)word;
word=*pointer;
length=length<<8;
length=length+(unsigned int)word;
return length;
}
/////////////////////////////////////////////////////////////////////////
void Get_Huffman_cs_cw(unsigned char *cs, unsigned int *cw, unsigned char *pointer)
{
unsigned char word;
unsigned char *pcount=0;
unsigned int index;
unsigned int l_codeword = 0; /* local_codeword*/
unsigned int last_valid;
unsigned int j;
for(j=0; j<16; j++)
{
word =*pointer;
pcount[j] = word;
pointer++;
}
for(j = 15; j >= 0; j--)
{
if(pcount[j])
break;
}
last_valid=j;
for(index = 0; index<16; index++)
{
if(0 == index)
{
cs[0] = 0;
}
else if(1 == index)
{
cs[1] = pcount[0];
}
else
{
cs[index] = cs[index - 1] + pcount[index-1];
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -