数据压缩原理 实验五 JPEG原理分析及JPEG解码器的调试
来源:互联网 发布:统赢编程说明书 编辑:程序博客网 时间:2024/06/15 20:13
实验原理
JPEG编码的过程如下图所示。解码是编码的逆过程。
JPEG文件解码流程:
①读入文件的相关信息
②初步了解图像数据流的结构
③颜色分量单元的内部解码
④直流系数的差分编码
⑤反量化&反zig-zag编码
⑥反离散余弦变换
JPEG文件格式:
实验流程
1.读取文件
2.解析文件
SOI、APP0、DQT、SOF0、DHT、SOS
3.根据每个分量的水平和垂直采样因子计算最小编码单元的大小,并得到每个最小编码单元内8×8宏块的个数
4.对每个最小编码单元解码
5.解析到EOI结束
6.将Y、Cb、Cr转换为所需的色彩空间保存
代码分析
main函数
int main(int argc, char *argv[]){ int output_format = TINYJPEG_FMT_YUV420P; char *output_filename, *input_filename; clock_t start_time, finish_time; unsigned int duration; int current_argument; int benchmark_mode = 0; Q_table = fopen("Q_table.txt","w"); //量化表、DC AC表 DC_table = fopen("DC_table.yuv","w"); AC_table = fopen("AC_table.yuv","w");#if TRACE p_trace = fopen(TRACEFILE,"w"); //路径文件 if (p_trace == NULL) { printf("trace file open error!"); }#endif if (argc < 3) usage(); current_argument = 1; while (1) { if (strcmp(argv[current_argument], "--benchmark")==0) benchmark_mode = 1; else break; current_argument++; } if (argc < current_argument+2) usage(); input_filename = argv[current_argument]; //设置变换方式 if (strcmp(argv[current_argument+1],"yuv420p")==0) output_format = TINYJPEG_FMT_YUV420P; else if (strcmp(argv[current_argument+1],"rgb24")==0) output_format = TINYJPEG_FMT_RGB24; else if (strcmp(argv[current_argument+1],"bgr24")==0) output_format = TINYJPEG_FMT_BGR24; else if (strcmp(argv[current_argument+1],"grey")==0) output_format = TINYJPEG_FMT_GREY; else if (strcmp(argv[current_argument+1],"yuv")==0) output_format = TINYJPEG_FMT_YUV; else exitmessage("Bad format: need to be one of yuv420p, rgb24, bgr24, grey\n"); output_filename = argv[current_argument+2]; start_time = clock(); if (benchmark_mode) load_multiple_times(input_filename, output_filename, output_format); //加载多次 else convert_one_image(input_filename, output_filename, output_format); //转换一个图像 finish_time = clock(); duration = finish_time - start_time; snprintf(error_string, sizeof(error_string),"Decoding finished in %u ticks\n", duration); fclose(Q_table); //关文件 fclose(DC_table); fclose(AC_table);#if TRACE fclose(p_trace);#endif return 0;}
输出量化表
static int parse_DQT(struct jdec_private *priv, const unsigned char *stream){ int i; int qi; float *table; const unsigned char *dqt_block_end;#if TRACE fprintf(p_trace,"> DQT marker\n"); fflush(p_trace);#endif dqt_block_end = stream + be16_to_cpu(stream); stream += 2; /* Skip length */ while (stream < dqt_block_end) { qi = *stream++;#if SANITY_CHECK if (qi>>4) snprintf(error_string, sizeof(error_string),"16 bits quantization table is not supported\n"); if (qi>4) snprintf(error_string, sizeof(error_string),"No more 4 quantization table is supported (got %d)\n", qi);#endif table = priv->Q_tables[qi]; build_quantization_table(table, stream); /***************************************************/ for(i=0;i<64;i++) { if((!(i%8))) { fprintf(Q_table,"\n%f",table[i]); } else { fprintf(Q_table," %f",table[i]); } } fprintf(Q_table,"\n"); /***************************************************/ stream += 64; }#if TRACE fprintf(p_trace,"< DQT marker\n"); fflush(p_trace);#endif return 0;}
输出DC、AC系数
for (y=0; y < priv->height/ystride_by_mcu; y++) { //trace("Decoding row %d\n", y); priv->plane[0] = priv->components[0] + (y * bytes_per_blocklines[0]); priv->plane[1] = priv->components[1] + (y * bytes_per_blocklines[1]); priv->plane[2] = priv->components[2] + (y * bytes_per_blocklines[2]); for (x=0; x < priv->width; x+=xstride_by_mcu) { decode_MCU(priv); convert_to_pixfmt(priv); priv->plane[0] += bytes_per_mcu[0]; priv->plane[1] += bytes_per_mcu[1]; priv->plane[2] += bytes_per_mcu[2]; if (priv->restarts_to_go>0) { priv->restarts_to_go--; if (priv->restarts_to_go == 0) { priv->stream -= (priv->nbits_in_reservoir/8); resync(priv); if (find_next_rst_marker(priv) < 0) return -1; } } DC[0]=(priv->component_infos->DCT[0]+512.0)/4; DCimage[0]=(unsigned char)(DC[0]+0.5); fwrite(DCimage,1,1,DC_table); //按块写DC系数 ACimage[0]=(unsigned char)(priv->component_infos->DCT[1]+128); fwrite(ACimage,1,1,AC_table); //按块写AC系数 } }
实验结果
原始图像
部分输出文件
DC图像
AC图像
阅读全文
0 0
- 数据压缩实验五 JPEG原理分析JPEG解码器的调试
- 数据压缩 实验五 JPEG原理分析 JPEG解码器的调试
- 数据压缩 实验五 JPEG原理分析JPEG解码器的调试
- 数据压缩原理与应用 实验五 JPEG 原理分析及 JPEG 解码器的调试
- 数据压缩原理 实验五 JPEG原理分析及JPEG解码器的调试
- 数据压缩实验五 JPEG原理分析及JPEG解码器的调试
- 数据压缩实验五——JPEG原理分析及JPEG解码器的调试
- 实验五 JPEG原理分析及JPEG 解码器的调试
- 实验五 JPEG原理分析及JPEG解码器的调试
- 实验五 JPEG原理分析及JPEG解码器的调试
- 【数据压缩】JPEG原理分析及JPEG解码器的调试
- 【实验六】JPEG原理分析及JPEG解码器的调试
- JPEG原理分析及JPEG解码器调试
- JPEG 原理分析及 JPEG 解码器的调试
- 数据压缩实验五:JPEG解码
- 数据压缩实验五:JPEG解码
- 数据压缩实验五:JPEG文件解码实验分析
- 【数据压缩】JPEG标准与原理解析
- MOOC清华《程序设计基础》第5章:快速排序(不分配动态空间-算法三)
- C#基础知识延伸
- Spark中宽依赖和窄依赖
- window快捷键
- Java基础知识总结(绝对经典)
- 数据压缩原理 实验五 JPEG原理分析及JPEG解码器的调试
- 二分法查找升序和降序集合
- STM32寄存器操作和库函数操作区别
- 完全覆盖问题
- 【编程题】数组中是否含有该整数
- 求职应用的制作
- Java中数组和List的排序
- RGB565颜色表,附RGB888转RGB565工具,RGB24转RGB565工具
- 初识Spark之 基本概念