注:分析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下编译通过。
压缩包中的"tinyjpegdecoder-20070609.tar.bz2"文件是Tiny JPEG Decoder的源代码包,日期为2007年6月9日,可能包含了编译说明、示例代码和其他相关资源。"welcome.txt"可能是对项目的一个简短介绍或使用指南。 学习...
作为从jpge小组文档中移植的代码,tinyjpeg可能是开源的,允许开发者查看源代码、学习解码技术,并对其进行改进。这有助于整个图像处理社区的技术交流和发展。 总的来说,tinyjpeg是一个实用的JPEG解码工具,它的...
在本文中,我们将深入探讨如何在STM32微控制器上移植JPEG解码程序,并结合SD卡和TTF(TrueType Font)技术实现图像显示在液晶屏上的完整过程。STM32是一款广泛应用于嵌入式系统的微处理器,具有高性能、低功耗的特点...
Arduino TJpg_Decoder库该Arduino库支持将存储在SD卡上以及程序存储器(FLASH)中的阵列中的Jpeg文件呈现到TFT显示器上。 此外,存储在SPIFFS Flash归档系统或“ PROGMEM”阵列中的图像可以与ESP8266和ESP32处理器...
4. **显示驱动**:解码后的图像数据需要通过LCD或OLED等显示设备呈现,需要将解码后的像素数据格式转换为对应驱动程序所接受的格式。 5. **性能优化**:由于STM32的处理能力有限,可能需要对解码算法进行优化,比如...
Tiny_Jpeg 微型 Jpeg 解码器 Luc Saillard GNU 公共许可证的原始代码 2007 年 6 月 9 日 tinyjpegdecoder-20070609.... 2个流行的公共Jpeg解码器小代码之一 Nano Jpeg Martin Fiedler东德 Tiny Jpeg Luc Saillard 法国
**源代码分析** 源代码是程序员用高级语言书写的程序文本,它是编译器工作的输入。在这个压缩包中,你将找到`Tiny+`编译器的源代码,这将使你有机会深入到编译器的内部,观察其如何处理源代码的每一个细节。 **...
Tiny+编译器源代码是针对编程语言 Tiny+ 的一种小型编译器实现,它用于将 Tiny+ 语言的源代码转换成机器可执行的代码。这个开源项目为学习编译器原理和实现提供了很好的实践素材,特别是对于华工大学的学生们在进行...
2. **源代码分析** 在`tinyxml_2_5_3.rar`中,包含了TinyXML的源代码,通过阅读源代码,你可以了解到XML解析器的工作原理。例如,`TiXmlElement`类如何存储元素名和属性,`TiXmlNode`如何构建节点树,以及`...
2. **TinyJPEG库**:针对嵌入式系统的轻量级解决方案,TinyJPEG库在libjpeg的基础上进行了优化,更适合资源受限的设备。它体积小、速度快,适合STM32这样的微控制器使用。 【JPEG压缩步骤】 使用TinyJPEG库将RGB...
Tiny JPEG Decompressor的源代码简洁明了,易于理解和移植。开发者可以轻松地根据自己的需求进行定制和优化。源码的组织结构清晰,主要分为解码核心部分和平台相关的I/O函数。解码核心部分负责处理JPEG的编码格式,...
对于学习者来说,分析和理解Tiny编译器的源代码是一个宝贵的机会,可以提高对编译原理的理解,同时为编写自己的编译器或解释器打下基础。实践过程中,可以尝试修改源代码,添加新的语言特性,或者优化现有功能,这将...
- **驱动程序源代码位置**:`Linux-2.6.38/drivers/i2c/busses/i2c-s3c2410.c` - **设备名**:`/dev/i2c/0` - **备注**:I2C(Inter-Integrated Circuit)总线用于连接低速的外围设备,如EEPROM。 ##### 18. 万能 ...
语法分析器是编译器设计的关键组成部分,它负责将源代码转换为抽象语法树(AST),这是理解程序结构的关键步骤。本项目以C语言为工具,实现了一个语法分析器,采用了两种不同的方法:递归下降分析法和LL(1)语法分析...
《TINY编译器源代码》是针对C语言实现的一款小型编译器,它能够将输入的源代码文件转换为对应的机器码,从而在计算机上执行。这一项目通常与《编译原理与实践》这本教材相结合,为学习编译器设计与实现的初学者提供...
•完成并提交实验报告,扫描程序的源程序,编译后的可执行程序,例子和运行结果. 实验报告至少要包含如下内容: 1 实验目的; 2 TINYC语言的词法说明,扫描器的输入和输出; 3 实验原理(所采用的过程); 3.1 记号种类及各...
【TINYC tiny c最快的c编译器源代码.rar】是一个包含TINYC C编译器源代码的压缩包。TINYC是一个小型且快速的C语言编译器,它被设计为轻量级,适合在资源有限的环境中使用,如嵌入式系统或老旧的计算机上。该压缩包中...