本文介绍Jpeg的压缩与解压缩。这里主要使用了jpeglib库来完成压缩与解压缩的任务。关于库的详细说明在此就不赘述。只把详细的编程介绍如下。需要说明的是由于采集到的视频格式是YUV422格式,在压缩时先转成了RGB后压缩的。
1 压缩
int jpeg_compress(int pic_num, _jpegcompress *jpegp, int imagesize)
{ char filename1[20];
image_width=jpegp->w;
image_height=jpegp->h;
__D("%d\n",image_width);
__D("%d\n",image_height);
image_length = image_width * image_height * 3;
__D("start compress\n");
struct jpeg_compress_struct cinfo;
struct jpeg_error_mgr jerr;
JSAMPROW row_pointer[1];
int row_stride;
quality=75;
FILE* fp;
g_RealLen = 0;
g_buf_length = image_length;
__D("%d\n",g_buf_length);
g_buf = (unsigned char *)malloc(g_buf_length);
if (g_buf == NULL) {
__E("Failed to allocate memory for g_buf \n");
return JPEGFAILURE;
}
struct jpeg_destination_mgr jmemdest;
jmemdest.free_in_buffer = g_buf_length;
jmemdest.next_output_byte = g_buf;
jmemdest.init_destination = mem_init_destination;
jmemdest.empty_output_buffer = mem_empty_output_buffer;
jmemdest.term_destination = mem_term_destination;
cinfo.err = jpeg_std_error(&jerr);
jpeg_create_compress(&cinfo);
cinfo.dest = &jmemdest;
cinfo.image_width = image_width;
cinfo.image_height = image_height;
cinfo.input_components =3;
cinfo.in_color_space = JCS_RGB;
__D("picture format:%d\n",JCS_RGB);
jpeg_set_defaults(&cinfo);
jpeg_set_quality(&cinfo, quality, TRUE);
jpeg_start_compress(&cinfo, TRUE);
row_stride = image_width * 3;
while (cinfo.next_scanline < cinfo.image_height)
{
row_pointer[0] = (JSAMPROW)& jpegp->bufp[cinfo.next_scanline * row_stride];
(void) jpeg_write_scanlines(&cinfo, row_pointer, 1);
}
jpeg_finish_compress(&cinfo);
jpeg_destroy_compress(&cinfo);
if(imagesize==D1)sprintf(filename1, "/mnt/usb/pic/D1_%d.jpg",pic_num);
if(imagesize==VGA)sprintf(filename1, "/mnt/usb/pic/VGA_%d.jpg",pic_num);
if(imagesize==CIF)sprintf(filename1, "/mnt/usb/pic/CIF_%d.jpg",pic_num);
fp = fopen(filename1, "wb");
fwrite(g_buf, g_RealLen, 1, fp);
fclose(fp);
// free(image_buffer);
free( g_buf);
__D("Finish compress \n");
return JPEGSUCCESS;
}
<!--[if !supportLists]-->2 <!--[endif]-->解压缩
int jpeg_create(char *filename, _simplejpeg *jpegp)
{
struct jpeg_decompress_struct cinfo;
FILE * infile;
JSAMPARRAY buffer;
int pos;
int row_stride;
struct jpeg_error_mgr jerr;
int x;
unsigned short *dst;
int r, g, b;
infile = fopen(filename, "rb");
if (infile == NULL) {
__E("Failed to open image file [%s]\n", filename);
return SIMPLEWIDGET_FAILURE;
}
cinfo.err = jpeg_std_error(&jerr);
jpeg_create_decompress(&cinfo);
jpeg_stdio_src(&cinfo, infile);
jpeg_read_header(&cinfo, TRUE);
jpeg_start_decompress(&cinfo);
row_stride = cinfo.output_width * cinfo.output_components;
buffer = (*cinfo.mem->alloc_sarray)
((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1);
jpegp->bufp = malloc(row_stride * cinfo.output_height * 2 / 3);
jpegp->w = cinfo.output_width;
jpegp->h = cinfo.output_height;
if (jpegp->bufp == NULL) {
__E("Failed to allocate memory for jpeg image\n");
return SIMPLEWIDGET_FAILURE;
}
dst = jpegp->bufp;
while (cinfo.output_scanline < cinfo.output_height) {
jpeg_read_scanlines(&cinfo, (JSAMPARRAY) buffer, 1);
for (x = 0; x < cinfo.output_width; x++) {
// __D("buffer[0][%d] = %#x\n", x, buffer[0][x]);
if (cinfo.output_components == 1) { // Grayscale
r = buffer[0][x] * (1<<5) / (1<<8);
g = buffer[0][x] * (1<<6) / (1<<8);
b = buffer[0][x] * (1<<5) / (1<<8);
}
else { // RGB
pos = x * cinfo.output_components;
r = buffer[0][pos + 0] * (1<<5) / (1<<8);
g = buffer[0][pos + 1] * (1<<6) / (1<<8);
b = buffer[0][pos + 2] * (1<<5) / (1<<8);
}
dst[x] = b | (g << 5) | (r << 11);
}
dst += cinfo.output_width;
}
jpeg_finish_decompress(&cinfo);
fclose(infile);
return SIMPLEWIDGET_SUCCESS;
}