注:分析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_PARAMfprintf(param_trace,"Bad pixel format\n");fflush(param_trace);
#endifreturn -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_PARAMfprintf(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_PARAMfprintf(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_PARAMfprintf(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_PARAMfprintf(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_PARAMfprintf(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_PARAMfprintf(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);
#endifreturn 0;
}

主页:http://www.saillard.org/programs_and_patches/tinyjpegdecoder/

源代码下载:http://download.csdn.net/detail/leixiaohua1020/6383115

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

  1. 中秋节祝福程序源代码分享:土地分类数据阈值筛选和重投影分类

    今年的中秋又要到啦,我的中秋节祝福程序源代码分享:过什么节,代码走起! 今天主要给大家介绍的是关于一个如何对影像重投影然后获取特定阈值情况下的影像 先看结果: 原始影像 重投影后的影像: 这里用到的数 ...

  2. ◆勇敢者论坛源代码分析系列(1)—数据查询

    前言:勇敢者论坛是一个开放源码的ASP.NET c#论坛,使用VS.NET 2005开发管理,可以支持两种数据库 SQL2000或Accsee.作者的开发本意,就是提供给大家学习使用的.写本系列代码分 ...

  3. Tiny Jpeg Decoder (JPEG解码程序) 源代码分析 1:解码文件头

    注:分析Tiny Jpeg Decoder源代码的文章: Tiny Jpeg Decoder (JPEG解码程序) 源代码分析 1:解码文件头 Tiny Jpeg Decoder (JPEG解码程序) ...

  4. MediaInfo源代码分析 5:JPEG解析代码分析

    ===================================================== MediaInfo源代码分析系列文章列表: MediaInfo源代码分析 1:整体结构 Me ...

  5. Android系统默认Home应用程序(Launcher)的启动过程源代码分析

    在前面一篇文章中,我们分析了Android系统在启动时安装应用程序的过程,这些应用程序安装好之后,还需要有一个Home应用程序来负责把它们在桌面上展示出来,在Android系统中,这个默认的Home应 ...

  6. Android应用程序进程启动过程的源代码分析(1)

    Android应用程序框架层创建的应用程序进程具有两个特点,一是进程的入口函数是ActivityThread.main,二是进程天然支持Binder进程间通信机制:这两个特点都是在进程的初始化过程中实 ...

  7. Android系统默认Home应用程序(Launcher)的启动过程源代码分析(3)

    Step 13.  ActivityStack.startActivityLocked 这个函数定义在frameworks/base/services/java/com/android/server/ ...

  8. Android应用程序组件Content Provider的启动过程源代码分析(1)

             通过前面的学习,我们知道在Android系统中,Content Provider可以为不同的应用程序访问相同的数据提供统一的入口.Content Provider一般是运行在独立的进 ...

  9. Android应用程序安装过程源代码分析(1)

    Android系统在启动的过程中,会启动一个应用程序管理服务PackageManagerService,这个服务负责扫描系统中特定的目录,找到里面的应用程序文件,即以Apk为后缀的文件,然后对这些文件 ...

最新文章

  1. mongo下面总是缺少那么几个好用的工具--------试试这个吧-----MongoDB管理工具
  2. MDK 的编译过程及文件类型全解
  3. LINUX ulimit命令
  4. context:annotation-config/,context:component-scan/,mvc:annotation-driven/区分
  5. Angular Lazy Load 的一个局限性以及解决办法
  6. Java 并发工具箱之concurrent包
  7. 前端学习(3253):react脚手架文件介绍
  8. FreeRTOS之源码 及 移植详解
  9. 百度AI开放平台文字之身份证识别的实现
  10. 《甄嬛传》影评(整理)
  11. ARM中C语言和汇编语言互相调用以及实例
  12. 同治光绪之交的九江城
  13. 论文阅读:Gradient Harmonized Single-stage Detector
  14. Oracle 官网下载地址
  15. iphone比android好在,比Android手机强在哪里?iPhone 6遇挑战
  16. PHP汉字转拼音笔记.txt
  17. 数字图像处理(第三版)绪论笔记
  18. 华为手机摄影入门到精通pdf_手机摄影入门教程视频 手机摄影技巧视频教程
  19. 单调时钟与墙上时钟的区别?ntp如何优雅校时?
  20. you-get简明使用教程

热门文章

  1. ORACLE 中IN和EXISTS比较
  2. 打算做个单用户博客,引用收藏一下zblog的话
  3. 机器学习基础(六十三)—— 奇异值分解(SVD)
  4. 趣学 C 语言(十)—— 控制台交互(getch() vs. getchar())
  5. gcc/g++ 参数总结
  6. bootstrap 模态框无法使用_22 模态框Modal教程(plotly Dash Bootstrap版)
  7. python菱形_python如何输出菱形与空心菱形详解与巧妙地使用center方法
  8. python下载-python
  9. python与java前景-Java和Python现在都很热门,哪个更有前途?
  10. python自学行吗-python自学行吗?给编程初学者零基础入门的建议