=====================================================

MediaInfo源代码分析系列文章列表:

MediaInfo源代码分析 1:整体结构
MediaInfo源代码分析 2:API函数
MediaInfo源代码分析 3:Open()函数
MediaInfo源代码分析 4:Inform()函数
MediaInfo源代码分析 5:JPEG解析代码分析

=====================================================

本文分析MediaInfo中解码JPEG信息的模块。之前写了几篇文章都是关于MediaInfo主程序的,并没有分析其具体是如何解析不同多媒体文件信息的。在这里分析一下解码JPEG文件的代码。其他格式如BMP,GIF等解析的思路基本上是类似的。

File_Jpeg.h的File_Jpeg类的定义如下所示:

//***************************************************************************
// Class File_Jpeg
//***************************************************************************
//继承 File__Analyze
class File_Jpeg : public File__Analyze
{
public ://Instream_t StreamKind;bool     Interlaced;//Constructor/DestructorFile_Jpeg();private ://Streams managementvoid Streams_Accept();//Buffer - File headerbool FileHeader_Begin();//Buffer - Synchrobool Synchronize();bool Synched_Test();void Synched_Init();//Buffer - Demux#if MEDIAINFO_DEMUXbool Demux_UnpacketizeContainer_Test() {return Demux_UnpacketizeContainer_Test_OneFramePerFile();}#endif //MEDIAINFO_DEMUX//Buffer - Globalvoid Read_Buffer_Unsynched();#if MEDIAINFO_SEEKsize_t Read_Buffer_Seek (size_t Method, int64u Value, int64u ID) {return Read_Buffer_Seek_OneFramePerFile(Method, Value, ID);}#endif //MEDIAINFO_SEEK//Buffer - Per element//解析头void Header_Parse();bool Header_Parser_Fill_Size();//解析数据void Data_Parse();//Elements//JPEG中的单元//解析相应的单元,并获得信息void TEM () {};void SOC () {}void SIZ ();void COD ();void COC () {Skip_XX(Element_Size, "Data");}void TLM () {Skip_XX(Element_Size, "Data");}void PLM () {Skip_XX(Element_Size, "Data");}void PLT () {Skip_XX(Element_Size, "Data");}void QCD ();void QCC () {Skip_XX(Element_Size, "Data");}void RGN () {Skip_XX(Element_Size, "Data");}void PPM () {Skip_XX(Element_Size, "Data");}void PPT () {Skip_XX(Element_Size, "Data");}void CME () {Skip_XX(Element_Size, "Data");}void SOT () {Skip_XX(Element_Size, "Data");}void SOP () {Skip_XX(Element_Size, "Data");}void EPH () {Skip_XX(Element_Size, "Data");}void SOD ();void SOF_();void S0F0() {SOF_();};void S0F1() {SOF_();};void S0F2() {SOF_();};void S0F3() {SOF_();}void DHT () {Skip_XX(Element_Size, "Data");}void S0F5() {SOF_();}void S0F6() {SOF_();}void S0F7() {SOF_();}void JPG () {Skip_XX(Element_Size, "Data");}void S0F9() {SOF_();}void S0FA() {SOF_();}void S0FB() {SOF_();}void DAC () {Skip_XX(Element_Size, "Data");}void S0FD() {SOF_();}void S0FE() {SOF_();}void S0FF() {SOF_();}void RST0() {};void RST1() {};void RST2() {};void RST3() {};void RST4() {};void RST5() {};void RST6() {};void RST7() {};void SOI () {};void EOI () {};void SOS ();void DQT () {Skip_XX(Element_Size, "Data");}void DNL () {Skip_XX(Element_Size, "Data");}void DRI () {Skip_XX(Element_Size, "Data");}void DHP () {Skip_XX(Element_Size, "Data");}void EXP () {Skip_XX(Element_Size, "Data");}void APP0();void APP0_AVI1();void APP0_JFIF();void APP0_JFFF();void APP0_JFFF_JPEG();void APP0_JFFF_1B();void APP0_JFFF_3B();void APP1();void APP1_EXIF();void APP2() {Skip_XX(Element_Size, "Data");}void APP3() {Skip_XX(Element_Size, "Data");}void APP4() {Skip_XX(Element_Size, "Data");}void APP5() {Skip_XX(Element_Size, "Data");}void APP6() {Skip_XX(Element_Size, "Data");}void APP7() {Skip_XX(Element_Size, "Data");}void APP8() {Skip_XX(Element_Size, "Data");}void APP9() {Skip_XX(Element_Size, "Data");}void APPA() {Skip_XX(Element_Size, "Data");}void APPB() {Skip_XX(Element_Size, "Data");}void APPC() {Skip_XX(Element_Size, "Data");}void APPD() {Skip_XX(Element_Size, "Data");}void APPE();void APPE_Adobe0();void APPF() {Skip_XX(Element_Size, "Data");}void JPG0() {Skip_XX(Element_Size, "Data");}void JPG1() {Skip_XX(Element_Size, "Data");}void JPG2() {Skip_XX(Element_Size, "Data");}void JPG3() {Skip_XX(Element_Size, "Data");}void JPG4() {Skip_XX(Element_Size, "Data");}void JPG5() {Skip_XX(Element_Size, "Data");}void JPG6() {Skip_XX(Element_Size, "Data");}void JPG7() {Skip_XX(Element_Size, "Data");}void JPG8() {Skip_XX(Element_Size, "Data");}void JPG9() {Skip_XX(Element_Size, "Data");}void JPGA() {Skip_XX(Element_Size, "Data");}void JPGB() {Skip_XX(Element_Size, "Data");}void JPGC() {Skip_XX(Element_Size, "Data");}void JPGD() {Skip_XX(Element_Size, "Data");}void COM () {Skip_XX(Element_Size, "Data");}//Tempint8u APPE_Adobe0_transform;bool  APP0_JFIF_Parsed;bool  SOS_SOD_Parsed;
};

上面代码有以下几个特点:

1.继承了File__Analyze类

2.包含了很多JPEG中的数据单元的解析:DHT(),DQT()等等

下面来分别仔细看看源代码:

1.File__Analyze类代码巨多无比,先不分析。他继承了继承了File__Base

2.看一个解码具体单元的代码:SOF_()

注:SOF0(Start of Image,图像开始)。

SOF0,Start of Frame,帧图像开始

标记代码                   2字节     固定值0xFFC0

包含9个具体字段:
                                      ① 数据长度           2字节     ①~⑥六个字段的总长度
                                                                                      即不包括标记代码,但包括本字段
                                     ② 精度                 1字节     每个数据样本的位数
                                                                                    通常是8位,一般软件都不支持 12位和16位
                                    ③ 图像高度           2字节     图像高度(单位:像素),如果不支持 DNL 就必须 >0
                                    ④ 图像宽度           2字节     图像宽度(单位:像素),如果不支持 DNL 就必须 >0
                                    ⑤ 颜色分量数        1字节     只有3个数值可选
                                                                     1:灰度图;3:YCrCb或YIQ;4:CMYK
                                                                     而JFIF中使用YCrCb,故这里颜色分量数恒为3
                                   ⑥颜色分量信息      颜色分量数×3字节(通常为9字节)
                                                       a)         颜色分量ID                 1字节    
                                                       b)        水平/垂直采样因子      1字节            高4位:水平采样因子
                                                                  低4位:垂直采样因子
                                                                (曾经看到某资料把这两者调转了)
                                                       c)        量化表                         1字节            当前分量使用的量化表的ID

本标记段中,字段⑥应该重复出现,有多少个颜色分量(字段⑤),就出现多少次(一般为3次)。

=====================================

void File_Jpeg::SOF_()
{//Parsingvector<Jpeg_samplingfactor> SamplingFactors;int16u Height, Width;int8u  Resolution, Count;Get_B1 (Resolution,                                         "P - Sample precision");Get_B2 (Height,                                             "Y - Number of lines");Get_B2 (Width,                                              "X - Number of samples per line");Get_B1 (Count,                                              "Nf - Number of image components in frame");for (int8u Pos=0; Pos<Count; Pos++){Jpeg_samplingfactor SamplingFactor;Element_Begin1("Component");Get_B1 (   SamplingFactor.Ci,                           "Ci - Component identifier"); if (SamplingFactor.Ci>Count) Element_Info1(Ztring().append(1, (Char)SamplingFactor.Ci)); else Element_Info1(SamplingFactor.Ci);BS_Begin();Get_S1 (4, SamplingFactor.Hi,                           "Hi - Horizontal sampling factor"); Element_Info1(SamplingFactor.Hi);Get_S1 (4, SamplingFactor.Vi,                           "Vi - Vertical sampling factor"); Element_Info1(SamplingFactor.Vi);BS_End();Skip_B1(                                                "Tqi - Quantization table destination selector");Element_End0();//Filling list of HiViSamplingFactors.push_back(SamplingFactor);}FILLING_BEGIN_PRECISE();if (Frame_Count==0 && Field_Count==0){Accept("JPEG");Fill("JPEG");if (Count_Get(StreamKind_Last)==0)Stream_Prepare(StreamKind_Last);Fill(StreamKind_Last, 0, Fill_Parameter(StreamKind_Last, Generic_Format), "JPEG");Fill(StreamKind_Last, 0, Fill_Parameter(StreamKind_Last, Generic_Codec), "JPEG");if (StreamKind_Last==Stream_Image)Fill(Stream_Image, 0, Image_Codec_String, "JPEG", Unlimited, true, true); //To Avoid automatic fillingif (StreamKind_Last==Stream_Video)Fill(Stream_Video, 0, Video_InternetMediaType, "video/JPEG", Unlimited, true, true);Fill(StreamKind_Last, 0, Fill_Parameter(StreamKind_Last, Generic_BitDepth), Resolution);Fill(StreamKind_Last, 0, "Height", Height*(Interlaced?2:1));Fill(StreamKind_Last, 0, "Width", Width);//ColorSpace from http://docs.oracle.com/javase/1.4.2/docs/api/javax/imageio/metadata/doc-files/jpeg_metadata.htmlswitch (APPE_Adobe0_transform){case 0x01 :if (Count==3)Fill(StreamKind_Last, 0, "ColorSpace", "YUV");case 0x02 :if (Count==4)Fill(StreamKind_Last, 0, "ColorSpace", "YCCB");break;default   :{int8u Ci[256];memset(Ci, 0, 256);;for (int8u Pos=0; Pos<Count; Pos++)Ci[SamplingFactors[Pos].Ci]++;switch (Count){case 1 :    Fill(StreamKind_Last, 0, "ColorSpace", "Y"); break;case 2 :    Fill(StreamKind_Last, 0, "ColorSpace", "YA"); break;case 3 :if (!APP0_JFIF_Parsed && Ci['R']==1 && Ci['G']==1 && Ci['B']==1)                                                       //RGBFill(StreamKind_Last, 0, "ColorSpace", "RGB");else if ((Ci['Y']==1 && ((Ci['C']==1 && Ci['c']==1)                                                                         //YCc|| Ci['C']==2))                                                                                       //YCC|| APP0_JFIF_Parsed                                                                                                   //APP0 JFIF header present so YCC|| APPE_Adobe0_transform==0                                                                                           //transform set to YCC|| (SamplingFactors[0].Ci==0 && SamplingFactors[1].Ci==1 && SamplingFactors[2].Ci==2)                                 //012|| (SamplingFactors[0].Ci==1 && SamplingFactors[1].Ci==2 && SamplingFactors[2].Ci==3))                                //123Fill(StreamKind_Last, 0, "ColorSpace", "YUV");break;case 4 :if (!APP0_JFIF_Parsed && Ci['R']==1 && Ci['G']==1 && Ci['B']==1 && Ci['A']==1)                                         //RGBAFill(StreamKind_Last, 0, "ColorSpace", "RGBA");else if ((Ci['Y']==1 && Ci['A']==1 && ((Ci['C']==1 && Ci['c']==1)                                                           //YCcA|| Ci['C']==2))                                                                         //YCCA|| APP0_JFIF_Parsed                                                                                                   //APP0 JFIF header present so YCCA|| (SamplingFactors[0].Ci==0 && SamplingFactors[1].Ci==1 && SamplingFactors[2].Ci==2 && SamplingFactors[3].Ci==3)     //0123|| (SamplingFactors[0].Ci==1 && SamplingFactors[1].Ci==2 && SamplingFactors[2].Ci==3 && SamplingFactors[3].Ci==4))    //1234Fill(StreamKind_Last, 0, "ColorSpace", "YUVA");else if (APPE_Adobe0_transform==0)                                                                                          //transform set to CMYKFill(StreamKind_Last, 0, "ColorSpace", "YCCB");break;default:    ;}}}//Chroma subsamplingif ((SamplingFactors.size()==3 || SamplingFactors.size()==4) && SamplingFactors[1].Hi==1 && SamplingFactors[2].Hi==1 && SamplingFactors[1].Vi==1 && SamplingFactors[2].Vi==1){string ChromaSubsampling;switch (SamplingFactors[0].Hi){case 1 :switch (SamplingFactors[0].Vi){case 1 : ChromaSubsampling="4:4:4"; break;default: ;}break;case 2 :switch (SamplingFactors[0].Vi){case 1 : ChromaSubsampling="4:2:2"; break;case 2 : ChromaSubsampling="4:2:0"; break;default: ;}break;case 4 :switch (SamplingFactors[0].Vi){case 1 : ChromaSubsampling="4:1:1"; break;default: ;}break;default: ;}if (!ChromaSubsampling.empty()){if (SamplingFactors.size()==4){if (ChromaSubsampling=="4:4:4" && SamplingFactors[3].Hi==1 && SamplingFactors[3].Vi==1)ChromaSubsampling+=":4";elseChromaSubsampling+=":?";}Fill(StreamKind_Last, 0, "ChromaSubsampling", ChromaSubsampling);}}}FILLING_END();
}

从代码的含义可知,提取出了图像的宽,高,采样方式等信息。

详细的代码暂时没有时间研究了,先这样了。

MediaInfo源代码分析 5:JPEG解析代码分析相关推荐

  1. u-boot分析之两阶段代码分析(三)

    目录 u-boot(三)启动文件 1,概述 2,uboot第一阶段代码分析: 汇编 2,uboot第二阶段代码分析 C:_start_armboot C:main_loop u-boot(三)启动文件 ...

  2. linux pl320 mbox控制器驱动分析-(3) pl320驱动代码分析

    linux pl320 mbox控制器驱动分析-(3)pl320驱动代码分析 1 pl320 mbox控制器宏定义 2 初始化接口 3 ipc_handler mbox中断处理函数 4 数据的收发 4 ...

  3. android 触摸屏驱动分析,Android 触摸屏驱动代码分析(ADC 类型触摸屏 CPU:s3c

    Android 2.1 farsight version for s5pc100 File Name: s3c-ts.c 1           简介 1.1          本例基于s5pc100 ...

  4. TI am335x 内核分析2--资源遍历代码分析

    MPU平台:OAMP3352 内核版本:3.2.0 声明:我讲解的范畴是从内核解压以后经过汇编代码执行最后跳到第一个C代码这个点开始讲解,一直讲到文件系统被正确的挂载起来,用户可以登入!至于之前的汇编 ...

  5. MediaInfo源代码分析 4:Inform()函数

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

  6. MediaInfo源代码分析 3:Open()函数

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

  7. MediaInfo源代码分析 2:API函数

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

  8. MediaInfo源代码分析 1:整体结构

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

  9. vs 2015 C 语言,VS2015中C/C++代码分析

    VS2015中C/C++代码分析 03/31/2015 8 分钟可看完 本文内容 [原文发表时间]:2015/2/24 1:00 PM 来自 Joe Morris & Jim Springfi ...

最新文章

  1. Android常用URI收藏
  2. centos7 安装kubernetes1.4(kubeadm版)
  3. Bellman-Ford
  4. 008PHP文件处理——文件操作r w (用的比较多) a x(用的比较少) 模式 rewind 指针归位:...
  5. 区块链BaaS云服务(21)腾讯CCGP ”跨链协议 AMDP“
  6. FastDFS工具类的使用
  7. Linux学习之系统编程篇:利用管道进行进程间通信
  8. 多少行数_经验丰富的程序员和其每日代码行数
  9. 经常使用计算机的孩子,常玩电脑对孩子负面影响大,家长们不容小觑!
  10. java weka 聚类_简单开源数据挖掘工具weka进行文本聚类
  11. ecshop flow.php goods_number,修复ECSHOP一重要BUG,当商品设置数量优惠时,加入不同属性的商品数量优惠判断错误...
  12. 【STM32】 定时器---正交解码编码器模式详解
  13. 【Linux】shell脚本执行错误 $‘\r‘:command not found
  14. Error creating bean with name ‘fastJsonpResponseBodyAdvice‘ defined in URL xxx
  15. OpenCL将数组从内存copy到显存
  16. jms消息模式和区别_JMS管理对象和JMS消息
  17. 玩转混合云+边缘计算,且看ZStack Mini!
  18. 如何在Mac上轻松使用SVN
  19. 软考高项论文写作技巧
  20. js获取当前Url后面的指定参数

热门文章

  1. C# 面向对象程序设计复习
  2. 最近做了个数据采集的工具
  3. HDU2527 Safe Or Unsafe【哈夫曼编码】
  4. UVA750 UVALive5358 8 Queens Chess Problem题解
  5. Spark utils —— 设置日志级别
  6. Java 高级数据结构 —— Properties
  7. 并发与计算机体系结构
  8. Java Colections 集合类 —— List、ArrayList、Set(HashSet)
  9. 面向对象——类设计(六)——算法类
  10. 前端集合删除对象_【两万字】面试官:听说你精通集合源码,接我二十个问题!...