JPEG轉RGB Bmp(IJG庫 jpeg.lib)

smilestone322發表於2016-03-01

JPEGRGBRGB壓縮的逆過程,從壓縮後的影象資料,然後進過熵編碼器,在經過量化器(),然後在經過逆DCT變換,得到解壓後的影象資料,我們在使用jpeg.lib庫進行解壓,解壓的函式如下:

      

       //讀取JPEG檔案

//引數:

//lpstrFileName——包含JPEG檔案的全路徑名

//uWidth——影象的寬度

//uHeight——影象的高度

//返回值為解壓後的資料緩衝區指標

BYTE* CJpeg::ReadJPEGFile(LPCSTR lpstrFileName, UINT *uWidth, UINT *uHeight)

{

     *uWidth=0;

     *uHeight=0;

     //定義JPEG檔案的解壓資訊

     struct jpeg_decompress_struct cinfo;

     //定義JPEG檔案的錯誤資訊

     struct my_error_mgr jerr;

    

     //定義緩衝區

     FILE * infile;        

     JSAMPARRAY buffer;

     int row_stride;       

     char buf[250];

    //開啟JPEG檔案

     if ((infile = fopen(lpstrFileName, "rb")) == NULL)

     {

         sprintf(buf, "JPEG :\nCan't open %s\n", lpstrFileName);

         m_strJPEGError = buf;

         return NULL;

     }

 

    //為JPEG檔案解壓物件分配記憶體並對其初始

     cinfo.err = jpeg_std_error(&jerr.pub);

     jerr.pub.error_exit = my_error_exit;

     if (setjmp(jerr.setjmp_buffer))

     {

         jpeg_destroy_decompress(&cinfo);

         fclose(infile);

         return NULL;

     }

     jpeg_create_decompress(&cinfo);

    //設定資料來源

     jpeg_stdio_src(&cinfo, infile);

    //讀取JPEG檔案引數

     (void) jpeg_read_header(&cinfo, TRUE);

      //開始解壓

     (void) jpeg_start_decompress(&cinfo);

     BYTE *dataBuf;

     dataBuf=(BYTE *)new BYTE[cinfo.output_width * 3 * cinfo.output_height];//存放解壓後的資料

     if (dataBuf==NULL)

     {

         m_strJPEGError = "JpegFile :\nOut of memory";

         jpeg_destroy_decompress(&cinfo);

         fclose(infile);

         return NULL;

     }

 

     *uWidth = cinfo.output_width;

     *uHeight = cinfo.output_height;

     row_stride = cinfo.output_width * cinfo.output_components;

     buffer = (*cinfo.mem->alloc_sarray)

         ((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1);         //分配記憶體

     //讀取掃描線

     while (cinfo.output_scanline < cinfo.output_height)

     {

         (void) jpeg_read_scanlines(&cinfo, buffer, 1);

         if (cinfo.out_color_components==3)

         {

              j_putRGBScanline(buffer[0],

                                 *uWidth,

                                 dataBuf,

                                 cinfo.output_scanline-1);

         }

         else if (cinfo.out_color_components==1)

         {

              j_putGrayScanlineToRGB(buffer[0],

                                     *uWidth,

                                     dataBuf,

                                     cinfo.output_scanline-1);

         }

     }

     //完成解壓

     (void) jpeg_finish_decompress(&cinfo);

    //釋放JPEG解壓物件

     jpeg_destroy_decompress(&cinfo);

     fclose(infile);

     return dataBuf;

}

 

//

//   stash a scanline

//

 

void j_putRGBScanline(BYTE *jpegline,

                        int widthPix,

                        BYTE *outBuf,

                        int row)

{

     int offset = row * widthPix * 3;

     int count;

     for (count=0;count<widthPix;count++) {

         BYTE iRed, iBlu, iGrn;

         LPBYTE oRed, oBlu, oGrn;

         iRed = *(jpegline + count * 3 + 0);

         iGrn = *(jpegline + count * 3 + 1);

         iBlu = *(jpegline + count * 3 + 2);

         oRed = outBuf + offset + count * 3 + 0;

         oGrn = outBuf + offset + count * 3 + 1;

          oBlu = outBuf + offset + count * 3 + 2;

         *oRed = iRed;

         *oGrn = iGrn;

         *oBlu = iBlu;

     }

}

 

//

//   stash a gray scanline

//

 

void j_putGrayScanlineToRGB(BYTE *jpegline,

                                  int widthPix,

                                  BYTE *outBuf,

                                  int row)

{

     int offset = row * widthPix * 3;

     int count;

     for (count=0;count<widthPix;count++)

     {

         BYTE iGray;

         LPBYTE oRed, oBlu, oGrn;

         // get our grayscale value

         iGray = *(jpegline + count);

         oRed = outBuf + offset + count * 3;

         oGrn = outBuf + offset + count * 3 + 1;

         oBlu = outBuf + offset + count * 3 + 2;

         *oRed = iGray;

         *oGrn = iGray;

         *oBlu = iGray;

     }

}

相關文章