📄 jpeg.c
字号:
unsigned int i, j;
unsigned int data[2];
unsigned int *pointer;
if(chrominance == 0)
pointer = (unsigned int *)P_MPEG4_LUMOFFSET_SA;
else
pointer = (unsigned int *)P_MPEG4_CHROMOFFSET_SA;
for(i=0; i<8; i++)
{
j = i * 2;
data[1] = (unsigned int)cs[j + 1];
data[0] = (unsigned int)cs[j];
data[1] = data[1] & 0x0000000f;
data[1] = data[1] << 4;
data[0] = data[0] & 0x0000000f;
*pointer++ = data[0] + data[1];
}
}
//=============================================================
// 语法格式: void set_jpg_huffman_dcv_reg(int chrominance, unsigned char *cv);
// 实现功能: 填充 DC Huffman值
// 参数: chrominance,选择亮度还是色度;*cv,DC huffman值
// 返回值: 无
//=============================================================
static void set_jpg_huffman_dcv_reg(int chrominance, unsigned char *cv)
{
unsigned int *pointer;
unsigned int i, j;
unsigned int data[2];
if(chrominance == 0)
pointer = (unsigned int *)P_MPEG4_LUMHUFFMANTABLE_START;
else
pointer = (unsigned int *)P_MPEG4_CHROMHUFFMANTABLE_START;
for(i=0; i<8; i++)
{
j = i * 2;
data[1] = (unsigned int)(cv[j+1] & 0x000f);
data[0] = (unsigned int)(cv[j] & 0x000f);
data[1] = data[1] << 4;
*pointer++ = data[0] + data[1];
}
}
//=============================================================
// 语法格式: int fill_huffman_reg(unsigned char *jpg_ptr);
// 实现功能: 向SPCE3200填充Huffman表,只能直接填充读出的huffman,需要解开填充
// 参数: jpg_ptr,指向jpeg数据的指针
// 返回值: 1: 成功; 0: 失败
//=============================================================
static int fill_huffman_reg(unsigned char *jpg_ptr)
{
unsigned int length, counter, i, index;
unsigned char word;
unsigned char *pointer;
unsigned char *temp_pointer;
unsigned int cw[16]; // 存储huffman表
unsigned char cs[16]; // huffman表的相对开始位置
unsigned char cv[256]; // DC或AC数据
length = get_jpg_segment_length(jpg_ptr);
if(length == 0x1A2)
{
counter = 3;
pointer = jpg_ptr + 3;
for(index=0; index<4; index++)
{
for(i=0; i<16; i++)
{
cw[i] = 0;
cs[i] = 0;
}
for(i=0; i<256; i++)
{
cv[i] = 0;
}
Get_Huffman_cs_cw(cs, cw, pointer);
word = *(pointer - 1); // Get Huffman table type
temp_pointer = pointer + 16; // Shift to the starting point of DiffDC_length or <R, V_length>
set_Huff_sram_mode(8); // Set TSramMode = CPU R/W TSRAM Regs and JPEG Decoding
set_jpg_huffman_cw_reg(word, cw);
if(word == 0x00)
{
length = 0x1c;
set_jpg_huffman_dcs_reg(0, cs);
for(i=0; i<16; i++)
{
cv[i] = *temp_pointer++;
}
set_jpg_huffman_dcv_reg(0, cv);
} // YDC
else if(word == 0x01)
{
length = 0x1c;
set_jpg_huffman_dcs_reg(1, cs);
for(i=0; i<16; i++)
{
cv[i] = *temp_pointer++;
}
set_jpg_huffman_dcv_reg(1, cv);
} // CDC
else if(word == 0x10)
{
length = 0xb2;
set_jpg_huffman_acs_reg(0, cs);
for(i=0; i<(0x40 * 3); i++)
{
cv[i] = *temp_pointer++;
}
set_jpg_huffman_acv_sram(0, cv);
} // YAC
else if(word == 0x11)
{
length = 0xb2;
set_jpg_huffman_acs_reg(1, cs);
for(i=0; i<(0x40 * 3); i++)
{
cv[i] = *temp_pointer++;
}
set_jpg_huffman_acv_sram(1, cv);
} // CAC
pointer = pointer + (length + 1);
counter = counter + (length + 1);
}
}
else if(length < 0xa0)
{
counter = 3;
pointer = jpg_ptr + 3;
for(i=0; i<16; i++)
{
cw[i] = 0;
cs[i] = 0;
}
for(i=0; i<256; i++)
{
cv[i] = 0;
}
Get_Huffman_cs_cw(cs, cw, pointer);
word = *(pointer - 1); // Get Huffman table type
temp_pointer = pointer + 16; // Shift to the starting point of DiffDC_length or <R,V_length>
set_Huff_sram_mode(8); // Set TSramMode = CPU R/W TSRAM Regs and JPEG Decoding
set_jpg_huffman_cw_reg(word, cw);
if(word == 0x00)
{
set_jpg_huffman_dcs_reg(0, cs);
for(i=0; i<16; i++)
{
word = *temp_pointer;
cv[i] = word;
temp_pointer++;
}
set_jpg_huffman_dcv_reg(0, cv);
} // YDC
else if(word == 0x01)
{
set_jpg_huffman_dcs_reg(1, cs);
for(i=0; i<16; i++)
{
word = *temp_pointer;
cv[i] = word;
temp_pointer++;
}
set_jpg_huffman_dcv_reg(1, cv);
} // CDC
else if(word == 0x10)
{
set_jpg_huffman_acs_reg(0, cs);
for(i=0; i<(0x40*3); i++)
{
word = *temp_pointer;
cv[i] = word;
temp_pointer++;
}
set_jpg_huffman_acv_sram(0, cv);
} // YAC
else if(word == 0x11)
{
set_jpg_huffman_acs_reg(1, cs);
for(i=0; i<(0x40*3); i++)
{
word = *temp_pointer;
cv[i] = word;
temp_pointer++;
}
set_jpg_huffman_acv_sram(1, cv);
} // CAC
pointer = pointer + (length - 3);
counter = counter + (length - 3);
}
else
return 0;
return 1;
}
//=============================================================
// 语法格式: void set_mcuno_reg(unsigned char *jpg_ptr);
// 实现功能: 有反转的处理
// 参数: *jpg_ptr,指向图片地址
// 返回值: 无
//=============================================================
static 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 = mcuno + (unsigned int)word;
*P_MPEG4_RESETMCU_LOW = (unsigned int)word;
}
//=============================================================
// 语法格式: unsigned int Extract_JPG_Header(unsigned int JPG_SA);
// 实现功能: 解jpeg图片的文件头数据
// 参数: JPG_SA,指向jpeg数据的指针
// 返回值: jpeg去除文件头的数据(VLC存储),失败则返回0
//=============================================================
static unsigned int Extract_JPG_Header(unsigned int JPG_SA)
{
unsigned char *jpg_ptr;
unsigned int vlc_sa = 0;
unsigned char word;
jpg_ptr = (unsigned char *)JPG_SA;
jpg_ptr = find_marker(jpg_ptr); // find marker
word = *jpg_ptr;
if(word == 0xd8) // jpg start marker
{
*P_MPEG4_SRAM_EN = 0x00000001; // turn on sram
while(jpg_ptr)
{
jpg_ptr = find_marker(jpg_ptr);
word = *jpg_ptr++;
if((word > 0xc0) && (word <= 0xcf) && (word != 0xc4))
return 0; // I can't decode this JPG file
switch(word)
{
case 0xd9 : // jpg file end
jpg_ptr = 0;
break;
case 0xdb : // Quantization table
fill_quantize_sram(jpg_ptr);
jpg_ptr = bypass_jpg_segment(jpg_ptr);
vlc_sa = (unsigned int)jpg_ptr;
break;
case 0xc4 : // Huffman table
if(fill_huffman_reg(jpg_ptr) == 0)
return 0;
jpg_ptr = bypass_jpg_segment(jpg_ptr);
vlc_sa = (unsigned int)jpg_ptr;
break;
case 0xda : // Start of scan
jpg_ptr = bypass_jpg_segment(jpg_ptr);
vlc_sa = (unsigned int)jpg_ptr;
break;
case 0xc0 : // Start of frame
if(set_jpg_mode(jpg_ptr) == 0)
return 0;
jpg_ptr = bypass_jpg_segment(jpg_ptr);
vlc_sa = (unsigned int)jpg_ptr;
break;
case 0xdd : // Restart_Interval mcu_no
set_mcuno_reg(jpg_ptr);
jpg_ptr = (jpg_ptr + 4);
vlc_sa = (unsigned int)jpg_ptr;
break;
case 0x00 :
jpg_ptr = 0; // i suppose there is no segment behind the vlc
break;
default :
jpg_ptr = bypass_jpg_segment(jpg_ptr);
vlc_sa = (unsigned int)jpg_ptr;
}
}
}// if(word==0xd8) jpg start marker
return vlc_sa;
}
//=============================================================
// 语法格式: int JPEG_DepressPicture(void *JPG_SA, void *DestBuf)
// 实现功能: 解jpeg图片
// 参数: *JPG_SA,要解码图片的首地址
// *DestBuf,解码后图片的保存位置
// 返回值: 1: 成功; 0: 失败
//=============================================================
int JPEG_DepressPicture(void *JPG_SA, void *DestBuf)
{
unsigned int vlc_sa; // 存储去除文件头的地址
vlc_sa = (unsigned int)JPG_SA;
*P_MPEG4_QTABLE_CTRL = C_MPEG4_QVALUE_ORIGIN // 设置量化表
| C_MPEG4_QSCALE_QTABLE;
*P_MPEG4_BUFFER_CTRL = C_MPEG4_NORMAL_MODE;
*P_MPEG4_MODE_CTRL3 = C_MPEG4_SOPTRIG_CPU;
*P_MPEG4_JFIF_COMPATIBLE = C_MPEG4_JFIF_MODE; // 兼容JFIF
*P_MPEG4_TRUNCATE_CTRL = C_MPEG4_QUANTIFY_TRUNCATE; // 裁减
if((vlc_sa = Extract_JPG_Header((unsigned int)JPG_SA)) == 0)
return 0; // 获取除去文件头的实际地址
// Decode VLC Bit Stream Starting Offset, Low/Middle/High is Byte Boundard.
*P_MPEG4_DECVLCOFFSET_SALOW = vlc_sa;
vlc_sa = vlc_sa >> 8;
*P_MPEG4_DECVLCOFFSET_SAMID = vlc_sa;
vlc_sa = vlc_sa >> 8;
*P_MPEG4_DECVLCOFFSET_SAHIGH = vlc_sa;
// *P_MPEG4_MODE_CTRL2 = 3;
*P_MPEG4_COMPRESS_CTRL = C_MPEG4_DECODE_START; // Start decoding
while((*P_MPEG4_COMPRESS_CTRL & C_MPEG4_DECODE_STATUS) != 0); // wait for hardware decoder
BLNDMA_YUV2RGB((unsigned int *)MPEG4_W_BUFFER0_SA, (unsigned int *)DestBuf);
return 1;
}
//=============================================================
// 语法格式: int Jpeg_Height_Width_Get(unsigned char *jpg_ptr, unsigned int *Height, unsigned int *Width);
// 实现功能: 得到Jpeg图片的高度、宽度
// 参数: *JPG_SA,要解码图片的首地址;*Height,高度;*Width,宽度
// 返回值: 1: 成功; 0: 失败
//=============================================================
int JPEG_GetPictureSize(void *pImage, unsigned short *Width, unsigned short *Height)
{
int Ret = 0;
unsigned char word = 0;
unsigned short height;
unsigned short width;
unsigned char *jpg_ptr;
jpg_ptr = find_marker(pImage); // find marker
word = *jpg_ptr;
if(word == 0xd8) // jpg start marker
{
while(jpg_ptr)
{
jpg_ptr = find_marker(jpg_ptr);
word = *jpg_ptr++;
switch(word)
{
case 0xc0 :
jpg_ptr = jpg_ptr + 3;
word = *jpg_ptr++;
height = (unsigned short)word << 8;
word = *jpg_ptr++;
height += (unsigned short)word;
word = *jpg_ptr++;
width = (unsigned short)word << 8;
word = *jpg_ptr++;
width += (unsigned short)word;
*Height = height;
*Width = width;
jpg_ptr = 0;
Ret = 1;
break;
default:
jpg_ptr = bypass_jpg_segment(jpg_ptr);
break;
}
}
}
return Ret;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -