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);