From: Vineeth TM Date: Thu, 25 Feb 2016 22:57:40 +0000 (+0900) Subject: Gif: Add support for progressive gif animation encoding. X-Git-Tag: submit/tizen/20160310.030656^0 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=9255289191e4864445e0b0fd7adfd76ca4b1a64d;p=platform%2Fcore%2Fapi%2Fimage-util.git Gif: Add support for progressive gif animation encoding. In case of systems with memory limitations, there should be a way to continue with encoding as soon as we get each frame, instead of waiting for all the frames. By calling encode_run for each frame this can be achieved. Change-Id: I38b52c528d0c3b59b552888faa5a6de8cb053596 Signed-off-by: Vineeth TM --- diff --git a/decode-test/image_util_decode_encode_testsuite.c b/decode-test/image_util_decode_encode_testsuite.c index c0dae25..105853d 100755 --- a/decode-test/image_util_decode_encode_testsuite.c +++ b/decode-test/image_util_decode_encode_testsuite.c @@ -166,7 +166,7 @@ int main(int argc, char *argv[]) image_util_encode_h encoded = NULL; void *src = NULL; unsigned char *data = NULL; - unsigned char **animated_data = NULL; + unsigned char *animated_data = NULL; unsigned char *dst = NULL; unsigned long long src_size = 0; int encode_image_type = -1; @@ -218,8 +218,21 @@ int main(int argc, char *argv[]) return 0; } + ret = image_util_encode_create(IMAGE_UTIL_GIF, &encoded); + if (ret != IMAGE_UTIL_ERROR_NONE) + return 0; + + if (!strcmp("encode-gif-mem", argv[1])) { + ret = image_util_encode_set_output_buffer(encoded, &dst); + if (ret != IMAGE_UTIL_ERROR_NONE) + return 0; + } else { + ret = image_util_encode_set_output_path(encoded, gif_filename); + if (ret != IMAGE_UTIL_ERROR_NONE) + return 0; + } + for (i = 0; i < number_files; i++) { - animated_data = (unsigned char **)realloc(animated_data, (i + 1) * sizeof(unsigned char *)); ret = image_util_decode_create(&decoded); if (ret != IMAGE_UTIL_ERROR_NONE) return 0; @@ -230,7 +243,7 @@ int main(int argc, char *argv[]) if (ret != IMAGE_UTIL_ERROR_NONE) return 0; - ret = image_util_decode_set_output_buffer(decoded, &animated_data[i]); + ret = image_util_decode_set_output_buffer(decoded, &animated_data); if (ret != IMAGE_UTIL_ERROR_NONE) return 0; @@ -241,53 +254,35 @@ int main(int argc, char *argv[]) ret = image_util_decode_destroy(decoded); if (ret != IMAGE_UTIL_ERROR_NONE) return 0; - } - ret = image_util_encode_create(IMAGE_UTIL_GIF, &encoded); - if (ret != IMAGE_UTIL_ERROR_NONE) - return 0; - - for (i = 0; i < number_files; i++) { - ret = image_util_encode_set_input_buffer(encoded, animated_data[i]); + ret = image_util_encode_set_input_buffer(encoded, animated_data); if (ret != IMAGE_UTIL_ERROR_NONE) return 0; - } - for (i = 0; i < number_files; i++) { + ret = image_util_encode_set_resolution(encoded, gif_image_width[i], gif_image_height[i]); if (ret != IMAGE_UTIL_ERROR_NONE) return 0; - } - for (i = 0; i < number_files; i++) { + ret = image_util_encode_set_gif_frame_delay_time(encoded, 10); if (ret != IMAGE_UTIL_ERROR_NONE) return 0; - } - if (!strcmp("encode-gif-mem", argv[1])) { - ret = image_util_encode_set_output_buffer(encoded, &dst); - if (ret != IMAGE_UTIL_ERROR_NONE) - return 0; - } else { - ret = image_util_encode_set_output_path(encoded, gif_filename); + + ret = image_util_encode_run(encoded, &image_size); if (ret != IMAGE_UTIL_ERROR_NONE) return 0; + + free(animated_data); } - ret = image_util_encode_run(encoded, &image_size); + + ret = image_util_encode_destroy(encoded); if (ret != IMAGE_UTIL_ERROR_NONE) return 0; if (!strcmp("encode-gif-mem", argv[1])) { _write_file(gif_filename, (void *)dst, image_size); free(dst); + dst = NULL; } - - ret = image_util_encode_destroy(encoded); - if (ret != IMAGE_UTIL_ERROR_NONE) - return 0; - - for (i = 0; i < number_files; i++) - free(animated_data[i]); - free(animated_data); - return 0; } else if (!strcmp("decode", argv[1]) || !strcmp("decode-mem", argv[1]) || !strcmp("decode-async", argv[1])) { if (argc < 4) { @@ -400,15 +395,14 @@ int main(int argc, char *argv[]) if (ret != IMAGE_UTIL_ERROR_NONE) return 0; - if (!strcmp("decode-mem", argv[1]) && (encode_image_type != IMAGE_UTIL_BMP)) { - _write_file(filename, (void *)dst, image_size); - free(dst); - } - ret = image_util_encode_destroy(encoded); if (ret != IMAGE_UTIL_ERROR_NONE) return 0; + if (!strcmp("decode-mem", argv[1]) && (encode_image_type != IMAGE_UTIL_BMP)) { + _write_file(filename, (void *)dst, image_size); + free(dst); + } free(data); } else { fprintf(stderr, "\tDECODED data is NULL\n"); diff --git a/include/image_util.h b/include/image_util.h index dc45078..4d98207 100755 --- a/include/image_util.h +++ b/include/image_util.h @@ -1360,7 +1360,8 @@ int image_util_encode_set_output_path(image_util_encode_h handle, const char *pa * * @remarks One of image_util_encode_set_output_path() or image_util_encode_set_output_buffer() should be set.\n * If both are set then the latest output set is considered.\n -* Output buffer setting is not supported for bmp. IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT will be returned for bmp. +* Output buffer setting is not supported for bmp. IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT will be returned for bmp.\n +* In case of gif encoding, the output buffer will be completely available only after image_util_encode_destroy(). * * @param[in] handle The handle to image util encoding * @param[in] dst_buffer The output image buffer @@ -1396,6 +1397,7 @@ int image_util_encode_set_output_buffer(image_util_encode_h handle, unsigned cha * When any of the @pre functions are not called, IMAGE_UTIL_ERROR_INVALID_PARAMETER is returned.\n * In case of animated gif encoding, image_util_encode_set_resolution(), image_util_encode_set_input_buffer() and\n * image_util_encode_set_gif_frame_delay_time() MUST be called for each frame. +* In case of animated gif encoding, call image_util_encode_run() for each frame to encode progressively. * * @param[in] handle The handle to image util encoding * @param[out] size Size of the encoded image @@ -1433,6 +1435,7 @@ int image_util_encode_run(image_util_encode_h handle, unsigned long long *size); * When any of the @pre functions are not called, IMAGE_UTIL_ERROR_INVALID_PARAMETER is returned.\n * In case of animated gif encoding, image_util_encode_set_resolution(), image_util_encode_set_input_buffer() and\n * image_util_encode_set_gif_frame_delay_time() MUST be called for each frame. +* In case of animated gif encoding, call image_util_encode_run_async() for each frame to encode progressively. * * @param[in] handle The handle to image util encoding * @param[in] callback The callback function to be invoked diff --git a/src/image_util.c b/src/image_util.c index 92ac54b..649df80 100755 --- a/src/image_util.c +++ b/src/image_util.c @@ -1925,6 +1925,17 @@ int image_util_encode_set_output_path(image_util_encode_h handle, const char *pa _handle->dst_buffer = NULL; _handle->path = path; + if (_handle->image_type == IMAGE_UTIL_GIF) { + mm_util_gif_data *gif_data; + + gif_data = (mm_util_gif_data *) _handle->image_h; + + if (gif_data->frames == NULL) { + image_util_error("Error allocating gif frames."); + return IMAGE_UTIL_ERROR_INVALID_PARAMETER; + } + mm_util_encode_open_gif_file(gif_data, path); + } return err; } @@ -1951,6 +1962,17 @@ int image_util_encode_set_output_buffer(image_util_encode_h handle, unsigned cha _handle->path = NULL; _handle->dst_buffer = (void **)dst_buffer; + if (_handle->image_type == IMAGE_UTIL_GIF) { + mm_util_gif_data *gif_data; + + gif_data = (mm_util_gif_data *) _handle->image_h; + + if (gif_data->frames == NULL) { + image_util_error("Error allocating gif frames."); + return IMAGE_UTIL_ERROR_INVALID_PARAMETER; + } + mm_util_encode_open_gif_memory(gif_data, _handle->dst_buffer); + } return err; } @@ -1995,7 +2017,6 @@ static int _image_util_encode_internal(decode_encode_s * _handle) case IMAGE_UTIL_GIF: { mm_util_gif_data *gif_data; - void *dst_buffer = NULL; gif_data = (mm_util_gif_data *) _handle->image_h; if (gif_data == NULL) { @@ -2008,14 +2029,9 @@ static int _image_util_encode_internal(decode_encode_s * _handle) } mm_util_gif_encode_set_image_count(gif_data, _handle->image_count); - if (_handle->path) - err = mm_util_encode_gif_to_file(gif_data, _handle->path); - else - err = mm_util_encode_gif_to_memory(gif_data, &dst_buffer); + err = mm_util_encode_gif(gif_data); if (err == MM_UTIL_ERROR_NONE) { - if (_handle->dst_buffer) - *(_handle->dst_buffer) = (unsigned char *)dst_buffer; _handle->dst_size = gif_data->size; _handle->width = gif_data->width; _handle->height = gif_data->height; @@ -2229,6 +2245,7 @@ int image_util_encode_destroy(image_util_encode_h handle) image_util_error("Invalid gif data"); return IMAGE_UTIL_ERROR_INVALID_PARAMETER; } + mm_util_encode_close_gif(gif_data); for (i = 1; i < _handle->image_count; i++) IMAGE_UTIL_SAFE_FREE(gif_data->frames[i]); IMAGE_UTIL_SAFE_FREE(gif_data->frames[0]);