//#include "stdafx.h"
#include<stdio.h>
#include "memory.h"
#include<stdlib.h>
//#include "string.h"
extern "C" {
#include "jpeglib.h"
}
#pragma comment(lib, "libjpeg/libjpeg.lib")
#define IMAGESIZE 452400
typedef unsigned long DWORD;
typedef int BOOL;
typedef unsigned char BYTE;
typedef unsigned short WORD;
typedef long LONG;
typedef struct tagBITMAPFILEHEADER {
WORD bfType;
WORD bfSizeL;
WORD bfSizeH;
WORD bfReserved1;
WORD bfReserved2;
WORD bfOffBitsL;
WORD bfOffBitsH;
} BITMAPFILEHEADER;
typedef struct tagRGBQUAD {
BYTE rgbBlue;
BYTE rgbGreen;
BYTE rgbRed;
BYTE rgbReserved;
} RGBQUAD;
typedef struct tagBITMAPINFOHEADER{
DWORD biSize;
LONG biWidth;
LONG biHeight;
WORD biPlanes;
WORD biBitCount;
DWORD biCompression;
DWORD biSizeImage;
LONG biXPelsPerMeter;
LONG biYPelsPerMeter;
DWORD biClrUsed;
DWORD biClrImportant;
DWORD biR;
DWORD biG;
DWORD biB;
DWORD biempty;
} BITMAPINFOHEADER;
typedef struct tagBITMAPINFO {
BITMAPINFOHEADER bmiHeader;
RGBQUAD bmiColors[1];
} BITMAPINFO;
/***********************************************
*解压缩jpeg到bmp格式
*对于灰度图和24位图,图像解压后正常
*对于256色索引位图,图像解压后为灰度图
**************************************************/
void jpgtobmp(const char *strSourceFileName, const char *strDestFileName)
{
BITMAPFILEHEADER bfh; // bmp文件头
BITMAPINFOHEADER bih; // bmp头信息
RGBQUAD rq[256]; // 调色板
DWORD bfSize;
DWORD bfOffBits;
WORD RGB;
printf("%d \n",sizeof(bfh));
BYTE *data= NULL;//new BYTE[bih.biWidth*bih.biHeight];
BYTE *data16 = NULL;
// WORD *data16 = NULL;
//BYTE *pDataConv = NULL;//new BYTE[bih.biWidth*bih.biHeight];
int nComponent = 0;
// 声明解压缩对象及错误信息管理器
struct jpeg_decompress_struct cinfo;
struct jpeg_error_mgr jerr;
cinfo.err = jpeg_std_error(&jerr);
jpeg_create_decompress(&cinfo);
FILE *f = fopen(strSourceFileName,"rb");
if (f==NULL)
{
printf("Open file error!\n");
return;
}
//
jpeg_stdio_src(&cinfo, f);
jpeg_read_header(&cinfo, TRUE);
data = new BYTE[cinfo.image_width*cinfo.image_height*3];
data16 = new BYTE[cinfo.image_width*cinfo.image_height*2];
// data16 = new WORD[cinfo.image_width*cinfo.image_height];
jpeg_start_decompress(&cinfo);
JSAMPROW row_pointer[1];
while (cinfo.output_scanline < cinfo.output_height)
{
row_pointer[0] = &data[(cinfo.output_height - cinfo.output_scanline-1)*cinfo.image_width*cinfo.num_components];
jpeg_read_scanlines(&cinfo,row_pointer ,
1);
}
jpeg_finish_decompress(&cinfo);
jpeg_destroy_decompress(&cinfo);
fclose(f);
f=fopen(strDestFileName,"wb");
if (f==NULL)
{
delete [] data;
//delete [] pDataConv;
return;
}
// 写文件头
memset(&bfh,0,sizeof(bfh));
bfSize = sizeof(bfh)+sizeof(bih);
printf("%d \n",sizeof(bih));
bfh.bfSizeH = bfSize/65536;
bfh.bfSizeL = bfSize%65536;
bfOffBits = sizeof(bfh)+sizeof(bih);
bfh.bfOffBitsH = bfOffBits/65536;
bfh.bfOffBitsL = bfOffBits%65536;
if (cinfo.num_components==1)
{
bfOffBits += 1024;
bfh.bfOffBitsH = bfOffBits/65536;
bfh.bfOffBitsL = bfOffBits%65536;
bfSize += 1024;
bfh.bfSizeH = bfSize/65536;
bfh.bfSizeL = bfSize%65536;
}
else{
bfSize += cinfo.image_width*cinfo.image_height*cinfo.num_components;
bfh.bfSizeH = bfSize/65536;
bfh.bfSizeL = bfSize%65536;
}
bfh.bfType = 0x4d42;
fwrite(&bfh,sizeof(bfh),1,f);
// 写图像信息
bih.biBitCount = 16;
bih.biSize = sizeof(bih);
bih.biWidth = cinfo.image_width;
bih.biHeight = cinfo.image_height;
bih.biPlanes = 1;
bih.biCompression = 3;
bih.biSizeImage = cinfo.image_width*cinfo.image_height*2;
bih.biXPelsPerMeter = 0;
bih.biYPelsPerMeter = 0;
bih.biClrUsed = 0;
bih.biClrImportant = 0;
bih.biR=0xf800;
bih.biG=0x7e0;
bih.biB=0x1f;
bih.biempty= 0;
fwrite(&bih,sizeof(bih),1,f);
// 写调色板
if (bih.biBitCount==8)
{
for (int i=0;i<256;i++)
{
rq[i].rgbBlue =i;
rq[i].rgbGreen = i;
rq[i].rgbRed = i;
rq[i].rgbReserved = 0;
}
fwrite(rq,1024,1,f);
}
if (bih.biBitCount==16)
{
for(int i = 0;i<bih.biWidth*bih.biHeight;i++)
{
BYTE red = data[i*3];
data[i*3] = data[i*3+2];
data[i*3+2] = red;
// printf("%x \n",data[i]);
}
for(int j = 0;j<bih.biWidth*bih.biHeight;j++)
{
RGB = (data[j*3]>>3) | (data[j*3+1]>>2)<<5 | (data[j*3+2]>>3)<<11;
// printf("%x",RGB);
data16[j*2] = RGB%256;
data16[j*2+1] = RGB/256;
}
fwrite(data16,cinfo.image_width*cinfo.image_height*2,1,f);
}
if (bih.biBitCount==24)
{
// 调整rgb顺序
for (int i = 0;i<bih.biWidth*bih.biHeight;i++)
{
BYTE red = data[i*3];
data[i*3] = data[i*3+2];
data[i*3+2] = red;
}
fwrite(data,cinfo.image_width*cinfo.image_height*3,1,f);
}
fclose(f);
delete [] data;
delete [] data16;
}
int main()
{
jpgtobmp("1.jpg","2.bmp");
return 0;
}