📄 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 + -