void bmpfile_to_bgr(char *bmp_file,BYTE **rgb,int *size,int *w,int *h,int *bit)
{
FILE *fp = fopen(bmp_file,"rb");
if(fp == NULL) return;
BITMAPFILEHEADER bmpheader;
BITMAPINFOHEADER bmpinfo;
fread(&bmpheader,sizeof(BITMAPFILEHEADER),1,fp);
fread(&bmpinfo,sizeof(BITMAPINFOHEADER),1,fp);
*rgb = new BYTE[bmpinfo.biSizeImage];
fread(*rgb,bmpinfo.biSizeImage,1,fp);
*size = bmpinfo.biSizeImage;
*w = bmpinfo.biWidth;
*h = abs(bmpinfo.biHeight);
*bit = bmpinfo.biBitCount;
fclose(fp);
}
BYTE *bgr1 = NULL;
int size=0,w=0,h=0,bit=0;
bmpfile_to_bgr("test.bmp",&bgr1,&size,&w,&h,&bit);
free(bgr1);
void bgr_to_bmpfile(char *bmp_file,BYTE *rgb,int size,int w,int h,int bit)
{
FILE *fp = fopen(bmp_file,"wb+");
if(fp == NULL) return;
BITMAPFILEHEADER bmpheader;
BITMAPINFOHEADER bmpinfo;
bmpheader.bfType = 0x4d42;
bmpheader.bfReserved1 = 0;
bmpheader.bfReserved2 = 0;
bmpheader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
bmpheader.bfSize = bmpheader.bfOffBits + size;
bmpinfo.biSize = sizeof(BITMAPINFOHEADER);
bmpinfo.biWidth = w;
bmpinfo.biHeight = h;
bmpinfo.biPlanes = 1;
bmpinfo.biBitCount = bit;
bmpinfo.biCompression = BI_RGB;
bmpinfo.biSizeImage = (w*bit+31)/32*4*h;
bmpinfo.biXPelsPerMeter = 0;
bmpinfo.biYPelsPerMeter = 0;
bmpinfo.biClrUsed = 0;
bmpinfo.biClrImportant = 0;
fwrite(&bmpheader, sizeof(BITMAPFILEHEADER), 1, fp);
fwrite(&bmpinfo, sizeof(BITMAPINFOHEADER), 1, fp);
fwrite(rgb, size, 1, fp);
fclose(fp);
}
bgr_to_bmpfile("test.bmp",bgr1,size,w,h,bit);
bmp的分量是以bgr保存的,但是libjpeg使用的是rgb,所以需要翻转br分量
void bgr_flip_rgb(BYTE *bgr,int size,int bit)
{
int i = 0;
for(;i<size;i+=bit/8){
BYTE b = bgr[i];
bgr[i] = bgr[i+2];
bgr[i+2] = b;
}
}
void jpgfile_to_jpgmem(char *jpg_file,BYTE **jpg,int *size)
{
FILE *fp = fopen(jpg_file,"rb");
if(fp == NULL) return;
fseek(fp,0,SEEK_END);
int length = ftell(fp);
fseek(fp,0,SEEK_SET);
*jpg = new BYTE[length];
fread(*jpg,length,1,fp);
*size = length;
fclose(fp);
}
BYTE *jpg = NULL;
int size = 0;
jpgfile_to_jpgmem("Tulips.jpg",&jpg,&size);
free(jpg);
void jpgmem_to_jpgfile(char *jpg_file,BYTE *jpg,int size)
{
FILE *fp = fopen(jpg_file,"wb+");
if(fp == NULL) return;
fwrite(jpg,size,1,fp);
fclose(fp);
}
void bgr_to_jpgmem(BYTE *rgb,int size,int w,int h,int bit,BYTE **jpg,int *j_size)
{
struct jpeg_error_mgr jerr;
jpeg_std_error(&jerr);
struct jpeg_compress_struct cinfo;
cinfo.err = &jerr;
jpeg_create_compress(&cinfo);
jpeg_mem_dest(&cinfo,jpg,(unsigned long*)j_size);
cinfo.image_width = w;
cinfo.image_height = h;
cinfo.input_components = 3;
cinfo.in_color_space = JCS_RGB;
jpeg_set_defaults(&cinfo);
jpeg_set_quality(&cinfo, 100, TRUE);
jpeg_start_compress(&cinfo,TRUE);
int row_stride = cinfo.image_width*cinfo.input_components;
JSAMPROW row_pointer[1];
while(cinfo.next_scanline < cinfo.image_height)
{
row_pointer[0] = & rgb[(cinfo.image_height-cinfo.next_scanline-1)*row_stride];
(void)jpeg_write_scanlines(&cinfo, row_pointer, 1);
}
jpeg_finish_compress(&cinfo);
jpeg_destroy_compress(&cinfo);
}
void bgr_to_jpgfile(BYTE *rgb,int size,int w,int h,int bit,char *jpgfile)
{
struct jpeg_error_mgr jerr;
jpeg_std_error(&jerr);
struct jpeg_compress_struct cinfo;
cinfo.err = &jerr;
jpeg_create_compress(&cinfo);
FILE *fp = fopen(jpgfile,"wb+");
jpeg_stdio_dest(&cinfo,fp);
//jpeg_mem_dest(&cinfo,jpg,(unsigned long*)j_size);
cinfo.image_width = w;
cinfo.image_height = h;
cinfo.input_components = 3;
cinfo.in_color_space = JCS_RGB;
jpeg_set_defaults(&cinfo);
jpeg_set_quality(&cinfo, 100, TRUE);
jpeg_start_compress(&cinfo,TRUE);
int row_stride = cinfo.image_width*cinfo.input_components;
JSAMPROW row_pointer[1];
while(cinfo.next_scanline < cinfo.image_height)
{
//row_pointer[0] = & rgb[cinfo.next_scanline * row_stride];
row_pointer[0] = & rgb[(cinfo.image_height-cinfo.next_scanline-1)*row_stride];
(void)jpeg_write_scanlines(&cinfo, row_pointer, 1);
}
jpeg_finish_compress(&cinfo);
jpeg_destroy_compress(&cinfo);
fclose(fp);
}
void jpgmem_to_bgr(BYTE *jpg,int size,BYTE **bgr,int *b_size,int *w,int *h)
{
struct jpeg_decompress_struct cinfo;
struct jpeg_error_mgr jerr;
cinfo.err = jpeg_std_error(&jerr);
jpeg_create_decompress(&cinfo);
jpeg_mem_src(&cinfo,jpg,size);
jpeg_read_header(&cinfo,TRUE);
jpeg_start_decompress(&cinfo);
unsigned long width = cinfo.output_width;
unsigned long height = cinfo.output_height;
unsigned short depth = cinfo.output_components;
*w = width;
*h = height;
*b_size = width*height*depth;
*bgr = (BYTE*)malloc(width*height*depth);
memset(*bgr,0,width*height*depth);
JSAMPARRAY buffer = (*cinfo.mem->alloc_sarray)((j_common_ptr)&cinfo, JPOOL_IMAGE, width*depth,1);
BYTE *point = (*bgr)+(height-cinfo.output_scanline-1)*(width*depth);
while(cinfo.output_scanline<height)
{
jpeg_read_scanlines(&cinfo, buffer, 1);
memcpy(point, *buffer, width*depth);
point -= width*depth;
}
jpeg_finish_decompress(&cinfo);
jpeg_destroy_decompress(&cinfo);
}
BYTE *jpg = NULL;
int j_size = 0;
jpgfile_to_jpgmem("Tulips.jpg",&jpg,&j_size);
BYTE *bgr = NULL;
int size,w,h,bit=24;
jpgmem_to_bgr(jpg,j_size,&bgr,&size,&w,&h);
bgr_flip_rgb(bgr,size,bit);
bgr_to_bmpfile("Tulips2.bmp",bgr,size,w,h,bit);
free(bgr);
free(jpg);