注:分析Tiny Jpeg Decoder源代码的文章:
Tiny Jpeg Decoder (JPEG解码程序) 源代码分析 1:解码文件头
Tiny Jpeg Decoder (JPEG解码程序) 源代码分析 2:解码数据
===================
Tiny Jpeg Decoder是一个可以用于嵌入式系统的JPEG解码器。也可以在Windows上编译通过。在此分析一下它部分的源代码,辅助学习JPEG解码知识。
通过TinyJpeg可以将JPEG(*.jpg)文件解码为YUV(*.yuv)或者RGB(*.tga)文件。
真正的解码数据开始于tinyjpeg_decode()函数:
注意:本代码中包含部分自己写的代码,用于提取DCT系数表,解码后亮度数据表等数据。
/** * Decode and convert the jpeg image into @pixfmt@ image *解码函数 * Note: components will be automaticaly allocated if no memory is attached. */ int tinyjpeg_decode(struct jdec_private *priv, int pixfmt) { unsigned int x, y, xstride_by_mcu, ystride_by_mcu; unsigned int bytes_per_blocklines[3], bytes_per_mcu[3]; decode_MCU_fct decode_MCU; const decode_MCU_fct *decode_mcu_table; const convert_colorspace_fct *colorspace_array_conv; convert_colorspace_fct convert_to_pixfmt; //------------------------------------------- FILE *fp; char *temp; int j,k; //------------------------------------------- if (setjmp(priv->jump_state)) return -1; /* To keep gcc happy initialize some array */ bytes_per_mcu[1] = 0; bytes_per_mcu[2] = 0; bytes_per_blocklines[1] = 0; bytes_per_blocklines[2] = 0; decode_mcu_table = decode_mcu_3comp_table; switch (pixfmt) { case TINYJPEG_FMT_YUV420P: colorspace_array_conv = convert_colorspace_yuv420p; if (priv->components[0] == NULL) priv->components[0] = (uint8_t *)malloc(priv->width * priv->height); if (priv->components[1] == NULL) priv->components[1] = (uint8_t *)malloc(priv->width * priv->height/4); if (priv->components[2] == NULL) priv->components[2] = (uint8_t *)malloc(priv->width * priv->height/4); bytes_per_blocklines[0] = priv->width; bytes_per_blocklines[1] = priv->width/4; bytes_per_blocklines[2] = priv->width/4; bytes_per_mcu[0] = 8; bytes_per_mcu[1] = 4; bytes_per_mcu[2] = 4; break; case TINYJPEG_FMT_RGB24: colorspace_array_conv = convert_colorspace_rgb24; if (priv->components[0] == NULL) priv->components[0] = (uint8_t *)malloc(priv->width * priv->height * 3); bytes_per_blocklines[0] = priv->width * 3; bytes_per_mcu[0] = 3*8; break; case TINYJPEG_FMT_BGR24: colorspace_array_conv = convert_colorspace_bgr24; if (priv->components[0] == NULL) priv->components[0] = (uint8_t *)malloc(priv->width * priv->height * 3); bytes_per_blocklines[0] = priv->width * 3; bytes_per_mcu[0] = 3*8; break; case TINYJPEG_FMT_GREY: decode_mcu_table = decode_mcu_1comp_table; colorspace_array_conv = convert_colorspace_grey; if (priv->components[0] == NULL) priv->components[0] = (uint8_t *)malloc(priv->width * priv->height); bytes_per_blocklines[0] = priv->width; bytes_per_mcu[0] = 8; break; default: #if TRACE_PARAM fprintf(param_trace,"Bad pixel format\n"); fflush(param_trace); #endif return -1; } 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_PARAM fprintf(param_trace,"Use decode 1x1 sampling\n"); fflush(param_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_PARAM fprintf(param_trace,"Use decode 1x2 sampling (not supported)\n"); fflush(param_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_PARAM fprintf(param_trace,"Use decode 2x2 sampling\n"); fflush(param_trace); #endif } else { decode_MCU = decode_mcu_table[2]; convert_to_pixfmt = colorspace_array_conv[2]; xstride_by_mcu = 16; #if TRACE_PARAM fprintf(param_trace,"Use decode 2x1 sampling\n"); fflush(param_trace); #endif } resync(priv); /* Don't forget to that block can be either 8 or 16 lines */ bytes_per_blocklines[0] *= ystride_by_mcu; bytes_per_blocklines[1] *= ystride_by_mcu; bytes_per_blocklines[2] *= ystride_by_mcu; bytes_per_mcu[0] *= xstride_by_mcu/8; bytes_per_mcu[1] *= xstride_by_mcu/8; bytes_per_mcu[2] *= xstride_by_mcu/8; /* Just the decode the image by macroblock (size is 8x8, 8x16, or 16x16) */ //纵向 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); //DCT系数----------------------------------------------------------- //temp=(char *)priv->component_infos->DCT; //if(y==4&&x==xstride_by_mcu*3){ if(priv->dlg->m_vijpgoutputdct.GetCheck()==1){ fp = fopen("DCT系数表.txt", "a+"); //fwrite(temp,64,1,fp); fprintf(fp,"第%d行,第%d列\n",y,x/xstride_by_mcu); for(j=0;j<64;j++){ fprintf(fp,"%d ",priv->component_infos[cY].DCT[j]); } fprintf(fp,"\n"); fclose(fp); } #if TRACE_PARAM fprintf(param_trace,"\n第3行,第4列\n"); for(j=0;j<8;j++){ for(k=0;k<8;k++){ fprintf(param_trace,"%d ",priv->component_infos[cY].DCT[j*8+k]); } fprintf(param_trace,"\n"); } fprintf(fp,"\n-----------------------\n"); fflush(param_trace); #endif //} //解码后系数(Y)--------------------------------------------------- //temp=(char *)priv->Y; //if(y==4&&x==xstride_by_mcu*3){ if(priv->dlg->m_vijpgoutputy.GetCheck()==1){ fp = fopen("解码后Y系数表.txt", "a+"); //fwrite(temp,64*4,1,fp); fprintf(fp,"第%d行,第%d列\n",y,x/xstride_by_mcu); for(j=0;j<64*4;j++){ fprintf(fp,"%d ",priv->Y[j]); } fprintf(fp,"\n"); fclose(fp); } #if TRACE_PARAM fprintf(param_trace,"第3行,第4列\n"); for(j=0;j<8;j++){ for(k=0;k<8;k++){ fprintf(param_trace,"%d ",priv->Y[j*8+k]); } fprintf(param_trace,"\n"); } fprintf(fp,"\n-----------------------\n"); fflush(param_trace); #endif //} //------------------------------------------------------------------ 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; } } } } #if TRACE_PARAM fprintf(param_trace,"Input file size: %d\n", priv->stream_length+2); fprintf(param_trace,"Input bytes actually read: %d\n", priv->stream - priv->stream_begin + 2); fflush(param_trace); #endif return 0; }
主页:http://www.saillard.org/programs_and_patches/tinyjpegdecoder/
源代码下载:http://download.csdn.net/detail/leixiaohua1020/6383115
相关推荐
tiny jpeg decoder 是可以用于嵌入式系统的jpeg解码器,也可以在windows下编译通过。
一个jpeg解码程序。部分程序移植子jpge group的文档。gcc下编译通过
Arduino TJpg_Decoder库该Arduino库支持将存储在SD卡上以及程序存储器(FLASH)中的阵列中的Jpeg文件呈现到TFT显示器上。 此外,存储在SPIFFS Flash归档系统或“ PROGMEM”阵列中的图像可以与ESP8266和ESP32处理器...
Tiny_Jpeg 微型 Jpeg 解码器 Luc Saillard GNU 公共许可证的原始代码 2007 年 6 月 9 日 tinyjpegdecoder-20070609.... 2个流行的公共Jpeg解码器小代码之一 Nano Jpeg Martin Fiedler东德 Tiny Jpeg Luc Saillard 法国
这个是友善之臂专题8的源代码,不过没有注释,现在加上了注释,提供下载链接,也可以不下载,对照着这里看。因为这个过程包括采集、硬编码、软解码等过程。 调用的函数是规范的,所以不是用tiny6410的也可以看看,...
•完成并提交实验报告,扫描程序的源程序,编译后的可执行程序,例子和运行结果. 实验报告至少要包含如下内容: 1 实验目的; 2 TINYC语言的词法说明,扫描器的输入和输出; 3 实验原理(所采用的过程); 3.1 记号种类及各...
tiny+编译器的源代码,喜欢研究编译器的都来看看吧
一共有两个Tiny编译器的源代码,供参考~实现TINY+编译器的词法分析和词义分析,以及建立语法树和语义分析。 包括源代码、可执行文件、详细设计报告
编译原理实验二 TINY扩充语言的语法分析 源代码
这是一份完全自主知识产权的tiny+源代码,仅供参考,大作业还是要自己认真做滴~
便宜,超全 快速入门 tinyxml源代码,示例,教程 三个包
Keil Rtx51 Tiny 多任务操作系统源代码
his is an attempt to implement key features of the Tiny Wings game.本代码基于Cocos2D framework/[appcodes.org]
TinyXML2源代码及工程,读写轻便有效率,接口易使用
TinyXML是一个开源的解析XML的解析库,能够用于C++,能够在Windows或Linux中编译。这个解析库的模型通过解析XML文件,然后在内存中生成DOM模型,从而让我们很方便的遍历...提供C++源代码、vs2010编译工程、lib库文件。
tinyxml2.6.2开发库及源代码,挺好用的
1.5.3 通过USB ADB在Tiny4412上运行程序 - 16 - 1.5.4 在Tiny4412上调试Android程序 - 18 - 第二章 在ANDORID程序中访问硬件 - 20 - 2.1 如何使用函数库(LIBFRIENDLYARM-HARDWARE.SO)? - 20 - 2.2 函数库...
解析xml的tinyxml源代码,适合c++开发者
TINY+词法分析,语法分析,语义分析,代码生成。包含实验报告。
TINY+语言的语法分析软件提供Window界面,用户可以点击【打开】按钮打开或者在编辑框中输入一个扩展Tiny+语言源程序;通过【打印语法树】复选按钮可以选择在分析结果中打印语法树,【语法分析】按钮提供Tiny语言词法...