`

Tiny Jpeg Decoder (JPEG解码程序) 源代码分析 2:解码数据

 
阅读更多

 

注:分析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解码器)

    tiny jpeg decoder 是可以用于嵌入式系统的jpeg解码器,也可以在windows下编译通过。

    小型JPEG图片解码器Tiny JPEG Decoder

    压缩包中的"tinyjpegdecoder-20070609.tar.bz2"文件是Tiny JPEG Decoder的源代码包,日期为2007年6月9日,可能包含了编译说明、示例代码和其他相关资源。"welcome.txt"可能是对项目的一个简短介绍或使用指南。 学习...

    tinyjpeg jpge解码程序

    作为从jpge小组文档中移植的代码,tinyjpeg可能是开源的,允许开发者查看源代码、学习解码技术,并对其进行改进。这有助于整个图像处理社区的技术交流和发展。 总的来说,tinyjpeg是一个实用的JPEG解码工具,它的...

    STM32中成功移值JPEG解码程序,有SD卡+TTF液晶

    在本文中,我们将深入探讨如何在STM32微控制器上移植JPEG解码程序,并结合SD卡和TTF(TrueType Font)技术实现图像显示在液晶屏上的完整过程。STM32是一款广泛应用于嵌入式系统的微处理器,具有高性能、低功耗的特点...

    TJpg_Decoder:基于Tiny JPEG Decompressor的Jpeg解码器库

    Arduino TJpg_Decoder库该Arduino库支持将存储在SD卡上以及程序存储器(FLASH)中的阵列中的Jpeg文件呈现到TFT显示器上。 此外,存储在SPIFFS Flash归档系统或“ PROGMEM”阵列中的图像可以与ESP8266和ESP32处理器...

    JPEG解码,可以移植到STM32中

    4. **显示驱动**:解码后的图像数据需要通过LCD或OLED等显示设备呈现,需要将解码后的像素数据格式转换为对应驱动程序所接受的格式。 5. **性能优化**:由于STM32的处理能力有限,可能需要对解码算法进行优化,比如...

    Tiny_Jpeg:微型 Jpeg 解码器

    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+编译器源代码是针对编程语言 Tiny+ 的一种小型编译器实现,它用于将 Tiny+ 语言的源代码转换成机器可执行的代码。这个开源项目为学习编译器原理和实现提供了很好的实践素材,特别是对于华工大学的学生们在进行...

    tinyxml源代码,示例,教程

    2. **源代码分析** 在`tinyxml_2_5_3.rar`中,包含了TinyXML的源代码,通过阅读源代码,你可以了解到XML解析器的工作原理。例如,`TiXmlElement`类如何存储元素名和属性,`TiXmlNode`如何构建节点树,以及`...

    STM32单片机上RGB数据转为JPEG格式办法.pdf

    2. **TinyJPEG库**:针对嵌入式系统的轻量级解决方案,TinyJPEG库在libjpeg的基础上进行了优化,更适合资源受限的设备。它体积小、速度快,适合STM32这样的微控制器使用。 【JPEG压缩步骤】 使用TinyJPEG库将RGB...

    Tiny JPEG Decompressor

    Tiny JPEG Decompressor的源代码简洁明了,易于理解和移植。开发者可以轻松地根据自己的需求进行定制和优化。源码的组织结构清晰,主要分为解码核心部分和平台相关的I/O函数。解码核心部分负责处理JPEG的编码格式,...

    Tiny编译器的源代码

    对于学习者来说,分析和理解Tiny编译器的源代码是一个宝贵的机会,可以提高对编译原理的理解,同时为编写自己的编译器或解释器打下基础。实践过程中,可以尝试修改源代码,添加新的语言特性,或者优化现有功能,这将...

    6410-linux驱动程序的位置

    - **驱动程序源代码位置**:`Linux-2.6.38/drivers/i2c/busses/i2c-s3c2410.c` - **设备名**:`/dev/i2c/0` - **备注**:I2C(Inter-Integrated Circuit)总线用于连接低速的外围设备,如EEPROM。 ##### 18. 万能 ...

    语法分析器(C语言源代码)(附实验报告)

    语法分析器是编译器设计的关键组成部分,它负责将源代码转换为抽象语法树(AST),这是理解程序结构的关键步骤。本项目以C语言为工具,实现了一个语法分析器,采用了两种不同的方法:递归下降分析法和LL(1)语法分析...

    TINY 编译器源代码

    《TINY编译器源代码》是针对C语言实现的一款小型编译器,它能够将输入的源代码文件转换为对应的机器码,从而在计算机上执行。这一项目通常与《编译原理与实践》这本教材相结合,为学习编译器设计与实现的初学者提供...

    设计并实现TINYC语言的扫描程序TINYC.zip

    •完成并提交实验报告,扫描程序的源程序,编译后的可执行程序,例子和运行结果. 实验报告至少要包含如下内容: 1 实验目的; 2 TINYC语言的词法说明,扫描器的输入和输出; 3 实验原理(所采用的过程); 3.1 记号种类及各...

    TINYC tiny c最快的c编译器源代码.rar

    【TINYC tiny c最快的c编译器源代码.rar】是一个包含TINYC C编译器源代码的压缩包。TINYC是一个小型且快速的C语言编译器,它被设计为轻量级,适合在资源有限的环境中使用,如嵌入式系统或老旧的计算机上。该压缩包中...

Global site tag (gtag.js) - Google Analytics