实验五 JPEG解码
2017-07-06 20:48
120 查看
实验原理
JPEG简介
JPEG是Joint PhotographicExperts Group(联合图像专家小组)的缩写,是第一个国际图像压缩标准。JPEG图像压缩算法能够在提供良好的压缩性能的同时,具有比较好的重建质量,被广泛应用于图像、视频处理领域。
JPEG 在文件中以 Segment 的形式组织,它具有以下特点:
1.均以 0xFF 开始,后跟 1 byte 的 Marker 和 2 byte 的 Segment length(包含表示 Length 本身所占用的 2 byte,不含“0xFF” + “Marker” 所占用的 2 byte);
2.采用 Motorola 序(相对于 Intel 序),即保存时高位在前,低位在后;
3. Data 部分中,0xFF 后若为 0x00,则跳过此字节不予处理;
JPEG编码原理图
零偏置:零偏置,对于灰度级是2n的像素,通过减去2n-1,将无符号的整数值变成有符号数,对于n=8,即将0~255的值域,通过减去128,转换为值域在-128~127之间的值,使像素的绝对值出现3位10进制的概率大大减少。零偏置:零偏置,对于灰度级是2n的像素,通过减去2n-1,将无符号的整数值变成有符号数,对于n=8,即将0~255的值域,通过减去128,转换为值域在-128~127之间的值,使像素的绝对值出现3位10进制的概率大大减少。零偏置:零偏置,对于灰度级是2n的像素,通过减去2n-1,将无符号的整数值变成有符号数,对于n=8,即将0~255的值域,通过减去128,转换为值域在-128~127之间的值,使像素的绝对值出现3位10进制的概率大大减少。
![](https://img-blog.csdn.net/20170706210738302?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcXFfMzc2NDE2NTA=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
零偏置:
零偏置,对于灰度级是2n的像素,通过减去2n-1,将无符号的整数值变成有符号数,对于n=8,即将0~255的值域,通过减去128,转换为值域在-128~127之间的值,使像素的绝对值出现3位10进制的概率大大减少。
DCT:
经过DCT变换后,图像中的低频分量会集中在左上角,由于图像低频能量高,故而左上角数值大,右下角有较多的0值。
量化:
人眼对低频敏感,对高频不敏感。所以低频细量化,高频粗量化;人眼对亮度信号敏感,对色度信号不敏感。所以亮度和色度分量分别采用不同的量化表。
DC系数差分编码:
8×8图像块经过DCT变换之后得到的DC直流系数有两个特点:系数的数值比较大和相邻8×8图像块的DC系数值变化不大:冗余;根据这个特点, JPEG算法使用了差分脉冲调制编码(DPCM)技术,对相邻图像块之间量化DC系数的差值DIFF进行huffma编码:
之字形扫描:
游程编码的扫描过程,由于DCT变换后,越往右下角的分量越小甚至为0,于是采用之字形扫描。将二维降到一维后会在高频部分出现连0,由此可以提高编码效率。
熵编码:
利用相邻块之间DC系数的空间相关性,对DC系数进行DPCM编码,即当前块的DC系数减去前一块的DC系数后编码。对AC系数进行游程编码(Run-Length Ecoding)。
JPEG图像格式介绍:
![](https://img-blog.csdn.net/20170706223548382?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcXFfMzc2NDE2NTA=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
解码流程:
(1)读取文件
(2)解析Segment Marker
*解析SOI
*解析APP0
检查标识”JFIF”及版本
得到一些参数
*解析DQT
得到量化表长度(可能包含多张量化表)
得到量化表的精度
得到及检查量化表的序号(只能是0~3)
得到量化表内容(64个数据)
*解析SOF0
得到每个sample的比特数、长宽、颜色分量数
得到每个颜色分量的ID、水平采样因子、垂直采样因子、使用的量化表序号(与DQT中序号对应)
*解析DHT
得到 Huffman
表的类型(AC、DC)、序号
依据数据重建 Huffman
表
*解析SOS
得到解析每个颜色分量的DC、AC值所使用的Huffman表序号(与DHT中序号对应)(3)依据每个分量的水平、垂直采样因子计算MCU的大小,并得到每个
MCU 中8*8宏块的个数。
(4)对每个MCU解码(依照各分量水平、垂直采样因子对MCU中每个分量宏块解码)。
*对每个宏块进行Huffman解码,得到DCT系数
*对每个宏块的DCT系数进行IDCT,得到Y、Cb、Cr
*遇到 Segment Marker RST
时,清空之前的 DC DCT
系数
(5)解析到 EOI,解码结束
(6)将Y、Cb、Cr转化为需要的色彩空间并保存。
实验步骤:
1.逐步调试JPEG解码器程序。将输入的JPG文件进行解码,将输出文件保存为可供
YUVViewer观看的YUV文件。
2.程序调试过程中,应做到:理解程序设计的整体框架;理解三个结构体的设计目的;
struct huffman_table struct component struct jdec_private
主要代码分析:
理解struct huffman_table、struct component、struct jdec_private三个结构体的设计目的:
struct huffman_table
{
/* Fast look up table, using HUFFMAN_HASH_NBITS bits we can have directly the symbol,
* if the symbol is <0, then we need to look into the tree table */
short int lookup[HUFFMAN_HASH_SIZE];
/* code size: give the number of bits of a symbol is encoded */
unsigned char code_size[HUFFMAN_HASH_SIZE];
/* some place to store value that is not encoded in the lookup table
* FIXME: Calculate if 256 value is enough to store all values
*/
uint16_t slowtable[16-HUFFMAN_HASH_NBITS][256];
};
struct component
{
unsigned int Hfactor;//水平采样因子
unsigned int Vfactor;//垂直采样因子
float *Q_table; /* Pointer to the quantisation table to use */
struct huffman_table *AC_table;
struct huffman_table *DC_table;
short int previous_DC; /* Previous DC coefficient */
short int DCT[64]; /* DCT coef */
#if SANITY_CHECK
unsigned int cid;
#endif
};
typedef void (*decode_MCU_fct) (struct jdec_private *priv);
typedef void (*convert_colorspace_fct) (struct jdec_private *priv);
struct jdec_private
{
/* Public variables */
uint8_t *components[COMPONENTS];
unsigned int width, height; /* Size of the image */
unsigned int flags;
/* Private variables */
const unsigned char *stream_begin, *stream_end;
unsigned int stream_length;
const unsigned char *stream; /* Pointer to the current stream */
unsigned int reservoir, nbits_in_reservoir;
struct component component_infos[COMPONENTS];
float Q_tables[COMPONENTS][64]; /* quantization tables */
struct huffman_table HTDC[HUFFMAN_TABLES]; /* DC huffman tables */
struct huffman_table HTAC[HUFFMAN_TABLES]; /* AC huffman tables */
int default_huffman_table_initialized;
int restart_interval;
int restarts_to_go; /* MCUs left in this restart interval */
int last_rst_marker_seen; /* Rst marker is incremented each time */
/* Temp space used after the IDCT to store each components */
uint8_t Y[64*4], Cr[64], Cb[64];
/*添加两个指针用于存放要输出的DC、AC图像,若要修改具体要输出的
AC分量,则要修改函数“output_AC_Image”*/
short int *DC_Image;
short int *AC_Image;
jmp_buf jump_state;
/* Internal Pointer use for colorspace conversion, do not modify it !!! */
uint8_t *plane[COMPONENTS];
};
将输出文件保存为可供YUVViewer观看的YUV文件
tinyjpeg.h
FILE *c_file;//输出表格的文件指针
FILE *acfile ;// AC图像
FILE *dcfile ;// DC图像
static char out_str[20];// c_file中输出的字符串
static unsigned char *outDCbuf = NULL;// 为DC图像开缓冲区
static unsigned char *outACbuf = NULL; 为AC图像开缓冲区
loadjpeg.c
提取量化表
static const unsigned char zigzag[64] =
{
0, 1, 5, 6, 14, 15, 27, 28,
2, 4, 7, 13, 16, 26, 29, 42,
3, 8, 12, 17, 25, 30, 41, 43,
9, 11, 18, 24, 31, 40, 44, 53,
10, 19, 23, 32, 39, 45, 52, 54,
20, 22, 33, 38, 46, 51, 55, 60,
21, 34, 37, 47, 50, 56, 59, 61,
35, 36, 48, 49, 57, 58, 62, 63
};
/*build_quantization_table*/
//get the Q table
#if C_TABLE
snprintf(out_str, sizeof(out_str),"%d", ref_table[*(zz-1)]); //按照zigzag索引
fprintf(c_file,"%s\t",out_str);
if(j == 7)
fprintf(c_file,"\n\n");
fflush(c_file);
#endif
以8×8的二维矩阵形式输出量化表,以TAB键为间隔
输出哈夫曼码表:
输出DC图像与某一个AC值图像
output_DC_AC_Image用于将AC系数、某一AC系数存放在struct jdec_private的DC_Image和AC_Image空间中,并且根据色度取样格式、MCU的不同有不同的存放方式。
向文件写出DC图像、AC图像
实验结果分析
![](https://img-blog.csdn.net/20170706230859209?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcXFfMzc2NDE2NTA=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
![](https://img-blog.csdn.net/20170706230958031?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcXFfMzc2NDE2NTA=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
输出图像直流dc.yuv 交流ac.yuv
![](https://img-blog.csdn.net/20170706231125227?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcXFfMzc2NDE2NTA=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
![](https://img-blog.csdn.net/20170706231221113?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcXFfMzc2NDE2NTA=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
蚊子噪声现象
低压缩比
![](https://img-blog.csdn.net/20170706231414149?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcXFfMzc2NDE2NTA=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
高压缩比
JPEG简介
JPEG是Joint PhotographicExperts Group(联合图像专家小组)的缩写,是第一个国际图像压缩标准。JPEG图像压缩算法能够在提供良好的压缩性能的同时,具有比较好的重建质量,被广泛应用于图像、视频处理领域。
JPEG 在文件中以 Segment 的形式组织,它具有以下特点:
1.均以 0xFF 开始,后跟 1 byte 的 Marker 和 2 byte 的 Segment length(包含表示 Length 本身所占用的 2 byte,不含“0xFF” + “Marker” 所占用的 2 byte);
2.采用 Motorola 序(相对于 Intel 序),即保存时高位在前,低位在后;
3. Data 部分中,0xFF 后若为 0x00,则跳过此字节不予处理;
JPEG编码原理图
零偏置:零偏置,对于灰度级是2n的像素,通过减去2n-1,将无符号的整数值变成有符号数,对于n=8,即将0~255的值域,通过减去128,转换为值域在-128~127之间的值,使像素的绝对值出现3位10进制的概率大大减少。零偏置:零偏置,对于灰度级是2n的像素,通过减去2n-1,将无符号的整数值变成有符号数,对于n=8,即将0~255的值域,通过减去128,转换为值域在-128~127之间的值,使像素的绝对值出现3位10进制的概率大大减少。零偏置:零偏置,对于灰度级是2n的像素,通过减去2n-1,将无符号的整数值变成有符号数,对于n=8,即将0~255的值域,通过减去128,转换为值域在-128~127之间的值,使像素的绝对值出现3位10进制的概率大大减少。
零偏置:
零偏置,对于灰度级是2n的像素,通过减去2n-1,将无符号的整数值变成有符号数,对于n=8,即将0~255的值域,通过减去128,转换为值域在-128~127之间的值,使像素的绝对值出现3位10进制的概率大大减少。
DCT:
经过DCT变换后,图像中的低频分量会集中在左上角,由于图像低频能量高,故而左上角数值大,右下角有较多的0值。
量化:
人眼对低频敏感,对高频不敏感。所以低频细量化,高频粗量化;人眼对亮度信号敏感,对色度信号不敏感。所以亮度和色度分量分别采用不同的量化表。
DC系数差分编码:
8×8图像块经过DCT变换之后得到的DC直流系数有两个特点:系数的数值比较大和相邻8×8图像块的DC系数值变化不大:冗余;根据这个特点, JPEG算法使用了差分脉冲调制编码(DPCM)技术,对相邻图像块之间量化DC系数的差值DIFF进行huffma编码:
之字形扫描:
游程编码的扫描过程,由于DCT变换后,越往右下角的分量越小甚至为0,于是采用之字形扫描。将二维降到一维后会在高频部分出现连0,由此可以提高编码效率。
熵编码:
利用相邻块之间DC系数的空间相关性,对DC系数进行DPCM编码,即当前块的DC系数减去前一块的DC系数后编码。对AC系数进行游程编码(Run-Length Ecoding)。
JPEG图像格式介绍:
解码流程:
(1)读取文件
(2)解析Segment Marker
*解析SOI
*解析APP0
检查标识”JFIF”及版本
得到一些参数
*解析DQT
得到量化表长度(可能包含多张量化表)
得到量化表的精度
得到及检查量化表的序号(只能是0~3)
得到量化表内容(64个数据)
*解析SOF0
得到每个sample的比特数、长宽、颜色分量数
得到每个颜色分量的ID、水平采样因子、垂直采样因子、使用的量化表序号(与DQT中序号对应)
*解析DHT
得到 Huffman
表的类型(AC、DC)、序号
依据数据重建 Huffman
表
*解析SOS
得到解析每个颜色分量的DC、AC值所使用的Huffman表序号(与DHT中序号对应)(3)依据每个分量的水平、垂直采样因子计算MCU的大小,并得到每个
MCU 中8*8宏块的个数。
(4)对每个MCU解码(依照各分量水平、垂直采样因子对MCU中每个分量宏块解码)。
*对每个宏块进行Huffman解码,得到DCT系数
*对每个宏块的DCT系数进行IDCT,得到Y、Cb、Cr
*遇到 Segment Marker RST
时,清空之前的 DC DCT
系数
(5)解析到 EOI,解码结束
(6)将Y、Cb、Cr转化为需要的色彩空间并保存。
实验步骤:
1.逐步调试JPEG解码器程序。将输入的JPG文件进行解码,将输出文件保存为可供
YUVViewer观看的YUV文件。
2.程序调试过程中,应做到:理解程序设计的整体框架;理解三个结构体的设计目的;
struct huffman_table struct component struct jdec_private
主要代码分析:
理解struct huffman_table、struct component、struct jdec_private三个结构体的设计目的:
struct huffman_table
{
/* Fast look up table, using HUFFMAN_HASH_NBITS bits we can have directly the symbol,
* if the symbol is <0, then we need to look into the tree table */
short int lookup[HUFFMAN_HASH_SIZE];
/* code size: give the number of bits of a symbol is encoded */
unsigned char code_size[HUFFMAN_HASH_SIZE];
/* some place to store value that is not encoded in the lookup table
* FIXME: Calculate if 256 value is enough to store all values
*/
uint16_t slowtable[16-HUFFMAN_HASH_NBITS][256];
};
struct component
{
unsigned int Hfactor;//水平采样因子
unsigned int Vfactor;//垂直采样因子
float *Q_table; /* Pointer to the quantisation table to use */
struct huffman_table *AC_table;
struct huffman_table *DC_table;
short int previous_DC; /* Previous DC coefficient */
short int DCT[64]; /* DCT coef */
#if SANITY_CHECK
unsigned int cid;
#endif
};
typedef void (*decode_MCU_fct) (struct jdec_private *priv);
typedef void (*convert_colorspace_fct) (struct jdec_private *priv);
struct jdec_private
{
/* Public variables */
uint8_t *components[COMPONENTS];
unsigned int width, height; /* Size of the image */
unsigned int flags;
/* Private variables */
const unsigned char *stream_begin, *stream_end;
unsigned int stream_length;
const unsigned char *stream; /* Pointer to the current stream */
unsigned int reservoir, nbits_in_reservoir;
struct component component_infos[COMPONENTS];
float Q_tables[COMPONENTS][64]; /* quantization tables */
struct huffman_table HTDC[HUFFMAN_TABLES]; /* DC huffman tables */
struct huffman_table HTAC[HUFFMAN_TABLES]; /* AC huffman tables */
int default_huffman_table_initialized;
int restart_interval;
int restarts_to_go; /* MCUs left in this restart interval */
int last_rst_marker_seen; /* Rst marker is incremented each time */
/* Temp space used after the IDCT to store each components */
uint8_t Y[64*4], Cr[64], Cb[64];
/*添加两个指针用于存放要输出的DC、AC图像,若要修改具体要输出的
AC分量,则要修改函数“output_AC_Image”*/
short int *DC_Image;
short int *AC_Image;
jmp_buf jump_state;
/* Internal Pointer use for colorspace conversion, do not modify it !!! */
uint8_t *plane[COMPONENTS];
};
将输出文件保存为可供YUVViewer观看的YUV文件
static void write_add_yuv(const char *filename, int width, int height, unsigned char **components) { FILE *F; char temp[1024]; snprintf(temp, 1024, "%s.YUV", filename); F = fopen(temp, "wb"); fwrite(components[0], width, height, F); fwrite(components[1], width*height / 4, 1, F); fwrite(components[2], width*height / 4, 1, F); fclose(F); }
tinyjpeg.h
FILE *c_file;//输出表格的文件指针
FILE *acfile ;// AC图像
FILE *dcfile ;// DC图像
static char out_str[20];// c_file中输出的字符串
static unsigned char *outDCbuf = NULL;// 为DC图像开缓冲区
static unsigned char *outACbuf = NULL; 为AC图像开缓冲区
enum tinyjpeg_fmt { TINYJPEG_FMT_GREY = 1, TINYJPEG_FMT_BGR24, TINYJPEG_FMT_RGB24, TINYJPEG_FMT_YUV420P, TINYJPEG_FMT_YUV, };
loadjpeg.c
int convert_one_image(const char *infilename, const char *outfilename, int output_format) { ...... switch (output_format) { ...... case TINYJPEG_FMT_YUV: write_add_yuv(outfilename, width, height, components); } ...... }
提取量化表
static const unsigned char zigzag[64] =
{
0, 1, 5, 6, 14, 15, 27, 28,
2, 4, 7, 13, 16, 26, 29, 42,
3, 8, 12, 17, 25, 30, 41, 43,
9, 11, 18, 24, 31, 40, 44, 53,
10, 19, 23, 32, 39, 45, 52, 54,
20, 22, 33, 38, 46, 51, 55, 60,
21, 34, 37, 47, 50, 56, 59, 61,
35, 36, 48, 49, 57, 58, 62, 63
};
/*build_quantization_table*/
//get the Q table
#if C_TABLE
snprintf(out_str, sizeof(out_str),"%d", ref_table[*(zz-1)]); //按照zigzag索引
fprintf(c_file,"%s\t",out_str);
if(j == 7)
fprintf(c_file,"\n\n");
fflush(c_file);
#endif
以8×8的二维矩阵形式输出量化表,以TAB键为间隔
static void build_quantization_table(float *qtable, const unsigned char *ref_table) { ...... for (i=0; i<8; i++) { for (j=0; j<8; j++) { #if TABLES fprintf(f_tables, "%d\t", ref_table[*zz]); fflush(f_tables); if (j == 7) { fprintf(f_tables,"\n"); fflush(f_tables); } #endif ...... } } }
输出哈夫曼码表:
static void build_huffman_table(const unsigned char *bits, const unsigned char *vals, struct huffman_table *table) { ...... for (i=0; huffsize[i]; i++) { ...... #if TABLES fprintf(f_tables, "val=%2.2x code=%8.8x codesize=%2.2d\n", val, code, code_size); fflush(f_tables); #endif ...... } }
输出DC图像与某一个AC值图像
output_DC_AC_Image用于将AC系数、某一AC系数存放在struct jdec_private的DC_Image和AC_Image空间中,并且根据色度取样格式、MCU的不同有不同的存放方式。
static void output_DC_AC_Image(struct jdec_private *priv,int temp) { static long int i = 0; int row, column; int width; width = priv->width/8; switch ( temp) { case 0://2*2 row = i / (2 * width); column = (i % (2 * width)) / 4; if (i % 4 == 0) { priv->DC_Image[row * 2 * width + column * 2] = priv->component_infos[0].DCT[0]; priv->AC_Image[row * 2 * width + column * 2] = priv->component_infos[0].DCT[1]; } else if (i%4==1) { priv->DC_Image[row * 2 * width + column * 2 + 1] = priv->component_infos[0].DCT[0]; priv->AC_Image[row * 2 * width + column * 2 + 1] = priv->component_infos[0].DCT[1]; } else if (i % 4 == 2) { priv->DC_Image[(row * 2 +1)* width + column * 2] = priv->component_infos[0].DCT[0]; priv->AC_Image[(row * 2 +1)* width + column * 2] = priv->component_infos[0].DCT[1]; } else { priv->DC_Image[(row * 2 + 1) * width + column * 2 + 1] = priv->component_infos[0].DCT[0]; priv->AC_Image[(row * 2 + 1)* width + column * 2 + 1] = priv->component_infos[0].DCT[1]; } break; case 1://1*2 row = i / (2 * width); column = (i % (2 * width)) / 2; if (i % 2 == 0) { priv->DC_Image[row * 2 * width + column ] = priv->component_infos[0].DCT[0]; priv->AC_Image[row * 2 * width + column] = priv->component_infos[0].DCT[1]; } else { priv->DC_Image[(row * 2 + 1)*width + column ] = priv->component_infos[0].DCT[0]; priv->AC_Image[(row * 2 + 1)*width + column ] = priv->component_infos[0].DCT[1]; } break; case 2://2*1 case 3://1*1 priv->DC_Image[i] = priv->component_infos[0].DCT[0]; priv->AC_Image[i] = priv->component_infos[0].DCT[1]; break; default: break; } i++; }
向文件写出DC图像、AC图像
static void write_DC_AC_Image(struct jdec_private *priv) { int i; short int DC_min, DC_max, AC_min, AC_max; unsigned char *temp; DC_min = priv->DC_Image[0]; DC_max = priv->DC_Image[0]; AC_min = priv->AC_Image[0]; AC_max = priv->AC_Image[0]; temp = (unsigned char*)malloc(priv->height*priv->width / 64); for (i = 0; i < (priv->height*priv->width/64); i++) { if (priv->DC_Image[i] > DC_max) DC_max = priv->DC_Image[i]; if (priv->DC_Image[i] < DC_min) DC_min = priv->DC_Image[i]; if (priv->AC_Image[i] > AC_max) AC_max = priv->AC_Image[i]; if (priv->AC_Image[i] < AC_min) AC_min = priv->AC_Image[i]; } for (i = 0; i < (priv->height*priv->width/64); i++) { temp[i] = (unsigned char)255 * (priv->DC_Image[i] - DC_min) / (DC_max - DC_min); } fwrite(temp, 1, priv->width*priv->height / 64, DC_FILE); for (i = 0; i < (priv->height*priv->width / 64); i++) { temp[i] = (unsigned char)255 * (priv->AC_Image[i] - AC_min) / (AC_max - AC_min); } fwrite(temp, 1, priv->width*priv->height / 64, AC_FILE); if (temp) free(temp); }
实验结果分析
输出图像直流dc.yuv 交流ac.yuv
蚊子噪声现象
低压缩比
高压缩比
相关文章推荐
- 《数据压缩》实验报告五·JPEG编解码
- 数据压缩实验五:JPEG文件解码实验分析
- 数据压缩原理实验5_JPEG编解码原理及代码分析
- 实验五——JPEG编解码
- 实验报告5_JPEG编解码原理及程序调试
- 数据压缩实验无--jpeg解码
- 【实验五】JPEG解码
- JPEG文件编/解码详解
- JPEG文件编/解码详解
- 基于libjpeg实现的jpeg解码demo
- cortex_m3_stm32嵌入式学习笔记(二十三):红外遥控实验(输入捕捉+解码)
- FW:使用libjpeg解码jpeg图片
- 网站图片优化-解码JPEG
- 视音频编解码学习工程:JPEG分析器
- JPEG图象解码源代码(Delphi源码)
- JPEG解码
- 数据压缩原理与应用 实验五 JPEG 原理分析及 JPEG 解码器的调试
- JPEG文件编/解码详解
- Jpeg图像 压缩/解码 之采样因子
- Jpeg解码小结(一)