JPEG转RGB Bmp(IJG库 jpeg.lib)

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;

     }

}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值