0. libjpeg 介绍
libjpeg 是一个完全用C语言编写的库,包含了被广泛使用的JPEG解码、JPEG编码和其他的JPEG功能的实现。这个库由独立JPEG工作组维护。
参考:http://zh.wikipedia.org/wiki/Libjpeg
本文基于 libjpeg9 对使用 libjpeg 保存图片时因磁盘写入失败导致程序退出的问题进行分析,文中的代码和解决问题的方法均可结合 libjpeg9 编译通过。
1.使用 libjpeg 保存图片的方法。
不多说,直接上代码:
/**
* 将 rgb 数据保存到 jpeg 文件*/
int rgb_to_jpeg(LPRgbImage img, const char*filename) {
FILE*f;structjpeg_compress_struct jcs;//声明错误处理器,并赋值给jcs.err域
structjpeg_error_mgr jem;
unsignedchar*pData;int error_flag = 0;
jcs.err= jpeg_std_error(&jem);
jpeg_create_compress(&jcs);f= fopen(filename, "wb");if (f ==NULL) {return -1;
}//android 下使用以下方法,来解决使用 fwrite 写文件时 sd 卡满而不返回错误的问题
setbuf(f, NULL);
jpeg_stdio_dest(&jcs, f);
jcs.image_width= img->width; //图像尺寸
jcs.image_height = img->height; //图像尺寸
jcs.input_components = 3; //在此为1,表示灰度图, 如果是彩色位图,则为3
jcs.in_color_space = JCS_RGB; //JCS_GRAYSCALE表示灰度图,JCS_RGB表示彩色图像
jpeg_set_defaults(&jcs);
jpeg_set_quality(&jcs, 100, 1); //图像质量,100 最高
jpeg_start_compress(&jcs, TRUE);while (jcs.next_scanline
pData= img->rgb + jcs.image_width * jcs.next_scanline * 3;jpeg_write_scanlines(&jcs, &pData, 1);}
jpeg_finish_compress(&jcs);
jpeg_destroy_compress(&jcs);
fclose (f);returnerror_flag;
}
libjpeg 也可已用来解码(读取 jpeg)文件:
/**
* 从 jpeg 文件读取数据,并保存到 RgbImage 中返回*/LPRgbImage jpeg_to_rgb(const char*filename) {structjpeg_decompress_struct cinfo;structjpeg_error_mgr jerr;
FILE*f;
LPRgbImage pRgbImage;
JSAMPROW row_pointer[1];
f= fopen(filename, "rb");if (f ==NULL) {returnNULL;
}//将 jpeg 错误处理中的异常退出回调修改为我们自己的回调函数,保证程序不异常退出
cinfo.err = jpeg_std_error(&jerr);jpeg_create_decompress(&cinfo);
jpeg_stdio_src(&cinfo, f);
jpeg_read_header(&cinfo, TRUE);
pRgbImage= (LPRgbImage) malloc(sizeof(RgbImage));if (pRgbImage ==NULL) {
fclose(f);returnNULL;
}
pRgbImage->width =cinfo.image_width;
pRgbImage->height =cinfo.image_height;
pRgbImage->linesize = libcfc_align_size(cinfo.image_width * 3);
pRgbImage->rgb = (unsigned char*) malloc(pRgbImage->linesize *cinfo.image_height);if (pRgbImage->rgb ==NU