图像转换(jpg to bmo)(bmp to jpg)

本文详细解析了JPEG图像到BMP图像的转换原理,并提供了一个使用VC6.0实现的代码实例,包括从文件读取、内存操作到最终保存为BMP格式的过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

//jpeg转bmp的原理很简单,用ipciture读入jpg图像,然后在成bmp的,由于在vc 6.0里面可以自动存储的格式只有两种:bmp和ico,由此的来

void JpegToBmp(const char *resourcepath,const char *destnatepath)
{
    IPicture *m_picture;
   
    CFile file(resourcepath,CFile::modeRead);
    DWORD m_filelen=file.GetLength();
    HGLOBAL hglobal=GlobalAlloc(GMEM_MOVEABLE,m_filelen);
    LPVOID pdata=NULL;
    pdata=GlobalLock(hglobal);
    file.ReadHuge(pdata,m_filelen);
    IStream *m_stream;
    GlobalUnlock(hglobal);
    file.Close();
   
    CreateStreamOnHGlobal(hglobal,TRUE,&m_stream);
    OleLoadPicture(m_stream,m_filelen,TRUE,IID_IPicture,(LPVOID*)&m_picture); 
     
      LONG   size;  
      m_picture->SaveAsFile(m_stream,TRUE,&size);  
      char   pathbuf[1024];  
      CFile   iconfile;  
      iconfile.Open(destnatepath,CFile::modeCreate|CFile::modeWrite);  
      LARGE_INTEGER li;  
      li.HighPart = 0;  
      li.LowPart = 0;  
      ULARGE_INTEGER ulnewpos;  
      m_stream->Seek(li,STREAM_SEEK_SET,&ulnewpos);  
      ULONG  uReadCount = 1;  
      while(uReadCount>0)  
      {  
            m_stream->Read(pathbuf,sizeof(pathbuf),&uReadCount);  
            if(uReadCount>0)  
                                iconfile.Write(pathbuf,uReadCount);  
      }
   
    GlobalFree(hglobal);
    m_stream->Release();
    m_stream=NULL;
    m_picture->Release();            
}

 

bmp转jpg的麻烦一点儿,因为jpg需要复杂的解压,从网上download了一个,可用主要是通过两个类实现:

  1. // CompressEncode.h: interface for the CCompressEncode class.  
  2. //  
  3. //////////////////////////////////////////////////////////////////////  
  4. #if !defined(AFX_COMPRESSENCODE_H__0EF37988_FDDE_4229_9EF1_CA5B1E51BEFF__INCLUDED_)  
  5. #define AFX_COMPRESSENCODE_H__0EF37988_FDDE_4229_9EF1_CA5B1E51BEFF__INCLUDED_  
  6. #if _MSC_VER > 1000  
  7. #pragma once  
  8. #endif // _MSC_VER > 1000  
  9. typedef struct tag_HUFFMAN_TABLE {   
  10.         unsigned int    code[256];  // code for each symbol    
  11.         char            size[256];  // length of code for each symbol    
  12.         //If no code has been allocated for a symbol S, size[S] is 0    
  13.    
  14.         /* These two fields directly represent the contents of a JPEG DHT marker */   
  15.         unsigned char bits[17];     /* bits[k] = # of symbols with codes of */   
  16.         /* length k bits; bits[0] is unused */   
  17.         unsigned char huffval[256];     /* The symbols, in order of incr code length */   
  18.                                 /* This field is used only during compression.  It's initialized FALSE when  
  19.                                 * the table is created, and set TRUE when it's been output to the file.  
  20.                                 * You could suppress output of a table by setting this to TRUE.  
  21.                                 * (See jpeg_suppress_tables for an example.)*/   
  22. }HUFFMAN_TABLE;   
  23. class CCompressEncode    
  24. {  
  25. public:  
  26.     CCompressEncode();  
  27.     virtual ~CCompressEncode();  
  28.     CCompressEncode( int nQuality );   
  29.     bool CompressImage(    
  30.         unsigned char *pInBuf,  //source data, bgr format, 3 bytes per pixel   
  31.         unsigned char *pOutBuf, //destination buffer, in jpg format   
  32.         int nWidthPix,          //image width in pixels   
  33.         int nHeight,            //height   
  34.         int& nOutputBytes       //return number of bytes being written   
  35.         );   
  36.    
  37.     ////////////////////////////////////////////////////////////////////////////   
  38.     //  Following data members should be computed in initialization   
  39.    
  40.     unsigned short m_nQuality, m_nScale;   
  41.    
  42.     //RGB转化YCbCr颜色对应表   
  43.     int m_RToY[256],    m_GToY[256],    m_BToY[256];   
  44.     int m_RToCb[256],   m_GToCb[256],   m_BToCb[256];   
  45.     int m_RToCr[256],   m_GToCr[256],   m_BToCr[256];   
  46.    
  47.     //  To speed up, we precompute two DCT quant tables   
  48.     unsigned short m_qtblY[64], m_qtblCbCr[64];   
  49.    
  50.     //用来写入JPG文件头   
  51.     unsigned char m_dqtY[64], m_dqtCbCr[64];   
  52.    
  53.     HUFFMAN_TABLE m_htblYDC, m_htblYAC, m_htblCbCrDC, m_htblCbCrAC;   
  54.    
  55.     ////////////////////////////////////////////////////////////////////////////   
  56.        
  57.     ////////////////////////////////////////////////////////////////////////////   
  58.     //  Following are should be initialized for compressing every image   
  59.    
  60.     unsigned short m_nWidth, m_nHeight;   
  61.    
  62.     //  Three dc records, used for dc differentize for Y/Cb/Cr   
  63.     int m_dcY, m_dcCb, m_dcCr;   
  64.    
  65.     //  The size (in bits) and value (in 4 byte buffer) to be written out   
  66.     int m_nPutBits, m_nPutVal;   
  67.    
  68.     unsigned char *m_pOutBuf;   
  69.    
  70.     ////////////////////////////////////////////////////////////////////////////   
  71.    
  72. private:   
  73.    
  74.     void InitEncoder( void );   
  75.        
  76.     void InitColorTable( void );   
  77.    
  78.     void InitQuantTable( void );   
  79.    
  80.     void ScaleQuantTable(   
  81.         unsigned short* tblRst,    
  82.         unsigned char* tblStd,         
  83.         unsigned short* tblAan     
  84.         );   
  85.    
  86.     void ScaleTable(unsigned char* tbl, int scale, int max);   
  87.    
  88.    
  89.     void InitHuffmanTable( void );   
  90.    
  91.     void ComputeHuffmanTable(   
  92.         unsigned char * pBits,    
  93.         unsigned char * pVal,   
  94.         HUFFMAN_TABLE * pTbl       
  95.         );   
  96.    
  97.     bool CompressOneTile(   
  98.         unsigned char * pBgr    //source data, in BGR format       
  99.     );   
  100.    
  101.     void BGRToYCbCr(       
  102.         unsigned char * pBgr,   //tile source data, in BGR format, 768 bytes   
  103.         unsigned char * pY,     //out, Illuminance, 256 bytes   
  104.         unsigned char * pCb,    //out, Cb, 256 bytes   
  105.         unsigned char * pCr     //out, Cr, 256 bytes   
  106.         );   
  107.        
  108.     void BGRToYCbCrEx(     
  109.         unsigned char * pBgr,   //in, tile data, in BGR format, 768 bytes   
  110.         int * pBlock            //out, Y: 256; Cb: 64; Cr: 64    
  111.         );   
  112.        
  113.     void ForwardDct(    
  114.         int* data,  //source data, length is 64    
  115.         int* coef   //output dct coefficients   
  116.         );   
  117.        
  118.     void Quantize(    
  119.         int* coef,  //coef is both in and out   
  120.         int iBlock  //block id; Y: 0,1,2,3; Cb: 4; Cr: 5   
  121.         );   
  122.    
  123.     bool HuffmanEncode(    
  124.         int* pCoef,             //  DCT coefficients   
  125.         int iBlock              //  0,1,2,3:Y; 4:Cb; 5:Cr;   
  126.         );   
  127.    
  128.     bool EmitBits(   
  129.         unsigned int code,      //Huffman code   
  130.         int size                //Size in bits of the Huffman code   
  131.         );   
  132.    
  133.     void EmitLeftBits(void);   
  134.    
  135.     void WriteJpegHeader(void);    
  136.     void write_sos(void);   
  137.     void write_sof(int code);   
  138.     void write_app0(void);   
  139.     void write_soi(void);   
  140.     void write_dht(int IsCbCr, int IsAc);   
  141.     void write_dqt(int index);   
  142.            
  143. };  
  144. #endif // !defined(AFX_COMPRESSENCODE_H__0EF37988_FDDE_4229_9EF1_CA5B1E51BEFF__INCLUDED_)   
  1. #ifndef __PICTUREOPERATE_H__   
  2. #define __PICTUREOPERATE_H__   
  3.    
  4. class PictureOperate   
  5. {   
  6. public:   
  7.     PictureOperate();   
  8.     ~PictureOperate();   
  9.    
  10.     //加载位图   
  11.     BOOL Load( const char * );   
  12.        
  13.    
  14.     //进行编码压缩并且保存文件   
  15.     void picCompressEncode(CString filename, BOOL color, int quality);   
  16.        
  17.        
  18.     UINT m_width, m_height, m_rowbytes;   
  19.    
  20. private:   
  21.     DWORD m_dwDibSize;   
  22.     unsigned char *m_pDib, *m_pDibBits;    
  23.     BITMAPINFOHEADER *m_pBIH;   
  24.        
  25.     CPalette m_Palette;   
  26.     RGBQUAD *m_pPalette;   
  27.     int m_nPaletteEntries;   
  28. };   
  29. #endif  
 
  1. #include "stdafx.h"     
  2. #include "PicOperate.h"      
  3. #include "CompressEncode.h"     
  4. ///////////////////////////////////////////////////////////////////////////////     
  5. //构造函数     
  6. PictureOperate::PictureOperate()     
  7. {     
  8.     m_pDib = NULL;     
  9. }     
  10. //析构函数     
  11. PictureOperate::~PictureOperate()     
  12. {     
  13.     if( m_pDib != NULL )     
  14.         delete [] m_pDib;     
  15. }     
  16. //加载位图     
  17. BOOL PictureOperate::Load( const char *pszFilename )     
  18. {     
  19.      
  20.     CFile cf;     
  21.      
  22.     // Attempt to open the Dib file for reading.     
  23.     if( !cf.Open( pszFilename, CFile::modeRead ) )     
  24.         return( FALSE );     
  25.      
  26.     // Get the size of the file and store     
  27.     // in a local variable. Subtract the     
  28.     // size of the BITMAPFILEHEADER structure     
  29.     // since we won't keep that in memory.     
  30.     DWORD dwDibSize;     
  31.     dwDibSize =     
  32.         cf.GetLength() - sizeof( BITMAPFILEHEADER );     
  33.      
  34.     // Attempt to allocate the Dib memory.     
  35.     unsigned char *pDib;     
  36.     pDib = new unsigned char [dwDibSize];     
  37.     if( pDib == NULL )     
  38.         return( FALSE );     
  39.      
  40.     BITMAPFILEHEADER BFH;     
  41.      
  42.     // Read in the Dib header and data.     
  43.     try{     
  44.      
  45.         // Did we read in the entire BITMAPFILEHEADER?     
  46.         if( cf.Read( &BFH, sizeof( BITMAPFILEHEADER ) )     
  47.             != sizeof( BITMAPFILEHEADER ) ||     
  48.      
  49.             // Is the type 'MB'?     
  50.             BFH.bfType != 'MB' ||     
  51.      
  52.             // Did we read in the remaining data?     
  53.             cf.Read( pDib, dwDibSize ) != dwDibSize ){     
  54.      
  55.             // Delete the memory if we had any     
  56.             // errors and return FALSE.     
  57.             delete [] pDib;     
  58.             return( FALSE );     
  59.             }     
  60.         }     
  61.      
  62.     // If we catch an exception, delete the     
  63.     // exception, the temporary Dib memory,     
  64.     // and return FALSE.     
  65.     catch( CFileException *e ){     
  66.         e->Delete();     
  67.         delete [] pDib;     
  68.         return( FALSE );     
  69.         }     
  70.          
  71.     // If we got to this point, the Dib has been     
  72.     // loaded. If a Dib was already loaded into     
  73.     // this class, we must now delete it.     
  74.     if( m_pDib != NULL )     
  75.         delete m_pDib;     
  76.      
  77.     // Store the local Dib data pointer and     
  78.     // Dib size variables in the class member     
  79.     // variables.     
  80.     m_pDib = pDib;     
  81.     m_dwDibSize = dwDibSize;     
  82.      
  83.     // Pointer our BITMAPINFOHEADER and RGBQUAD     
  84.     // variables to the correct place in the Dib data.     
  85.     m_pBIH = (BITMAPINFOHEADER *) m_pDib;     
  86.     m_pPalette =     
  87.         (RGBQUAD *) &m_pDib[sizeof(BITMAPINFOHEADER)];     
  88.      
  89.     //  get image width and height     
  90.     m_width = m_pBIH->biWidth;     
  91.     m_height = m_pBIH->biHeight;     
  92.      
  93.     // Calculate the number of palette entries.     
  94.     m_nPaletteEntries = 1 << m_pBIH->biBitCount;     
  95.     if( m_pBIH->biBitCount > 8 )     
  96.         m_nPaletteEntries = 0;     
  97.     else if( m_pBIH->biClrUsed != 0 )     
  98.         m_nPaletteEntries = m_pBIH->biClrUsed;     
  99.      
  100.     // Point m_pDibBits to the actual Dib bits data.     
  101.     m_pDibBits =     
  102.         &m_pDib[sizeof(BITMAPINFOHEADER)+     
  103.             m_nPaletteEntries*sizeof(RGBQUAD)];     
  104.      
  105.     // If we have a valid palette, delete it.     
  106.     if( m_Palette.GetSafeHandle() != NULL )     
  107.         m_Palette.DeleteObject();     
  108.      
  109.     // If there are palette entries, we'll need     
  110.     // to create a LOGPALETTE then create the     
  111.     // CPalette palette.     
  112.     if( m_nPaletteEntries != 0 ){     
  113.      
  114.         // Allocate the LOGPALETTE structure.     
  115.         LOGPALETTE *pLogPal = (LOGPALETTE *) new char     
  116.                 [sizeof(LOGPALETTE)+     
  117.                 m_nPaletteEntries*sizeof(PALETTEENTRY)];     
  118.      
  119.         if( pLogPal != NULL ){     
  120.      
  121.             // Set the LOGPALETTE to version 0x300     
  122.             // and store the number of palette     
  123.             // entries.     
  124.             pLogPal->palVersion = 0x300;     
  125.             pLogPal->palNumEntries = m_nPaletteEntries;     
  126.      
  127.             // Store the RGB values into each     
  128.             // PALETTEENTRY element.     
  129.             forint i=0; i<m_nPaletteEntries; i++){  
  130.                 pLogPal->palPalEntry[i].peRed =     
  131.                     m_pPalette[i].rgbRed;     
  132.                 pLogPal->palPalEntry[i].peGreen =     
  133.                     m_pPalette[i].rgbGreen;     
  134.                 pLogPal->palPalEntry[i].peBlue =     
  135.                     m_pPalette[i].rgbBlue;     
  136.                 }     
  137.      
  138.             // Create the CPalette object and     
  139.             // delete the LOGPALETTE memory.     
  140.             m_Palette.CreatePalette( pLogPal );     
  141.             delete [] pLogPal;     
  142.             }     
  143.         }     
  144.          
  145.     return( TRUE );     
  146.      
  147. }     
  148.      
  149.      
  150.      
  151. ///////////////////////////////////////////////////////////////////////////////     
  152. //对位图进行基于DCT的压缩编码,并且保存为JPG文件     
  153. void PictureOperate::picCompressEncode(CString filename, BOOL color, int quality)     
  154. {     
  155.      
  156.     //压缩后的字节数     
  157.     int nOutputBytes = 0;     
  158.      
  159.     unsigned char *pJpg;     
  160.     pJpg = new unsigned char [m_dwDibSize];     
  161.          
  162.     LARGE_INTEGER iLarge;     
  163.     QueryPerformanceFrequency( &iLarge );        
  164.     double dbFreq = (double) iLarge.QuadPart;     
  165.          
  166.     //获得起始时间     
  167.     QueryPerformanceCounter( &iLarge );      
  168.     double dbBegin = (double) iLarge.QuadPart;     
  169.      
  170.     /////////////////////////////////////////////////////     
  171.      
  172.          
  173.     //quality为压缩质量     
  174.     CCompressEncode encoder( quality );     
  175.      
  176.     encoder.CompressImage( m_pDibBits, pJpg,      
  177.         m_pBIH->biWidth, m_pBIH->biHeight, nOutputBytes );     
  178.      
  179.     //////////////////////////////////////////////////////     
  180.      
  181.     //获得压缩结束后时间     
  182.     QueryPerformanceCounter( &iLarge );      
  183.     double dbEnd = (double) iLarge.QuadPart;     
  184.      
  185.     int nms = (int) (( dbEnd - dbBegin ) * 1000.0 / dbFreq );        
  186.              
  187.     float ratio = (float) m_dwDibSize / nOutputBytes;     
  188.     CString str;     
  189.     //输出压缩后信息     
  190.     str.Format( "压缩后字节数 = %d, 压缩比 = %f, 耗时 = %d ",      
  191.                     nOutputBytes, ratio, nms );     
  192.     AfxMessageBox( str );     
  193.          
  194.     //保存JPG文件     
  195.     CFile cf;     
  196.     if( !cf.Open( filename, CFile::modeCreate | CFile::modeWrite ) )     
  197.     {     
  198.         AfxMessageBox("Can not create jpg file!");     
  199.         return;     
  200.     }     
  201.      
  202.     cf.Write( pJpg, nOutputBytes );     
  203.      
  204.     delete []pJpg;     
  205. }   
  1. // CompressEncode.cpp: implementation of the CCompressEncode class.  
  2. //  
  3. //////////////////////////////////////////////////////////////////////  
  4. #include "stdafx.h"  
  5. #include "bmptojpg.h"  
  6. #include "CompressEncode.h"  
  7. #ifdef _DEBUG  
  8. #undef THIS_FILE  
  9. static char THIS_FILE[]=__FILE__;  
  10. #define new DEBUG_NEW  
  11. #endif  
  12. //////////////////////////////////////////////////////////////////////  
  13. // Construction/Destruction  
  14. //////////////////////////////////////////////////////////////////////  
  15. ////////////////////////////////////////////////////////////////////////////////   
  16. //JPEG标志码   
  17. typedef enum {         
  18.   M_SOF0  = 0xc0,   
  19.   M_SOF1  = 0xc1,   
  20.   M_SOF2  = 0xc2,   
  21.   M_SOF3  = 0xc3,   
  22.      
  23.   M_SOF5  = 0xc5,   
  24.   M_SOF6  = 0xc6,   
  25.   M_SOF7  = 0xc7,   
  26.      
  27.   M_JPG   = 0xc8,   
  28.   M_SOF9  = 0xc9,   
  29.   M_SOF10 = 0xca,   
  30.   M_SOF11 = 0xcb,   
  31.      
  32.   M_SOF13 = 0xcd,   
  33.   M_SOF14 = 0xce,   
  34.   M_SOF15 = 0xcf,   
  35.      
  36.   M_DHT   = 0xc4,   
  37.      
  38.   M_DAC   = 0xcc,   
  39.      
  40.   M_RST0  = 0xd0,   
  41.   M_RST1  = 0xd1,   
  42.   M_RST2  = 0xd2,   
  43.   M_RST3  = 0xd3,   
  44.   M_RST4  = 0xd4,   
  45.   M_RST5  = 0xd5,   
  46.   M_RST6  = 0xd6,   
  47.   M_RST7  = 0xd7,   
  48.      
  49.   M_SOI   = 0xd8,   
  50.   M_EOI   = 0xd9,   
  51.   M_SOS   = 0xda,   
  52.   M_DQT   = 0xdb,   
  53.   M_DNL   = 0xdc,   
  54.   M_DRI   = 0xdd,   
  55.   M_DHP   = 0xde,   
  56.   M_EXP   = 0xdf,   
  57.      
  58.   M_APP0  = 0xe0,   
  59.   M_APP1  = 0xe1,   
  60.   M_APP2  = 0xe2,   
  61.   M_APP3  = 0xe3,   
  62.   M_APP4  = 0xe4,   
  63.   M_APP5  = 0xe5,   
  64.   M_APP6  = 0xe6,   
  65.   M_APP7  = 0xe7,   
  66.   M_APP8  = 0xe8,   
  67.   M_APP9  = 0xe9,   
  68.   M_APP10 = 0xea,   
  69.   M_APP11 = 0xeb,   
  70.   M_APP12 = 0xec,   
  71.   M_APP13 = 0xed,   
  72.   M_APP14 = 0xee,   
  73.   M_APP15 = 0xef,   
  74.      
  75.   M_JPG0  = 0xf0,   
  76.   M_JPG13 = 0xfd,   
  77.   M_COM   = 0xfe,   
  78.      
  79.   M_TEM   = 0x01,   
  80.      
  81.   M_ERROR = 0x100   
  82. } JPEG_MARKER;   
  83.    
  84. //Z字型扫描数组      
  85.     static const int jpeg_natural_order[64+16] = {   
  86.             0,  1,  8, 16,  9,  2,  3, 10,   
  87.             17, 24, 32, 25, 18, 11,  4,  5,   
  88.             12, 19, 26, 33, 40, 48, 41, 34,   
  89.             27, 20, 13,  6,  7, 14, 21, 28,   
  90.             35, 42, 49, 56, 57, 50, 43, 36,   
  91.             29, 22, 15, 23, 30, 37, 44, 51,   
  92.             58, 59, 52, 45, 38, 31, 39, 46,   
  93.             53, 60, 61, 54, 47, 55, 62, 63,   
  94.             63, 63, 63, 63, 63, 63, 63, 63,//extra entries for safety   
  95.             63, 63, 63, 63, 63, 63, 63, 63   
  96.     };   
  97.    
  98.    
  99.        
  100.        
  101.     unsigned char std_luminance_quant_tbl[64] =    
  102.     {   
  103.             16,  11,  10,  16,  24,  40,  51,  61,   
  104.             12,  12,  14,  19,  26,  58,  60,  55,   
  105.             14,  13,  16,  24,  40,  57,  69,  56,   
  106.             14,  17,  22,  29,  51,  87,  80,  62,   
  107.             18,  22,  37,  56,  68, 109, 103,  77,   
  108.             24,  35,  55,  64,  81, 104, 113,  92,   
  109.             49,  64,  78,  87, 103, 121, 120, 101,   
  110.             72,  92,  95,  98, 112, 100, 103,  99   
  111.     };   
  112.     unsigned char std_chrominance_quant_tbl[64] =    
  113.     {   
  114.             17,  18,  24,  47,  99,  99,  99,  99,   
  115.             18,  21,  26,  66,  99,  99,  99,  99,   
  116.             24,  26,  56,  99,  99,  99,  99,  99,   
  117.             47,  66,  99,  99,  99,  99,  99,  99,   
  118.             99,  99,  99,  99,  99,  99,  99,  99,   
  119.             99,  99,  99,  99,  99,  99,  99,  99,   
  120.             99,  99,  99,  99,  99,  99,  99,  99,   
  121.             99,  99,  99,  99,  99,  99,  99,  99   
  122.     };   
  123.    
  124.    
  125.    
  126.    
  127.    
  128. ////////////////////////////////////////////////////////////////////////////////   
  129.    
  130. #define emit_byte(val)  *m_pOutBuf++=(unsigned char)(val);     
  131.       
  132. #define emit_2bytes(val)            *m_pOutBuf=(unsigned char)(((val)>>8)&0xFF);  *(m_pOutBuf+1)=(unsigned char)((val)&0xFF);  m_pOutBuf+=2;     
  133.       
  134. #define emit_marker(val)            *m_pOutBuf=0xFF;   *(m_pOutBuf+1)=(unsigned char)(val);   m_pOutBuf+=2;     
  135.        
  136. //////////////////////////////////////////////////////////////////////  
  137. CCompressEncode::CCompressEncode()  
  138. {  
  139.     m_nQuality = 50;   
  140.     InitEncoder( );    
  141. }  
  142. CCompressEncode::CCompressEncode(int nQuality)  
  143. {  
  144.     m_nQuality = nQuality;   
  145.     InitEncoder( );    
  146. }  
  147. CCompressEncode::~CCompressEncode()  
  148. {  
  149. }  
  150. //////////////////////////////////////////////////////////////////////////  
  151. //初始化颜色转化表、量化表、Huffman表   
  152. void CCompressEncode::InitEncoder( )   
  153. {   
  154.        
  155.     InitColorTable( );   
  156.    
  157.    
  158.     InitQuantTable( );   
  159.    
  160.        
  161.     InitHuffmanTable( );   
  162. }   
  163.    
  164.    
  165. ////////////////////////////////////////////////////////////////////////////////   
  166.    
  167. //从RGB转换成YCbCr   
  168. /*  
  169.    
  170.  *  Y  =  0.29900 * R + 0.58700 * G + 0.11400 * B  
  171.  *  Cb = -0.16874 * R - 0.33126 * G + 0.50000 * B  + 128  
  172.  *  Cr =  0.50000 * R - 0.41869 * G - 0.08131 * B  + 128  
  173.    
  174.  */   
  175. void CCompressEncode::InitColorTable( void )   
  176. {   
  177.     int i;   
  178.     int nScale  = 1L << 16;          
  179.     int CBCR_OFFSET = 128<<16;   
  180.        
  181.     int nHalf = nScale >> 1;     
  182.    
  183.     for( i=0; i<256; i++ )   
  184.     {   
  185.         m_RToY[ i ] = (int)( 0.29900 * nScale + 0.5 ) * i;   
  186.         m_GToY[ i ] = (int)( 0.58700 * nScale + 0.5 ) * i;   
  187.         m_BToY[ i ] = (int)( 0.11400 * nScale + 0.5 ) * i + nHalf;   
  188.    
  189.         m_RToCb[ i ] = (int)( 0.16874 * nScale + 0.5 ) * (-i);   
  190.         m_GToCb[ i ] = (int)( 0.33126 * nScale + 0.5 ) * (-i);   
  191.         m_BToCb[ i ] = (int)( 0.50000 * nScale + 0.5 ) * i +    
  192.                                         CBCR_OFFSET + nHalf - 1;   
  193.    
  194.         m_RToCr[ i ] = m_BToCb[ i ];   
  195.         m_GToCr[ i ] = (int)( 0.41869 * nScale + 0.5 ) * (-i);   
  196.         m_BToCr[ i ] = (int)( 0.08131 * nScale + 0.5 ) * (-i);   
  197.     }   
  198. }   
  199.    
  200.    
  201. ////////////////////////////////////////////////////////////////////////////////   
  202. //初始化量化表   
  203. //m_tblYQuant[0..63] 和m_tblCbCrQuant[0..63]   
  204.    
  205. void CCompressEncode::InitQuantTable( void )   
  206. {   
  207.        
  208.     static unsigned short aanscales[64] = {   
  209.                
  210.             16384, 22725, 21407, 19266, 16384, 12873,  8867,  4520,   
  211.             22725, 31521, 29692, 26722, 22725, 17855, 12299,  6270,   
  212.             21407, 29692, 27969, 25172, 21407, 16819, 11585,  5906,   
  213.             19266, 26722, 25172, 22654, 19266, 15137, 10426,  5315,   
  214.             16384, 22725, 21407, 19266, 16384, 12873,  8867,  4520,   
  215.             12873, 17855, 16819, 15137, 12873, 10114,  6967,  3552,   
  216.              8867, 12299, 11585, 10426,  8867,  6967,  4799,  2446,   
  217.              4520,  6270,  5906,  5315,  4520,  3552,  2446,  1247   
  218.     };   
  219.        
  220.        
  221.     m_nScale = m_nQuality;   
  222.    
  223.     if (m_nScale <= 0)    
  224.         m_nScale = 1;   
  225.     if (m_nScale > 100)    
  226.         m_nScale = 100;   
  227.        
  228.        
  229.     if (m_nScale < 50)   
  230.         m_nScale = 5000 / m_nScale;   
  231.     else   
  232.         m_nScale = 200 - m_nScale*2;   
  233.    
  234.        
  235.     memcpy( m_dqtY,     std_luminance_quant_tbl,    64 );   
  236.     memcpy( m_dqtCbCr,  std_chrominance_quant_tbl,  64 );   
  237.    
  238.        
  239.     ScaleTable( m_dqtY,     m_nScale, 100 );   
  240.     ScaleTable( m_dqtCbCr,  m_nScale, 100 );           
  241.    
  242.    
  243.     ScaleQuantTable( m_qtblY,    &std_luminance_quant_tbl[0],   aanscales );   
  244.     ScaleQuantTable( m_qtblCbCr, &std_chrominance_quant_tbl[0], aanscales );   
  245. }   
  246.    
  247. ////////////////////////////////////////////////////////////////////////////////   
  248. void CCompressEncode::ScaleTable(unsigned char* tbl, int scale, int max)   
  249. {   
  250.     int i, temp, half = max/2;   
  251.    
  252.     for (i = 0; i < 64; i++)    
  253.     {   
  254.            
  255.         temp = (int)(( m_nScale * tbl[i] + half ) / max );   
  256.    
  257.            
  258.         if (temp <= 0)   
  259.             temp = 1;   
  260.         if (temp > 255)   
  261.             temp = 255;   
  262.    
  263.            
  264.         tbl[i] = (unsigned char)temp;   
  265.     }   
  266. }   
  267.    
  268.    
  269. ////////////////////////////////////////////////////////////////////////////////   
  270.    
  271. void CCompressEncode::ScaleQuantTable(   
  272.             unsigned short* tblRst,        
  273.             unsigned char* tblStd,         
  274.             unsigned short* tblAan         
  275.             )   
  276. {   
  277.     int i, temp, half = 1<<10;   
  278.     for (i = 0; i < 64; i++)    
  279.     {   
  280.            
  281.         temp = (int)(( m_nScale * tblStd[i] + 50 ) / 100 );   
  282.    
  283.            
  284.         if (temp <= 0)    
  285.             temp = 1;   
  286.         if (temp > 255)   
  287.             temp = 255;        
  288.    
  289.            
  290.         tblRst[i] = (unsigned short)(( temp * tblAan[i] + half )>>11 );   
  291.     }   
  292. }   
  293.    
  294.    
  295. ////////////////////////////////////////////////////////////////////////////////   
  296. //初始化Huffman表:   
  297. //      HUFFMAN_TABLE m_htblYDC, m_htblYAC, m_htblCbCrDC, m_htblCbCrAC;   
  298.    
  299. void CCompressEncode::InitHuffmanTable( void )   
  300. {   
  301.     //  Y dc系数   
  302.     static unsigned char bitsYDC[17] =   
  303.     { 0, 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 };   
  304.     static unsigned char valYDC[] =   
  305.     { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };   
  306.        
  307.    
  308.     //  CbCr dc   
  309.     static unsigned char bitsCbCrDC[17] =   
  310.     { 0, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 };   
  311.     static unsigned char valCbCrDC[] =   
  312.     { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };   
  313.        
  314.    
  315.     //  Y ac系数   
  316.     static unsigned char bitsYAC[17] =   
  317.     { 0, 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d };   
  318.     static unsigned char valYAC[] =   
  319.     { 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12,   
  320.     0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,   
  321.     0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08,   
  322.     0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0,   
  323.     0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16,   
  324.     0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,   
  325.     0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,   
  326.     0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,   
  327.     0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,   
  328.     0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,   
  329.     0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,   
  330.     0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,   
  331.     0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,   
  332.     0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,   
  333.     0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,   
  334.     0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,   
  335.     0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4,   
  336.     0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,   
  337.     0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,   
  338.     0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,   
  339.     0xf9, 0xfa };   
  340.        
  341.    
  342.     //  CbCr ac   
  343.     static unsigned char bitsCbCrAC[17] =   
  344.     { 0, 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 0x77 };   
  345.     static unsigned char valCbCrAC[] =   
  346.     { 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21,   
  347.     0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,   
  348.     0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,   
  349.     0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0,   
  350.     0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34,   
  351.     0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26,   
  352.     0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38,   
  353.     0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,   
  354.     0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,   
  355.     0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,   
  356.     0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,   
  357.     0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,   
  358.     0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96,   
  359.     0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5,   
  360.     0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4,   
  361.     0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3,   
  362.     0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2,   
  363.     0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda,   
  364.     0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,   
  365.     0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,   
  366.     0xf9, 0xfa };   
  367.    
  368.     //  计算生成Huffman表   
  369.     ComputeHuffmanTable( bitsYDC, valYDC, &m_htblYDC );   
  370.     ComputeHuffmanTable( bitsYAC, valYAC, &m_htblYAC );   
  371.    
  372.     ComputeHuffmanTable( bitsCbCrDC, valCbCrDC, &m_htblCbCrDC );   
  373.     ComputeHuffmanTable( bitsCbCrAC, valCbCrAC, &m_htblCbCrAC );   
  374. }   
  375.    
  376. ////////////////////////////////////////////////////////////////////////////////   
  377.    
  378. //  计算生成Huffman表   
  379. void CCompressEncode::ComputeHuffmanTable(   
  380.         unsigned char * pBits,    
  381.         unsigned char * pVal,   
  382.         HUFFMAN_TABLE * pTbl    )   
  383. {   
  384.     int p, i, l, lastp, si;   
  385.     char huffsize[257];   
  386.     unsigned int huffcode[257];   
  387.     unsigned int code;   
  388.    
  389.     // First we copy bits and huffval   
  390.     memcpy( pTbl->bits,      pBits,  sizeof(pTbl->bits) );   
  391.     memcpy( pTbl->huffval,  pVal,    sizeof(pTbl->huffval) );   
  392.        
  393.     /* Figure C.1: make table of Huffman code length for each symbol */   
  394.     /* Note that this is in code-length order. */   
  395.        
  396.     p = 0;   
  397.     for (l = 1; l <= 16; l++) {   
  398.         for (i = 1; i <= (int) pBits[l]; i++)   
  399.             huffsize[p++] = (char) l;   
  400.     }   
  401.     huffsize[p] = 0;   
  402.     lastp = p;   
  403.        
  404.     /* Figure C.2: generate the codes themselves */   
  405.     /* Note that this is in code-length order. */   
  406.        
  407.     code = 0;   
  408.     si = huffsize[0];   
  409.     p = 0;   
  410.     while (huffsize[p]) {   
  411.         while (((int) huffsize[p]) == si) {   
  412.             huffcode[p++] = code;   
  413.             code++;   
  414.         }   
  415.         code <<= 1;   
  416.         si++;   
  417.     }   
  418.        
  419.     /* Figure C.3: generate encoding tables */   
  420.     /* These are code and size indexed by symbol value */   
  421.        
  422.     /* Set any codeless symbols to have code length 0;  
  423.     * this allows EmitBits to detect any attempt to emit such symbols.  
  424.     */   
  425.     memset( pTbl->size, 0, sizeof( pTbl->size ) );   
  426.        
  427.     for (p = 0; p < lastp; p++) {   
  428.         pTbl->code[ pVal[p] ] = huffcode[p];   
  429.         pTbl->size[ pVal[p] ] = huffsize[p];   
  430.     }   
  431. }   
  432.    
  433. ///////////////////////////////////////////////////////////////////////////////   
  434.    
  435. //写入JPG头,soi, app0, Y_dqt, CbCr_dqt, sof, 4 * dht, sos.   
  436. void CCompressEncode::WriteJpegHeader(void)   
  437. {   
  438.     write_soi();   
  439.    
  440.     write_app0();   
  441.    
  442.     write_dqt(0);//Y   
  443.    
  444.     write_dqt(1);//cbcr   
  445.    
  446.     write_sof(M_SOF0);   
  447.    
  448.     write_dht(0, 0);//m_htblYDC   
  449.     write_dht(0, 1);//m_htblYAC   
  450.     write_dht(1, 0);//m_htblCbCrDC   
  451.     write_dht(1, 1);//m_htblCbCrAC   
  452.    
  453.     write_sos();   
  454. }   
  455.    
  456. ///////////////////////////////////////////////////////////////////////////////   
  457.    
  458. void CCompressEncode::write_soi()   
  459. {   
  460.     emit_marker(M_SOI);   
  461. }   
  462.    
  463. void CCompressEncode::write_app0()   
  464. {   
  465.      
  466.      
  467.   emit_marker(M_APP0);   
  468.      
  469.   emit_2bytes(2 + 4 + 1 + 2 + 1 + 2 + 2 + 1 + 1); /* length */   
  470.    
  471.   emit_byte(0x4A);  /* Identifier: ASCII "JFIF" */   
  472.   emit_byte(0x46);   
  473.   emit_byte(0x49);   
  474.   emit_byte(0x46);   
  475.   emit_byte(0);   
  476.    
  477.      
  478.   emit_byte(1);     /* Major version */   
  479.   emit_byte(1);     /* Minor version */   
  480.   emit_byte(1); /* Pixel size information */   
  481.   emit_2bytes(300);   
  482.   emit_2bytes(300);   
  483.   emit_byte(0);     /* No thumbnail image */   
  484.   emit_byte(0);   
  485. }   
  486.    
  487. void CCompressEncode::write_dqt(int index)//0:Y;1:CbCr   
  488. {   
  489.     unsigned char* dqt;   
  490.     if( index == 0 )   
  491.         dqt = &m_dqtY[0];//changed from std with quality   
  492.     else   
  493.         dqt = &m_dqtCbCr[0];   
  494.    
  495.     //only allow prec = 0;   
  496.    
  497.     emit_marker(M_DQT);   
  498.     emit_2bytes(67);//length   
  499.     emit_byte(index);   
  500.    
  501.     int i;   
  502.     unsigned char qval;   
  503.     for (i = 0; i < 64; i++)    
  504.     {   
  505.         qval = (unsigned char) (dqt[jpeg_natural_order[i]]);   
  506.         emit_byte(qval);   
  507.     }   
  508. }   
  509.    
  510.    
  511. //currently support M_SOF0 baseline implementation   
  512. void CCompressEncode::write_sof(int code)   
  513. {   
  514.     emit_marker(code);   
  515.     emit_2bytes(17); //length   
  516.    
  517.     emit_byte(8);//cinfo->data_precision);   
  518.     emit_2bytes(m_nHeight);   
  519.     emit_2bytes(m_nWidth);   
  520.     emit_byte(3);//cinfo->num_components);   
  521.    
  522.     //for Y   
  523.     emit_byte(1);//compptr->component_id);   
  524.     emit_byte(34);//(compptr->h_samp_factor << 4) + compptr->v_samp_factor);   
  525.     emit_byte(0);//quant_tbl_no   
  526.    
  527.     //for Cb   
  528.     emit_byte(2);//compptr->component_id);   
  529.     emit_byte(17);//(compptr->h_samp_factor << 4) + compptr->v_samp_factor);   
  530.     emit_byte(1);//quant_tbl_no   
  531.    
  532.     //for Cr   
  533.     emit_byte(3);//compptr->component_id);   
  534.     emit_byte(17);//(compptr->h_samp_factor << 4) + compptr->v_samp_factor);   
  535.     emit_byte(1);//quant_tbl_no   
  536. }   
  537.    
  538. void CCompressEncode::write_dht(int IsCbCr, int IsAc)   
  539. {   
  540.     HUFFMAN_TABLE *htbl;   
  541.     int index;   
  542.     if( IsCbCr )   
  543.     {   
  544.         if( IsAc )   
  545.         {   
  546.             htbl = &m_htblCbCrAC;   
  547.             index = 17;   
  548.         }   
  549.         else   
  550.         {   
  551.             htbl = &m_htblCbCrDC;   
  552.             index = 1;   
  553.         }   
  554.     }   
  555.     else   
  556.     {   
  557.         if( IsAc )   
  558.         {   
  559.             htbl = &m_htblYAC;   
  560.             index = 16;   
  561.         }   
  562.         else   
  563.         {   
  564.             htbl = &m_htblYDC;   
  565.             index = 0;   
  566.         }   
  567.     }   
  568.    
  569.     emit_marker(M_DHT);   
  570.    
  571.     int i, length = 0;   
  572.     for (i = 1; i <= 16; i++)   
  573.         length += htbl->bits[i];   
  574.        
  575.     emit_2bytes(length + 2 + 1 + 16);   
  576.        
  577.     emit_byte(index);   
  578.    
  579.     for (i = 1; i <= 16; i++)   
  580.         emit_byte(htbl->bits[i]);   
  581.        
  582.     for (i = 0; i < length; i++)//varible-length   
  583.         emit_byte(htbl->huffval[i]);       
  584. }   
  585.    
  586. void CCompressEncode::write_sos()   
  587. {   
  588.     emit_marker(M_SOS);   
  589.    
  590.     int length = 2 * 3 + 2 + 1 + 3;   
  591.     emit_2bytes(length);   
  592.    
  593.     emit_byte(3);//cinfo->comps_in_scan   
  594.    
  595.     //Y   
  596.     emit_byte(1);//index   
  597.     emit_byte(0);//dc and ac tbl use 0-th tbl   
  598.    
  599.     //Cb   
  600.     emit_byte(2);//index   
  601.     emit_byte(0x11);//dc and ac tbl use 1-th tbl   
  602.    
  603.     //Cr   
  604.     emit_byte(3);//index   
  605.     emit_byte(0x11);//dc and ac tbl use 1-th tbl   
  606.    
  607.     emit_byte(0);//Ss   
  608.     emit_byte(0x3F);//Se   
  609.     emit_byte(0);//  Ah/Al   
  610. }   
  611. ////////////////////////////////////////////////////////////////////////////////   
  612.    
  613.    
  614.    
  615.    
  616. ////////////////////////////////////////////////////////////////////////////////   
  617. //对图像进行压缩编码的主函数   
  618. bool CCompressEncode::CompressImage(       
  619.      unsigned char *pInBuf, //源数据   
  620.      unsigned char *pOutBuf,//目标数据   
  621.      int nWidthPix,         //图像宽   
  622.      int nHeight,           //图像高   
  623.      int& nOutputBytes      //转化后字节数   
  624.      )   
  625. {   
  626.     //  错误处理   
  627.     if(( pInBuf == 0 )||( pOutBuf == 0 ))   
  628.         return false;   
  629.    
  630.     m_nWidth = nWidthPix;   
  631.     m_nHeight = nHeight;   
  632.     m_pOutBuf = pOutBuf;   
  633.    
  634.     //写入JPG头   
  635.     WriteJpegHeader();   
  636.    
  637.        
  638.     int nHeadBytes = m_pOutBuf - pOutBuf;   
  639.    
  640.        
  641.     int nRowBytes = ( m_nWidth * 3 + 3 ) / 4 * 4;          
  642.    
  643.     //异常   
  644.     if(( nWidthPix <= 0 )||( nRowBytes <= 0 )||( nHeight <= 0 ))   
  645.         return false;   
  646.    
  647.        
  648.     int xPixel, yPixel, xTile, yTile, cxTile, cyTile, cxBlock, cyBlock;   
  649.     int x, y, nTrueRows, nTrueCols, nTileBytes;   
  650.     unsigned char byTile[768], *pTileRow, *pLastPixel, *pHolePixel;   
  651.            
  652.     //  水平和垂直MCU的数量    
  653.     //  MCU(Minimum Coded Unit), 16*16 象素   
  654.     cxTile = (nWidthPix + 15)>> 4;       
  655.     cyTile = (nHeight + 15) >> 4;   
  656.    
  657.     //  水平和垂直块的数量 8*8 象素   
  658.     cxBlock = cxTile << 1;   
  659.     cyBlock = cyTile << 1;   
  660.    
  661.    
  662.     //初始化   
  663.     nTileBytes = 0;   
  664.    
  665.    
  666.     m_dcY = m_dcCb = m_dcCr = 0;   
  667.    
  668.    
  669.     m_nPutBits = 0;   
  670.     m_nPutVal = 0;   
  671.    
  672.     //循环对每个MCU进行处理   
  673.        
  674.     for( yTile = 0; yTile < cyTile; yTile++ )   
  675.     {   
  676.         for( xTile = 0; xTile < cxTile; xTile++ )   
  677.         {   
  678.             //获得此MCU初始相似   
  679.             xPixel = xTile << 4;   
  680.             yPixel = yTile << 4;   
  681.    
  682.             //  获得列和栏数   
  683.             nTrueRows = 16;   
  684.             nTrueCols = 16;            
  685.             if( yPixel + nTrueRows > nHeight )   
  686.                 nTrueRows = nHeight - yPixel;   
  687.             if( xPixel + nTrueCols > nWidthPix )   
  688.                 nTrueCols = nWidthPix - xPixel;   
  689.    
  690.                
  691.             pTileRow = pInBuf + (m_nHeight - yPixel) * nRowBytes + xPixel * 3;   
  692.    
  693.             //获得数据   
  694.             for( y = 0; y < 16; y ++ )   
  695.             {   
  696.                 if( y < nTrueRows )   
  697.                 {      
  698.                        
  699.                     pTileRow -= nRowBytes;                     
  700.                     memcpy( byTile + y * 16 * 3, pTileRow, nTrueCols * 3 );   
  701.                        
  702.                        
  703.                     if( nTrueCols < 16 )   
  704.                     {   
  705.                         pLastPixel = pTileRow + (nTrueCols - 1) * 3;   
  706.                         pHolePixel = byTile + y * 16 * 3 + nTrueCols * 3;   
  707.                         for( x = nTrueCols; x < 16; x ++ )   
  708.                         {   
  709.                             memcpy( pHolePixel, pLastPixel, 3 );   
  710.                             pHolePixel += 3;   
  711.                         }   
  712.                     }   
  713.                 }   
  714.                 else   
  715.                 {   
  716.                        
  717.                     memcpy( byTile + y * 16 * 3,    
  718.                             byTile + (nTrueRows - 1) * 16 * 3,   
  719.                             16 * 3 );   
  720.                 }   
  721.             }   
  722.            
  723.             //调用函数对此MCU进行压缩编码   
  724.             if( ! CompressOneTile(  byTile ))   
  725.                 return false;              
  726.         }   
  727.     }   
  728.        
  729.     //处理剩余部分   
  730.     if( m_nPutBits > 0 )   
  731.     {   
  732.         EmitLeftBits( );   
  733.     }   
  734.    
  735.     //写入结束标志   
  736.     emit_marker(M_EOI);   
  737.     nOutputBytes = m_pOutBuf - pOutBuf;   
  738.     return true;   
  739. }   
  740.    
  741. ////////////////////////////////////////////////////////////////////////////////   
  742. //  对一个16*16象素的块进行基于DCT的压缩编码   
  743.    
  744. bool CCompressEncode::CompressOneTile(     
  745.     unsigned char * pBgr       
  746.     )   
  747. {   
  748.     //  三个颜色部分    
  749.     int pYCbCr[384];   
  750.    
  751.     //  DCT变换输出   
  752.     int coef[64];      
  753.    
  754.     //  颜色转换   
  755.     BGRToYCbCrEx( pBgr, pYCbCr );   
  756.    
  757.     //  分别对Y/Cb/Cr几个部分进行压缩编码 Y: 4 blocks; Cb: 1 block; Cr: 1 block   
  758.     int i;   
  759.     for( i=0; i<6; i++ )   
  760.     {   
  761.         ForwardDct( pYCbCr + i*64, coef );   
  762.            
  763.         Quantize( coef, i );       
  764.            
  765.         HuffmanEncode( coef, i );      
  766.     }   
  767.    
  768.     return true;   
  769. }   
  770.    
  771.    
  772. ////////////////////////////////////////////////////////////////////////////////   
  773. //  颜色转换   
  774. void CCompressEncode::BGRToYCbCr(      
  775.         unsigned char * pBgr,   //tile source data, in BGR format, 768 bytes   
  776.         unsigned char * pY,     //out, Illuminance, 256 bytes   
  777.         unsigned char * pCb,    //out, Cb, 256 bytes   
  778.         unsigned char * pCr     //out, Cr, 256 bytes   
  779.         )   
  780. {   
  781.     int i;   
  782.     unsigned char r, g, b, *pByte = pBgr, *py = pY, *pcb = pCb, *pcr = pCr;   
  783.    
  784.     for( i=0; i<256; i++ )   
  785.     {   
  786.         b = *(pByte ++);   
  787.         g = *(pByte ++);   
  788.         r = *(pByte ++);   
  789.    
  790.         *(py++)  = (unsigned char)((m_RToY[r]  + m_GToY[g]  + m_BToY[b] )>>16);   
  791.         *(pcb++) = (unsigned char)((m_RToCb[r] + m_GToCb[g] + m_BToCb[b])>>16);   
  792.         *(pcr++) = (unsigned char)((m_RToCr[r] + m_GToCr[g] + m_BToCr[b])>>16);   
  793.     }   
  794. }   
  795.    
  796. ////////////////////////////////////////////////////////////////////////////////   
  797.    
  798. void CCompressEncode::BGRToYCbCrEx(    
  799.         unsigned char * pBgr,   //in, tile data, in BGR format, 768 bytes   
  800.         int * pBlock    //out, Y: 256; Cb: 64; Cr: 64    
  801.         )   
  802. {   
  803.     int x, y, *py[4], *pcb, *pcr;   
  804.     unsigned char r, g, b, *pByte;   
  805.    
  806.     pByte = pBgr;   
  807.     for( x = 0; x < 4; x++ )   
  808.         py[ x ] = pBlock + 64 * x;   
  809.     pcb   = pBlock + 256;   
  810.     pcr   = pBlock + 320;   
  811.        
  812.     for( y=0; y<16; y++ )   
  813.     {   
  814.         for( x=0; x<16; x++ )   
  815.         {   
  816.             b = *(pByte ++);   
  817.             g = *(pByte ++);   
  818.             r = *(pByte ++);   
  819.                
  820.             //  block number is ((y/8) * 2 + x/8): 0, 1, 2, 3   
  821.             *( py[((y>>3)<<1) + (x>>3)] ++ ) =    
  822.                 ((m_RToY[ r ]  + m_GToY[ g ]  + m_BToY[ b ] )>>16) -128;     
  823.                
  824.             //  Equal to: (( x%2 == 0 )&&( y%2 == 0 ))   
  825.             if( (!(y & 1L)) && (!(x & 1L)) )   
  826.             {   
  827.                 *(pcb++) =    
  828.                     ((m_RToCb[ r ] + m_GToCb[ g ] + m_BToCb[ b ])>>16) -128;   
  829.                 *(pcr++) =    
  830.                     ((m_RToCr[ r ] + m_GToCr[ g ] + m_BToCr[ b ])>>16) -128;   
  831.             }   
  832.         }   
  833.     }   
  834. }   
  835.    
  836. ////////////////////////////////////////////////////////////////////////////////   
  837.    
  838. //离散余弦正变换   
  839. void CCompressEncode::ForwardDct(    
  840.         int* data,  //source data, length is 64    
  841.         int* coef   //output dct coefficients   
  842.         )   
  843. {   
  844.    
  845. ////////////////////////////////////////////////////////////////////////////   
  846. //为了方便计算定义几个宏   
  847. #define FIX_0_382683433  ((int)98)      /* FIX(0.382683433) */   
  848. #define FIX_0_541196100  ((int)139)     /* FIX(0.541196100) */   
  849. #define FIX_0_707106781  ((int)181)     /* FIX(0.707106781) */   
  850. #define FIX_1_306562965  ((int)334)     /* FIX(1.306562965) */   
  851.        
  852.    
  853. #define MULTIPLY(var,cons)  (int)(((cons) * (var)) >> 8 )   
  854.    
  855. ////////////////////////////////////////////////////////////////////////////   
  856.    
  857.     static const int DCTSIZE = 8;   
  858.     int x, y;   
  859.     int *dataptr;   
  860.     int tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;   
  861.     int tmp10, tmp11, tmp12, tmp13;   
  862.     int z1, z2, z3, z4, z5, z11, z13, *coefptr;   
  863.        
  864.     /* Pass 1: process rows. */   
  865.        
  866.     dataptr = data;     //input   
  867.     coefptr = coef;     //output       
  868.     for( y = 0; y < 8; y++ )    
  869.     {   
  870.         tmp0 = dataptr[0] + dataptr[7];   
  871.         tmp7 = dataptr[0] - dataptr[7];   
  872.         tmp1 = dataptr[1] + dataptr[6];   
  873.         tmp6 = dataptr[1] - dataptr[6];   
  874.         tmp2 = dataptr[2] + dataptr[5];   
  875.         tmp5 = dataptr[2] - dataptr[5];   
  876.         tmp3 = dataptr[3] + dataptr[4];   
  877.         tmp4 = dataptr[3] - dataptr[4];   
  878.            
  879.         /* Even part */   
  880.            
  881.         tmp10 = tmp0 + tmp3;    /* phase 2 */   
  882.         tmp13 = tmp0 - tmp3;   
  883.         tmp11 = tmp1 + tmp2;   
  884.         tmp12 = tmp1 - tmp2;   
  885.            
  886.         coefptr[0] = tmp10 + tmp11; /* phase 3 */   
  887.         coefptr[4] = tmp10 - tmp11;   
  888.            
  889.         z1 = MULTIPLY(tmp12 + tmp13, FIX_0_707106781); /* c4 */   
  890.         coefptr[2] = tmp13 + z1;    /* phase 5 */   
  891.         coefptr[6] = tmp13 - z1;   
  892.            
  893.         /* Odd part */   
  894.            
  895.         tmp10 = tmp4 + tmp5;    /* phase 2 */   
  896.         tmp11 = tmp5 + tmp6;   
  897.         tmp12 = tmp6 + tmp7;   
  898.            
  899.         /* The rotator is modified from fig 4-8 to avoid extra negations. */   
  900.         z5 = MULTIPLY(tmp10 - tmp12, FIX_0_382683433);  /* c6 */   
  901.         z2 = MULTIPLY(tmp10, FIX_0_541196100) + z5;     /* c2-c6 */   
  902.         z4 = MULTIPLY(tmp12, FIX_1_306562965) + z5;     /* c2+c6 */   
  903.         z3 = MULTIPLY(tmp11, FIX_0_707106781);          /* c4 */   
  904.            
  905.         z11 = tmp7 + z3;        /* phase 5 */   
  906.         z13 = tmp7 - z3;   
  907.            
  908.         coefptr[5] = z13 + z2;  /* phase 6 */   
  909.         coefptr[3] = z13 - z2;   
  910.         coefptr[1] = z11 + z4;   
  911.         coefptr[7] = z11 - z4;   
  912.            
  913.         dataptr += 8;       /* advance pointer to next row */   
  914.         coefptr += 8;   
  915.     }   
  916.        
  917.     /* Pass 2: process columns. */     
  918.    
  919.     coefptr = coef;     //both input and output   
  920.     for ( x = 0; x < 8; x++ )    
  921.     {   
  922.         tmp0 = coefptr[DCTSIZE*0] + coefptr[DCTSIZE*7];   
  923.         tmp7 = coefptr[DCTSIZE*0] - coefptr[DCTSIZE*7];   
  924.         tmp1 = coefptr[DCTSIZE*1] + coefptr[DCTSIZE*6];   
  925.         tmp6 = coefptr[DCTSIZE*1] - coefptr[DCTSIZE*6];   
  926.         tmp2 = coefptr[DCTSIZE*2] + coefptr[DCTSIZE*5];   
  927.         tmp5 = coefptr[DCTSIZE*2] - coefptr[DCTSIZE*5];   
  928.         tmp3 = coefptr[DCTSIZE*3] + coefptr[DCTSIZE*4];   
  929.         tmp4 = coefptr[DCTSIZE*3] - coefptr[DCTSIZE*4];   
  930.            
  931.         /* Even part */   
  932.            
  933.         tmp10 = tmp0 + tmp3;    /* phase 2 */   
  934.         tmp13 = tmp0 - tmp3;   
  935.         tmp11 = tmp1 + tmp2;   
  936.         tmp12 = tmp1 - tmp2;   
  937.            
  938.         coefptr[DCTSIZE*0] = tmp10 + tmp11; /* phase 3 */   
  939.         coefptr[DCTSIZE*4] = tmp10 - tmp11;   
  940.            
  941.         z1 = MULTIPLY(tmp12 + tmp13, FIX_0_707106781); /* c4 */   
  942.         coefptr[DCTSIZE*2] = tmp13 + z1; /* phase 5 */   
  943.         coefptr[DCTSIZE*6] = tmp13 - z1;   
  944.            
  945.         /* Odd part */   
  946.            
  947.         tmp10 = tmp4 + tmp5;    /* phase 2 */   
  948.         tmp11 = tmp5 + tmp6;   
  949.         tmp12 = tmp6 + tmp7;   
  950.            
  951.         /* The rotator is modified from fig 4-8 to avoid extra negations. */   
  952.         z5 = MULTIPLY(tmp10 - tmp12, FIX_0_382683433); /* c6 */   
  953.         z2 = MULTIPLY(tmp10, FIX_0_541196100) + z5; /* c2-c6 */   
  954.         z4 = MULTIPLY(tmp12, FIX_1_306562965) + z5; /* c2+c6 */   
  955.         z3 = MULTIPLY(tmp11, FIX_0_707106781); /* c4 */   
  956.            
  957.         z11 = tmp7 + z3;        /* phase 5 */   
  958.         z13 = tmp7 - z3;   
  959.            
  960.         coefptr[DCTSIZE*5] = z13 + z2; /* phase 6 */   
  961.         coefptr[DCTSIZE*3] = z13 - z2;   
  962.         coefptr[DCTSIZE*1] = z11 + z4;   
  963.         coefptr[DCTSIZE*7] = z11 - z4;   
  964.            
  965.         coefptr++;          /* advance pointer to next column */   
  966.     }   
  967. }   
  968.    
  969.    
  970. ////////////////////////////////////////////////////////////////////////////////   
  971.    
  972. //进行量化   
  973. void CCompressEncode::Quantize(    
  974.         int* coef,  //coef is both in and out   
  975.         int iBlock  //block id; Y: 0,1,2,3; Cb: 4; Cr: 5   
  976.         )   
  977. {   
  978.     int temp;   
  979.     unsigned short qval, *pQuant;   
  980.    
  981.     if( iBlock < 4 )   
  982.         pQuant = m_qtblY;   
  983.     else   
  984.         pQuant = m_qtblCbCr;   
  985.    
  986.     for (int i = 0; i < 64; i++)    
  987.     {   
  988.         qval = pQuant[i];   
  989.         temp = coef[i];   
  990.            
  991.            
  992. #define DIVIDE_BY(a,b)  if (a >= b) a /= b; else a = 0   
  993.            
  994.            
  995.         if ( temp < 0)    
  996.         {   
  997.             temp = -temp;   
  998.             temp += qval>>1;  /* for rounding */   
  999.             DIVIDE_BY(temp, qval);   
  1000.             temp = -temp;   
  1001.         }    
  1002.         else    
  1003.         {   
  1004.             temp += qval>>1;  /* for rounding */   
  1005.             DIVIDE_BY(temp, qval);   
  1006.         }   
  1007.            
  1008.         coef[i] = temp;        
  1009.     }   
  1010. }   
  1011.    
  1012.    
  1013.    
  1014. ////////////////////////////////////////////////////////////////////////////////   
  1015.    
  1016. //Huffman编码   
  1017. bool CCompressEncode::HuffmanEncode(    
  1018.         int* pCoef,             //  DCT coefficients   
  1019.         int iBlock              //  0,1,2,3:Y; 4:Cb; 5:Cr;   
  1020.         )   
  1021. {      
  1022.     //对AC系数进行Z字型扫描   
  1023.     static const int jpeg_natural_order[64+16] = {   
  1024.              0,  1,  8, 16,  9,  2,  3, 10,   
  1025.             17, 24, 32, 25, 18, 11,  4,  5,   
  1026.             12, 19, 26, 33, 40, 48, 41, 34,   
  1027.             27, 20, 13,  6,  7, 14, 21, 28,   
  1028.             35, 42, 49, 56, 57, 50, 43, 36,   
  1029.             29, 22, 15, 23, 30, 37, 44, 51,   
  1030.             58, 59, 52, 45, 38, 31, 39, 46,   
  1031.             53, 60, 61, 54, 47, 55, 62, 63,   
  1032.             63, 63, 63, 63, 63, 63, 63, 63,//extra entries for safety   
  1033.             63, 63, 63, 63, 63, 63, 63, 63   
  1034.     };   
  1035.        
  1036.     int temp, temp2, nbits, k, r, i;   
  1037.     int *block = pCoef;   
  1038.     int *pLastDc = &m_dcY;   
  1039.     HUFFMAN_TABLE *dctbl, *actbl;   
  1040.    
  1041.     if( iBlock < 4 )   
  1042.     {   
  1043.         dctbl = & m_htblYDC;   
  1044.         actbl = & m_htblYAC;   
  1045. //      pLastDc = &m_dcY;      
  1046.     }   
  1047.     else   
  1048.     {   
  1049.         dctbl = & m_htblCbCrDC;   
  1050.         actbl = & m_htblCbCrAC;   
  1051.    
  1052.         if( iBlock == 4 )   
  1053.             pLastDc = &m_dcCb;   
  1054.         else   
  1055.             pLastDc = &m_dcCr;   
  1056.     }   
  1057.        
  1058.     //对DC系数进行编码   
  1059.        
  1060.     temp = temp2 = block[0] - (*pLastDc);   
  1061.     *pLastDc = block[0];   
  1062.        
  1063.     if (temp < 0) {   
  1064.         temp = -temp;       /* temp is abs value of input */   
  1065.            
  1066.         temp2 --;   
  1067.     }   
  1068.        
  1069.     /* Find the number of bits needed for the magnitude of the coefficient */   
  1070.     nbits = 0;   
  1071.     while (temp) {   
  1072.         nbits ++;   
  1073.         temp >>= 1;   
  1074.     }   
  1075.        
  1076.     //  Write category number   
  1077.     if (! EmitBits( dctbl->code[nbits], dctbl->size[nbits] ))   
  1078.         return FALSE;   
  1079.    
  1080.     //  Write category offset   
  1081.     if (nbits)          /* EmitBits rejects calls with size 0 */   
  1082.     {   
  1083.         if (! EmitBits( (unsigned int) temp2, nbits ))   
  1084.             return FALSE;   
  1085.     }   
  1086.        
  1087.     ////////////////////////////////////////////////////////////////////////////   
  1088.     //对AC系数进行编码   
  1089.        
  1090.     r = 0;          /* r = run length of zeros */   
  1091.        
  1092.     for (k = 1; k < 64; k++)    
  1093.     {   
  1094.         if ((temp = block[jpeg_natural_order[k]]) == 0)    
  1095.         {   
  1096.             r++;   
  1097.         }    
  1098.         else    
  1099.         {   
  1100.             /* if run length > 15, must emit special run-length-16 codes (0xF0) */   
  1101.             while (r > 15) {   
  1102.                 if (! EmitBits( actbl->code[0xF0], actbl->size[0xF0] ))   
  1103.                     return FALSE;   
  1104.                 r -= 16;   
  1105.             }   
  1106.                
  1107.             temp2 = temp;   
  1108.             if (temp < 0) {   
  1109.                 temp = -temp;       /* temp is abs value of input */   
  1110.                 /* This code assumes we are on a two's complement machine */   
  1111.                 temp2--;   
  1112.             }   
  1113.                
  1114.             /* Find the number of bits needed for the magnitude of the coefficient */   
  1115.             nbits = 1;      /* there must be at least one 1 bit */   
  1116.             while ((temp >>= 1))   
  1117.                 nbits++;   
  1118.                
  1119.             /* Emit Huffman symbol for run length / number of bits */   
  1120.             i = (r << 4) + nbits;   
  1121.             if (! EmitBits( actbl->code[i], actbl->size[i] ))   
  1122.                 return FALSE;   
  1123.                            
  1124.             //  Write Category offset   
  1125.             if (! EmitBits( (unsigned int) temp2, nbits ))   
  1126.                 return FALSE;   
  1127.                            
  1128.             r = 0;   
  1129.         }   
  1130.     }   
  1131.        
  1132.        
  1133.     if (r > 0)   
  1134.     {   
  1135.         if (! EmitBits( actbl->code[0], actbl->size[0] ))   
  1136.             return FALSE;   
  1137.     }          
  1138.        
  1139.     return TRUE;   
  1140. }   
  1141.    
  1142.    
  1143. ////////////////////////////////////////////////////////////////////////////////   
  1144.    
  1145.    
  1146. inline bool CCompressEncode::EmitBits(   
  1147.         unsigned int code,      //Huffman code   
  1148.         int size                //Size in bits of the Huffman code   
  1149.         )   
  1150. {   
  1151.     /* This routine is heavily used, so it's worth coding tightly. */   
  1152.     int put_buffer = (int) code;   
  1153.     int put_bits = m_nPutBits;   
  1154.        
  1155.     /* if size is 0, caller used an invalid Huffman table entry */   
  1156.     if (size == 0)   
  1157.         return false;   
  1158.        
  1159.     put_buffer &= (((int)1)<<size) - 1; /* mask off any extra bits in code */   
  1160.        
  1161.     put_bits += size;                   /* new number of bits in buffer */   
  1162.        
  1163.     put_buffer <<= 24 - put_bits;     /* align incoming bits */   
  1164.        
  1165.     put_buffer |= m_nPutVal;            /* and merge with old buffer contents */   
  1166.        
  1167.     //  If there are more than 8 bits, write it out   
  1168.     unsigned char uc;   
  1169.     while (put_bits >= 8)    
  1170.     {   
  1171.         //  Write one byte out !!!!   
  1172.         uc = (unsigned char) ((put_buffer >> 16) & 0xFF);   
  1173.         emit_byte(uc);   
  1174.        
  1175.         if (uc == 0xFF) {       //need to stuff a zero byte?   
  1176.             emit_byte(0);   //  Write one byte out !!!!   
  1177.         }   
  1178.    
  1179.         put_buffer <<= 8;   
  1180.         put_bits -= 8;   
  1181.     }   
  1182.        
  1183.     m_nPutVal   = put_buffer; /* update state variables */   
  1184.     m_nPutBits  = put_bits;   
  1185.        
  1186.     return TRUE;   
  1187. }   
  1188.    
  1189. ////////////////////////////////////////////////////////////////////////////////   
  1190.    
  1191. inline void CCompressEncode::EmitLeftBits(void)   
  1192. {   
  1193.     if (! EmitBits(0x7F, 7)) /* fill 7 bits with ones */   
  1194.         return;   
  1195.        
  1196.     m_nPutVal  = 0;   
  1197.     m_nPutBits = 0;   
  1198. }   
  1199.    
  1200.    
  1201. ////////////////////////////////////////////////////////////////////////////////   

 

CompressEncode.h

CompressEncode.cpp

PicOperate.h

PicOperate.cpp

使用规则:

    char *bmppath="1.bmp";
    CString jpgpath="2.jpg";
    int qui=30;
    m_op.Load( bmppath);
    m_op.picCompressEncode(jpgpath,TRUE,qui);

哈哈

http://blog.youkuaiyun.com/s06cuiyanchao/article/details/5194354
用于将jpeg文件转换成为bmp文件, MICROSOFT FOUNDATION CLASS LIBRARY : JpgVSbmp ======================================================================== AppWizard has created this JpgVSbmp DLL for you. This DLL not only demonstrates the basics of using the Microsoft Foundation classes but is also a starting point for writing your DLL. This file contains a summary of what you will find in each of the files that make up your JpgVSbmp DLL. JpgVSbmp.dsp This file (the project file) contains information at the project level and is used to build a single project or subproject. Other users can share the project (.dsp) file, but they should export the makefiles locally. JpgVSbmp.h This is the main header file for the DLL. It declares the CJpgVSbmpApp class. JpgVSbmp.cpp This is the main DLL source file. It contains the class CJpgVSbmpApp. JpgVSbmp.rc This is a listing of all of the Microsoft Windows resources that the program uses. It includes the icons, bitmaps, and cursors that are stored in the RES subdirectory. This file can be directly edited in Microsoft Visual C++. JpgVSbmp.clw This file contains information used by ClassWizard to edit existing classes or add new classes. ClassWizard also uses this file to store information needed to create and edit message maps and dialog data maps and to create prototype member functions. res\JpgVSbmp.rc2 This file contains resources that are not edited by Microsoft Visual C++. You should place all resources not editable by the resource editor in this file. JpgVSbmp.def This file contains information about the DLL that must be provided to run with Microsoft Windows. It defines parameters such as the name and description of the DLL. It also exports functions from the DLL. ///////////////////////////////////////////////////////////////////////////// Other standard files: StdAfx.h, StdAfx.cpp These files are used to build a precompiled header (PCH) file named JpgVSbmp.pch and a precompiled types file named StdAfx.obj. Resource.h This is the standard header file, which defines new resource IDs. Microsoft Visual C++ reads and updates this file. ///////////////////////////////////////////////////////////////////////////// Other notes: AppWizard uses "TODO:" to indicate parts of the source code you should add to or customize.
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值