JPEG解码

匿名 (未验证) 提交于 2019-12-03 00:22:01

一、JPEG编码原理

1.原理框图


2.各个步骤

【零偏置(Level offset)】

将无符号的数变为有符号的数,使得出现大数的概率减小

【DCT变换】

将时域上的转变为频域上的,低频的集中在左上角,高频的在右下角,这样大部分的数据基本在左上角

【量化】

低频数据多且人眼敏感,细量化,高频数据少不敏感,粗量化;同理,根据人眼对亮度敏感高于色度的原理,亮度细量化,色度粗量化;

【之字形扫描(Zig_zag scan)】:使非零的数集中在前面,后面的连0用EOB表示

【编码】

DC 系数编码: 由于直流系数 F(0,0)反映了该子图像中包含的直流成分,通常较大,又由 于两个相邻的子图像的直流系数通常具有较大的相关性,所以对 DC 系数采用 差值脉冲编码(DPCM),即对本像素块直流系数与前一像素块直流系数的差 值进行无损编码。

二、JPEG解码原理

1.主要流程


2.文件格式

2.1

Segment 的组织形式 JPEG 在文件中以 Segment 的形式组织,它具有以下特点:

(1)均以 0xFF 开始,后跟 1 byte 的 Marker 和 2 byte 的 Segment length(包含表示 Length 本身所占用的 2 byte,不含“0xFF” + “Marker” 所占用的 2 byte);

(3)Data 部分中,0xFF 后若为 0x00,则跳过此字节不予处理

2.2JPEG的Segment Marker




三、代码分析

3.1

主函数里面,通过benchmark_mode看是单个图像转换还是多次转换


3.2

tinyjpeg_parse_header解析头函数

int tinyjpeg_parse_header(struct jdec_private *priv, const unsigned char *buf, unsigned int size) {   int ret;    /* Identify the file */   if ((buf[0] != 0xFF) || (buf[1] != SOI))//segment marker文件开始一定是0XFF     snprintf(error_string, sizeof(error_string),"Not a JPG file ?\n");    priv->stream_begin = buf+2;   priv->stream_length = size-2;   priv->stream_end = priv->stream_begin + priv->stream_length;    ret = parse_JFIF(priv, priv->stream_begin);//解析JFIF    return ret; }

在parse_JFIF中依次解析了各个标志


3.3tinyjpeg_decode解码中


int tinyjpeg_decode(struct jdec_private *priv, int pixfmt) {   ...   xstride_by_mcu = ystride_by_mcu = 8;   if ((priv->component_infos[cY].Hfactor | priv->component_infos[cY].Vfactor) == 1) {      decode_MCU = decode_mcu_table[0];      convert_to_pixfmt = colorspace_array_conv[0]; #if TRACE      fprintf(p_trace,"Use decode 1x1 sampling\n"); 	 fflush(p_trace); #endif   } else if (priv->component_infos[cY].Hfactor == 1) {      decode_MCU = decode_mcu_table[1];      convert_to_pixfmt = colorspace_array_conv[1];      ystride_by_mcu = 16; #if TRACE      fprintf(p_trace,"Use decode 1x2 sampling (not supported)\n"); 	 fflush(p_trace); #endif   } else if (priv->component_infos[cY].Vfactor == 2) {      decode_MCU = decode_mcu_table[3];      convert_to_pixfmt = colorspace_array_conv[3];      xstride_by_mcu = 16;      ystride_by_mcu = 16; #if TRACE  	 fprintf(p_trace,"Use decode 2x2 sampling\n"); 	 fflush(p_trace); #endif   } else {      decode_MCU = decode_mcu_table[2];      convert_to_pixfmt = colorspace_array_conv[2];      xstride_by_mcu = 16; #if TRACE      fprintf(p_trace,"Use decode 2x1 sampling\n"); 	 fflush(p_trace); #endif   }   


四、实验结果

4.1输出YUV文件



输出三个改为输出一个


4.2TRACE


Huffman表



3.输出DC图像

4.输出DCT[25]

DCT系数往后基本都为0,只有前几个非0

文章来源: JPEG解码
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!