home *** CD-ROM | disk | FTP | other *** search
/ Windows Graphics Programming / Feng_Yuan_Win32_GDI_DirectX.iso / Samples / include / jpeg.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2000-05-12  |  5.5 KB  |  250 lines

  1. //-----------------------------------------------------------------------------------//
  2. //              Windows Graphics Programming: Win32 GDI and DirectDraw               //
  3. //                             ISBN  0-13-086985-6                                   //
  4. //                                                                                   //
  5. //  Written            by  Yuan, Feng                             www.fengyuan.com   //
  6. //  Copyright (c) 2000 by  Hewlett-Packard Company                www.hp.com         //
  7. //  Published          by  Prentice Hall PTR, Prentice-Hall, Inc. www.phptr.com      //
  8. //                                                                                   //
  9. //  FileName   : jpeg.cpp                                                             //
  10. //  Description: KPicture class, wrapper for JPEG encoding/decoding                  //
  11. //  Version    : 1.00.000, May 31, 2000                                              //
  12. //-----------------------------------------------------------------------------------//
  13.  
  14. #define STRICT
  15. #define WIN32_LEAN_AND_MEAN
  16.  
  17. #include <windows.h>
  18. #include <stdio.h>
  19. #include <assert.h>
  20. #include <math.h>
  21.  
  22. #define XMD_H
  23.  
  24. #include "jpeg.h"
  25. #include ".\jlib\jpeglib.h"
  26.  
  27. void KPicture::Release(void)
  28. {
  29.     if ( m_pBMI )
  30.     {
  31.         delete [] (BYTE *) m_pBMI;
  32.         m_pBMI = NULL;
  33.     }
  34.  
  35.     if ( m_pBits )
  36.     {
  37.         delete [] (BYTE *) m_pBits;
  38.         m_pBits = NULL;
  39.     }
  40. }
  41.  
  42.  
  43. int KPicture::Allocate(int width, int height, int channels, bool bBits)
  44. {
  45.     Release();
  46.  
  47.     switch ( channels )
  48.     {
  49.         case 3:
  50.             m_pBMI = (BITMAPINFO *) new BYTE[sizeof(BITMAPINFOHEADER)];
  51.             break;
  52.  
  53.         case 1:
  54.             m_pBMI = (BITMAPINFO *) new BYTE[sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)];
  55.             {
  56.                 for (int i=0; i<256; i++)
  57.                 {
  58.                     m_pBMI->bmiColors[i].rgbRed         = i;
  59.                     m_pBMI->bmiColors[i].rgbGreen     = i;
  60.                     m_pBMI->bmiColors[i].rgbBlue     = i;
  61.                     m_pBMI->bmiColors[i].rgbReserved = 0;
  62.                 }
  63.             }
  64.             break;
  65.  
  66.         default:
  67.             return 0;
  68.     }
  69.  
  70.     if ( m_pBMI==NULL )
  71.         return 0;
  72.  
  73.     memset(m_pBMI, 0, sizeof(BITMAPINFOHEADER));
  74.     m_pBMI->bmiHeader.biSize     = sizeof(m_pBMI->bmiHeader);
  75.     m_pBMI->bmiHeader.biWidth    = width;
  76.     m_pBMI->bmiHeader.biHeight   = height;
  77.     m_pBMI->bmiHeader.biBitCount = channels * 8;
  78.     m_pBMI->bmiHeader.biPlanes   = 1;
  79.  
  80.     // allocate bitmap
  81.     int    bps = (width * channels + 3) /4 * 4;
  82.  
  83.     if ( bBits )
  84.         m_pBits = (BYTE *) new BYTE[bps * height];
  85.  
  86.     return bps;
  87. }
  88.  
  89.  
  90. BOOL KPicture::DecodeJPEG(const void * jpegimage, int jpegsize)
  91. {
  92.     try
  93.     {
  94.         struct jpeg_decompress_struct dinfo;
  95.  
  96.         jpeg_error_mgr jerr;
  97.         dinfo.err  = & jerr;
  98.  
  99.         dinfo.jpeg_create_decompress();
  100.         jpeg_const_src(&dinfo, (const BYTE *) jpegimage, jpegsize);
  101.         dinfo.jpeg_read_header(TRUE);
  102.         dinfo.jpeg_start_decompress();
  103.  
  104.         int    bps = Allocate(dinfo.image_width, dinfo.image_height, dinfo.out_color_components, true);
  105.  
  106.         if ( m_pBits==NULL )
  107.             return FALSE;
  108.  
  109.         for (int h=dinfo.image_height-1; h>=0; h--) // bottom-up
  110.         {
  111.             BYTE * addr = m_pBits + bps * h; 
  112.             dinfo.jpeg_read_scanlines(& addr, 1);
  113.         }
  114.         
  115.         dinfo.jpeg_finish_decompress();
  116.         dinfo.jpeg_destroy_decompress();
  117.  
  118.         m_pJPEG     = (BYTE *) jpegimage;
  119.         m_nJPEGSize = jpegsize;
  120.     }
  121.     catch (...)
  122.     {
  123.         return FALSE;
  124.     }
  125.     
  126.     return TRUE;
  127. }
  128.  
  129.  
  130. BOOL KPicture::QueryJPEG(const void * jpegimage, int jpegsize)
  131. {
  132.     try
  133.     {
  134.         struct jpeg_decompress_struct dinfo;
  135.  
  136.         jpeg_error_mgr jerr;
  137.         dinfo.err  = & jerr;
  138.  
  139.         dinfo.jpeg_create_decompress();
  140.  
  141.         jpeg_const_src(&dinfo, (const BYTE *) jpegimage, jpegsize);
  142.  
  143.         dinfo.jpeg_read_header(TRUE);
  144.  
  145.         Allocate(dinfo.image_width, dinfo.image_height, dinfo.out_color_components, false);
  146.  
  147.         dinfo.jpeg_destroy_decompress();
  148.     }
  149.     catch (...)
  150.     {
  151.         return FALSE;
  152.     }
  153.  
  154.     return TRUE;
  155. }
  156.  
  157.  
  158. BOOL KPicture::LoadJPEGFile(const TCHAR * filename)
  159. {
  160.     HANDLE hFile = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ, NULL,
  161.           OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  162.  
  163.     if (hFile == INVALID_HANDLE_VALUE)
  164.         return FALSE;
  165.  
  166.     int size = GetFileSize(hFile, NULL);
  167.     BYTE * pImage = new BYTE[size];
  168.  
  169.     BOOL rslt = FALSE;
  170.  
  171.     if ( pImage )
  172.     {
  173.         DWORD dwRead;
  174.         ReadFile(hFile, pImage, size, & dwRead, NULL);
  175.  
  176.         rslt = DecodeJPEG(pImage, size);
  177.         
  178.     //    delete [] pImage;
  179.     }    
  180.  
  181.     CloseHandle(hFile);
  182.  
  183.     return rslt;
  184. }
  185.  
  186. BOOL KPicture::SaveJPEGFile(const TCHAR * filename, int quality)
  187. {
  188.     if ( (m_pBMI==NULL) || (m_pBits==NULL) )
  189.         return FALSE;
  190.  
  191.     FILE * outfile = fopen(filename, "wb");
  192.  
  193.     if  ( outfile==NULL ) 
  194.     {
  195.         assert(false);
  196.         return FALSE;
  197.     }
  198.  
  199.     try
  200.     {
  201.         struct jpeg_compress_struct cinfo;
  202.  
  203.         jpeg_error_mgr jerr;
  204.         cinfo.err = &jerr;
  205.  
  206.         jpeg_create_compress(&cinfo);
  207.         jpeg_stdio_dest(&cinfo, outfile);
  208.  
  209.         cinfo.image_width  =     m_pBMI->bmiHeader.biWidth;
  210.         cinfo.image_height = abs(m_pBMI->bmiHeader.biHeight);
  211.         
  212.         if ( m_pBMI->bmiHeader.biBitCount==24 ) 
  213.         {
  214.             cinfo.input_components = 3;
  215.             cinfo.in_color_space   = JCS_RGB;
  216.         } 
  217.         else if ( m_pBMI->bmiHeader.biBitCount==8 ) 
  218.         {
  219.             cinfo.input_components = 1;
  220.             cinfo.in_color_space   = JCS_GRAYSCALE;
  221.         }
  222.         else
  223.             return FALSE;
  224.  
  225.         jpeg_set_defaults(&cinfo);
  226.           jpeg_set_quality(&cinfo, quality, TRUE);
  227.         jpeg_start_compress(&cinfo, TRUE);
  228.  
  229.         int bps = ( m_pBMI->bmiHeader.biWidth * cinfo.input_components + 3 ) / 4 * 4;
  230.         
  231.         for (int y=abs(m_pBMI->bmiHeader.biHeight)-1; y>=0; y++)
  232.         {
  233.             const BYTE * BGR = m_pBits + bps * y;
  234.  
  235.             jpeg_write_scanlines(&cinfo, (BYTE **) & BGR, 1);
  236.         }
  237.  
  238.         jpeg_finish_compress(&cinfo);
  239.         jpeg_destroy_compress(&cinfo);
  240.     }
  241.     catch (...)
  242.     {
  243.     }
  244.  
  245.     fclose(outfile);
  246.  
  247.     return TRUE;
  248. }
  249.  
  250.