From 7bcb89e0fac8085e079d7892ecaa42ca3d9a36fd Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sat, 3 Apr 2010 19:42:09 +0000 Subject: [PATCH] Make our jpeg_mem_* functions API compatible with the libjpeg8 versions libjpeg8 ships with its own memory source and dest support (hurray!), make our memory source and dest functions API compatible and only implement them when building against an older libjpeg. Thanks to Theodore Kilgore for pointing this out. git-svn-id: https://svn.code.sf.net/p/gphoto/code/trunk/libgphoto2@12899 67ed7778-7388-44ab-90cf-0a291f65f57c --- camlibs/ax203/ax203_compress_jpeg.c | 27 +++++----- camlibs/ax203/jpeg_memsrcdest.c | 78 ++++++++++++----------------- camlibs/ax203/jpeg_memsrcdest.h | 10 ++-- 3 files changed, 51 insertions(+), 64 deletions(-) diff --git a/camlibs/ax203/ax203_compress_jpeg.c b/camlibs/ax203/ax203_compress_jpeg.c index aedc5405c..bfecf1510 100644 --- a/camlibs/ax203/ax203_compress_jpeg.c +++ b/camlibs/ax203/ax203_compress_jpeg.c @@ -117,9 +117,10 @@ ax203_compress_jpeg(int **in, uint8_t *outbuf, int out_size, struct jpeg_decompress_struct dinfo; struct jpeg_error_mgr jcerr, jderr; JSAMPROW row_pointer[1]; - JOCTET *buf, *regular_jpeg = NULL; + JOCTET *buf = NULL, *regular_jpeg = NULL; jvirt_barray_ptr *in_coefficients; - int i, x, y, stop, regular_jpeg_size, buf_size, size, ret, outc; + int i, x, y, stop, size, ret, outc; + unsigned long regular_jpeg_size = 0, buf_size = 0; int last_dc_val[3] = { 0, 0, 0 }; /* Compression configuration settings */ int uv_subsample = 2; @@ -142,7 +143,7 @@ ax203_compress_jpeg(int **in, uint8_t *outbuf, int out_size, creating the ax203 JPEG-ish format */ cinfo.err = jpeg_std_error (&jcerr); jpeg_create_compress (&cinfo); - jpeg_mem_dest (&cinfo); + jpeg_mem_dest (&cinfo, ®ular_jpeg, ®ular_jpeg_size); cinfo.image_width = width; cinfo.image_height = height; cinfo.input_components = 3; @@ -165,11 +166,6 @@ ax203_compress_jpeg(int **in, uint8_t *outbuf, int out_size, jpeg_write_scanlines (&cinfo, row_pointer, 1); } jpeg_finish_compress (&cinfo); - regular_jpeg = jpeg_mem_dest_get_buffer (&cinfo); - regular_jpeg_size = jpeg_mem_dest_get_final_image_size (&cinfo); - /* Note we do not call jpeg_mem_dest_free_buffer() here as one would - do normally, as we want to keep the buffer around (we free it - later ourselves) */ jpeg_destroy_compress (&cinfo); /* Write image header to outbuf */ @@ -233,7 +229,6 @@ ax203_compress_jpeg(int **in, uint8_t *outbuf, int out_size, /* Create a JPEG compression object for our mini JPEGs */ cinfo.err = jpeg_std_error (&jcerr); jpeg_create_compress (&cinfo); - jpeg_mem_dest (&cinfo); cinfo.image_width = 8 * uv_subsample; cinfo.image_height = 8 * uv_subsample; cinfo.input_components = 3; @@ -281,6 +276,10 @@ ax203_compress_jpeg(int **in, uint8_t *outbuf, int out_size, uv_subsample, 0); for (x = 0; x < width / (8 * uv_subsample); x++) { + /* (Re)init our destination buffer */ + jpeg_mem_dest (&cinfo, &buf, &buf_size); + + /* Add MCU info block to output */ add_mcu_info (outbuf, y * width / (8 * uv_subsample) + x, last_dc_val[2], last_dc_val[0], @@ -351,8 +350,6 @@ ax203_compress_jpeg(int **in, uint8_t *outbuf, int out_size, jpeg_finish_compress (&cinfo); - buf = jpeg_mem_dest_get_buffer (&cinfo); - buf_size = jpeg_mem_dest_get_final_image_size (&cinfo); stop = 0; for (i = 2; i < buf_size && !stop; i += size) { stop = buf[i] == 0xff && buf[i + 1] == 0xda; @@ -372,15 +369,19 @@ ax203_compress_jpeg(int **in, uint8_t *outbuf, int out_size, return GP_ERROR_FIXED_LIMIT_EXCEEDED; } outc += copy_huffman(outbuf + outc, buf + i, size); + + /* Cleanup our memory dest */ + free (buf); + buf = NULL; + buf_size = 0; } } /* We're done with the jpeg decompress (input) and compress (output) objs */ jpeg_destroy_decompress (&dinfo); - free(regular_jpeg); - jpeg_mem_dest_free_buffer(&cinfo); jpeg_destroy_compress (&cinfo); + free(regular_jpeg); return outc; } diff --git a/camlibs/ax203/jpeg_memsrcdest.c b/camlibs/ax203/jpeg_memsrcdest.c index d954e9d33..a2f79df94 100644 --- a/camlibs/ax203/jpeg_memsrcdest.c +++ b/camlibs/ax203/jpeg_memsrcdest.c @@ -21,6 +21,9 @@ #include #include "jpeg_memsrcdest.h" +/* libjpeg8 and later come with their own (API compatible) memory source + and dest */ +#if JPEG_LIB_VERSION < 80 /* Expanded data source object for memory input */ @@ -137,7 +140,8 @@ term_source (j_decompress_ptr cinfo) */ GLOBAL(void) -jpeg_mem_src (j_decompress_ptr cinfo, const JOCTET * buffer, size_t bufsize) +jpeg_mem_src (j_decompress_ptr cinfo, unsigned char * buffer, + unsigned long bufsize) { my_src_ptr src; @@ -179,8 +183,8 @@ jpeg_mem_src (j_decompress_ptr cinfo, const JOCTET * buffer, size_t bufsize) typedef struct { struct jpeg_destination_mgr pub; /* public fields */ - JOCTET * buffer; /* start of buffer */ - int buf_size, final_image_size; + JOCTET **buffer; /* start of buffer */ + unsigned long buf_size, *outsize; } my_destination_mgr; typedef my_destination_mgr * my_dest_ptr; @@ -196,17 +200,10 @@ typedef my_destination_mgr * my_dest_ptr; METHODDEF(void) init_destination (j_compress_ptr cinfo) { - my_dest_ptr dest = (my_dest_ptr) cinfo->dest; - - if (!dest->buffer) { - dest->buffer = malloc (OUTPUT_BUF_SIZE); - if (!dest->buffer) - ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, 0); - dest->buf_size = OUTPUT_BUF_SIZE; - } - - dest->pub.next_output_byte = dest->buffer; - dest->pub.free_in_buffer = dest->buf_size; + /* No work, since jpeg_mem_dest set up the buffer pointer and count. + * Indeed, if we want to write multiple JPEG images to one buffer, + * this *must* not do anything to the pointer. + */ } /* @@ -237,11 +234,11 @@ empty_output_buffer (j_compress_ptr cinfo) { my_dest_ptr dest = (my_dest_ptr) cinfo->dest; - dest->buffer = realloc (dest->buffer, dest->buf_size + OUTPUT_BUF_SIZE); - if (!dest->buffer) + *dest->buffer = realloc (*dest->buffer, dest->buf_size + OUTPUT_BUF_SIZE); + if (!*dest->buffer) ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, 0); - dest->pub.next_output_byte = dest->buffer + dest->buf_size; + dest->pub.next_output_byte = *dest->buffer + dest->buf_size; dest->pub.free_in_buffer = OUTPUT_BUF_SIZE; dest->buf_size += OUTPUT_BUF_SIZE; @@ -262,11 +259,12 @@ term_destination (j_compress_ptr cinfo) { my_dest_ptr dest = (my_dest_ptr) cinfo->dest; - dest->final_image_size = dest->buf_size - dest->pub.free_in_buffer; + *dest->outsize = dest->buf_size - dest->pub.free_in_buffer; } GLOBAL(void) -jpeg_mem_dest (j_compress_ptr cinfo) +jpeg_mem_dest (j_compress_ptr cinfo, unsigned char ** outbuffer, + unsigned long * outsize) { my_dest_ptr dest; @@ -287,32 +285,20 @@ jpeg_mem_dest (j_compress_ptr cinfo) dest->pub.init_destination = init_destination; dest->pub.empty_output_buffer = empty_output_buffer; dest->pub.term_destination = term_destination; - dest->buffer = NULL; - dest->buf_size = 0; + dest->buffer = outbuffer; + dest->buf_size = *outsize; + dest->outsize = outsize; + + if (*dest->buffer == NULL || dest->buf_size == 0) { + /* Allocate initial buffer */ + *dest->buffer = malloc(OUTPUT_BUF_SIZE); + if (*dest->buffer == NULL) + ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, 10); + dest->buf_size = OUTPUT_BUF_SIZE; + } + + dest->pub.next_output_byte = *dest->buffer; + dest->pub.free_in_buffer = dest->buf_size; } -GLOBAL(int) -jpeg_mem_dest_get_final_image_size (j_compress_ptr cinfo) -{ - my_dest_ptr dest = (my_dest_ptr) cinfo->dest; - - return dest->final_image_size; -} - -GLOBAL(JOCTET *) -jpeg_mem_dest_get_buffer (j_compress_ptr cinfo) -{ - my_dest_ptr dest = (my_dest_ptr) cinfo->dest; - - return dest->buffer; -} - -GLOBAL(void) -jpeg_mem_dest_free_buffer (j_compress_ptr cinfo) -{ - my_dest_ptr dest = (my_dest_ptr) cinfo->dest; - - free (dest->buffer); - dest->buffer = NULL; - dest->buf_size = 0; -} +#endif diff --git a/camlibs/ax203/jpeg_memsrcdest.h b/camlibs/ax203/jpeg_memsrcdest.h index 221491f02..e97118246 100644 --- a/camlibs/ax203/jpeg_memsrcdest.h +++ b/camlibs/ax203/jpeg_memsrcdest.h @@ -1,9 +1,9 @@ #include void -jpeg_mem_src (j_decompress_ptr cinfo, const JOCTET * buffer, size_t bufsize); +jpeg_mem_src (j_decompress_ptr cinfo, unsigned char * buffer, + unsigned long bufsize); -void jpeg_mem_dest (j_compress_ptr cinfo); -int jpeg_mem_dest_get_final_image_size (j_compress_ptr cinfo); -JOCTET * jpeg_mem_dest_get_buffer (j_compress_ptr cinfo); -void jpeg_mem_dest_free_buffer (j_compress_ptr cinfo); +void +jpeg_mem_dest (j_compress_ptr cinfo, unsigned char ** outbuffer, + unsigned long * outsize);