jpeg解码需要使用哈夫曼表和离散余弦变换
参考网上的一些资料,得到的结果似乎不正确求能正确解码组件为YCrCb的jpeg图片的实用资料
http://bbs.pfan.cn/post-316797.html
http://wenku.baidu.com/view/408f55e49b89680203d8251c.html
以下为使用的文件头:
class MJpegDecode
{
private:
    struct _JFIFAPPOInfo
    {
        BYTE APP0[2];         /* 02h  Application Use Marker    */
        BYTE Length[2];       /* 04h  Length of APP0 Field      */
        BYTE Identifier[5];   /* 06h  "JFIF" (zero terminated) Id String */
        BYTE Version[2];      /* 0Bh  JFIF Format Revision      */
        BYTE Units;           /* 0Dh  Units used for Resolution */
        BYTE Xdensity[2];     /* 0Eh  Horizontal Resolution     */
        BYTE Ydensity[2];     /* 10h  Vertical Resolution       */
        BYTE XThumbnail;      /* 12h  Thumbnail Horizontal Pixel Count    */
        BYTE YThumbnail;      /* 13h  Thumbnail Vertical Pixel Count      */
    } JFIFAPPOINFO;
    struct _JFIFDQTInfo
    {
        BYTE DQT[2];          // 14h  量化表段标记
        BYTE Length[2];       // 16h  量化表段长度
        BYTE Identifier;      // 18h  量化表ID
        BYTE QTData[64];      // 19h  量化表数据
    } JFIFDQTINFO[2];
    struct _JFIFSOFOInfo
    {
        BYTE SOFO[2];                   // 9Eh  帧开始段标记
        BYTE Length[2];                 // A0h  帧开始段长度
        BYTE BitCount;                  // A2h  样本精度bit位数
        BYTE Height[2];                 // A5h  图像像素宽度
        BYTE Width[2];                  // A3h  图像像素高度
        BYTE ComponentsCount;           // A7h  图像组件计数
        BYTE YIdentifier;               // A8h  亮度Y的ID号
        BYTE YHVSamplingCoefficient;    // A9h  亮度Y垂直和水平采样系数
        BYTE YUsedDQTIdentifier;        // AAh  亮度Y使用的量化表ID号
        BYTE CbIdentifier;              // ABh  色度Cb的ID号
        BYTE CbHVSamplingCoefficient;   // ACh  色度Cb垂直和水平采样系数
        BYTE CbUsedDQTIdentifier;       // ADh  色度Cb使用的量化表ID号
        BYTE CrIdentifier;              // AEh  色度Cr的ID号
        BYTE CrHVSamplingCoefficient;   // AFh  色度Cr垂直和水平采样系数
        BYTE CrUsedDQTIdentifier;       // B0h  色度Cr使用的量化表ID号
    } JFIFSOFOINFO;
    struct _JEIFDHTInfo
    {
        BYTE DHT[2];                    // B1h  哈夫曼表定义段标记
        BYTE Length[2];                 // B3h  哈夫曼表段长度
        BYTE HTIdentifier;              // B5h  哈夫曼表号
        BYTE NBitsSymbolsCount[16];     // B6h  (符号的二进制位长度为n)的符号个数
        BYTE SymbolsTable[256];         // C6h  按递增次序代码长度排列的符号表
    } JFIFDHTINFO[4];
    struct _JEIFSOSInfo
    {
        BYTE SOS[2];                    // 261h  扫描开始段标记
        BYTE Length[2];                 // 263h  扫描开始段长度
        BYTE ComponentsCount;           // 265h  扫描行内组件的数量
        BYTE YIdentifier;               // 266h  亮度Y的ID号
        BYTE YHTTableID;                // 267h  亮度Y使用的哈夫曼表ID号
        BYTE CbIdentifier;              // 268h  色度Cb的ID号
        BYTE CbHTTableID;               // 269h  色度Cb使用的哈夫曼表ID号
        BYTE CrIdentifier;              // 26Ah  色度Cr的ID号
        BYTE CrHTTableID;               // 26Bh  色度Cr使用的哈夫曼表ID号
        BYTE Reserved[3];               // 26Ch  3个未知保留字节
    } JFIFSOSINFO;
private:
    struct HuffmanTable
    {
        int CodeOfFirstNLengthSymbol[17];     //长度为N的第一个码字的整数值
        int NLengthToSymbolsTableIndex[16];   //查表得到第一个长度为N的符号位于符号表的索引
    } HUFFMANTABLE[4];
public:
    int ReadJFIFInfo(const BYTE* const jfifData,int jfifDataSize);
    void DecodeData(int mcuStartIndex,BYTE* jfifData,int jfifDataSize,ImageComponentData*& targetBitmapData);
    void SetHuffmanTable();
    void DecodeOneDUDC(MBitReader* myBitReader,double* DU,double& lastDC,int HTID);
    void DecodeOneDUAC(MBitReader* myBitReader,double* DU,int HTID);
    void DecodeOneMCU(MBitReader* myBitReader,int mcuXn,int mcuYn,int mcuWidth,int mcuHeight,double *DU,ImageComponentData* targetImage);
    void InverseQuantization(double* du,BYTE* quantizationTable);
    void InverseZigzag(double* sourceDU,double* targetDU);
    void IDCT(double* sourceDU,double* targetDU);
    void YCrCbToRGB(ImageComponentData* sourceImage,ImageComponentData* targetImage);
public:
    int imageHeight;
    int imageWidth;
    int alignedImageWidth;
    int alignedImageHeight;
    struct HuffmanTableID
    {
        int dc;
        int ac;
    } HTID[3];
    double DC[3];
    int HSamplingCoefficient[3];
    int VSamplingCoefficient[3];
    int DQTID[3];
};