From: jiyong.min Date: Thu, 2 Jul 2020 00:38:09 +0000 (+0900) Subject: [ACR-1584] Supports WebP encode and decode X-Git-Tag: submit/tizen/20200803.051111^0 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=0820dd34721f40543a288f3f6b8e26ba5cfda75d;p=platform%2Fcore%2Fapi%2Fimage-util.git [ACR-1584] Supports WebP encode and decode Change-Id: I2fbe8155b8f9ff276eefa62f568cb09c8627c74b --- diff --git a/doc/image_util_doc.h b/doc/image_util_doc.h index 9dd6782..ca38b37 100755 --- a/doc/image_util_doc.h +++ b/doc/image_util_doc.h @@ -71,13 +71,13 @@ * @section CAPI_MEDIA_IMAGE_UTIL_MODULE_ENCODE_DECODE_OVERVIEW Overview * * Image Util API provides support for encoding and decoding of images. The API allows : - *- Encoding of a JPEG/PNG/GIF/BMP image. - *- Decoding of a JPEG/PNG/GIF/BMP image. + *- Encoding of a JPEG/PNG/GIF/BMP and WEBP(Since 6.0) image. + *- Decoding of a JPEG/PNG/GIF/BMP and WEBP(Since 6.0) image. * Encoding supports gif images including the animated, but decoding gif does not support the animated. * * The decoding of a jpeg/png/gif/bmp image located at a given path, to a buffer can be done by calling #image_util_decode_run() function and decoding of a jpeg image on memory * can be done by calling #image_util_decode_set_output_buffer(). Similarly, for encoding #image_util_encode_run() and #image_util_encode_set_output_buffer() functions can be called - * to encode an image buffer to a jpeg/png/gif/bmp image and a buffer respectively. + * to encode an image buffer to a jpeg/png/gif/bmp/webp image and a buffer respectively. * * @subsection CAPI_MEDIA_IMAGE_UTIL_ENCODE_DECODE_FOREACH_OPERATIONS Foreach Operations *
@@ -89,7 +89,7 @@ * * * - * + * * *
image_util_foreach_supported_colorspace()image_util_supported_colorspace_cb() Supported JPEG/PNG/GIF/BMP encoding/decoding colorspace Supported JPEG/PNG/GIF/BMP/WEBP encoding/decoding colorspace
*/ diff --git a/include/image_util.h b/include/image_util.h index 18173da..9fa533d 100644 --- a/include/image_util.h +++ b/include/image_util.h @@ -73,8 +73,8 @@ int image_util_calculate_buffer_size(int width, int height, image_util_colorspac * * @retval #IMAGE_UTIL_ERROR_NONE Successful * @retval #IMAGE_UTIL_ERROR_INVALID_PARAMETER Invalid parameter -* @retval #IMAGE_UTIL_ERROR_OUT_OF_MEMORY Out of memory * @retval #IMAGE_UTIL_ERROR_INVALID_OPERATION Invalid operation +* @retval #IMAGE_UTIL_ERROR_OUT_OF_MEMORY Out of memory * */ int image_util_extract_color_from_memory(const unsigned char *image_buffer, int width, int height, unsigned char *rgb_r, unsigned char *rgb_g, unsigned char *rgb_b); diff --git a/include/image_util_decode.h b/include/image_util_decode.h index 7cd24ee..c78bc1d 100644 --- a/include/image_util_decode.h +++ b/include/image_util_decode.h @@ -58,7 +58,8 @@ int image_util_decode_create(image_util_decode_h *handle); * If both are set then the latest input set, is considered.\n * http://tizen.org/privilege/mediastorage is needed if input or output path are relevant to media storage.\n * http://tizen.org/privilege/externalstorage is needed if input or output path are relevant to external storage.\n -* Finds out image type by reading the header of the image provided in input path. +* Finds out image type by reading the header of the image provided in input path.\n +* Since 6.0, this module supports WEBP image format. * * @param[in] handle The handle of image util decoding * @param[in] path The path to input image @@ -67,12 +68,12 @@ int image_util_decode_create(image_util_decode_h *handle); * otherwise a negative error value * * @retval #IMAGE_UTIL_ERROR_NONE Successful -* @retval #IMAGE_UTIL_ERROR_NO_SUCH_FILE No such file * @retval #IMAGE_UTIL_ERROR_INVALID_PARAMETER Invalid parameter * @retval #IMAGE_UTIL_ERROR_INVALID_OPERATION Invalid operation * @retval #IMAGE_UTIL_ERROR_PERMISSION_DENIED The application does not have the privilege to call this function * @retval #IMAGE_UTIL_ERROR_OUT_OF_MEMORY Out of memory * @retval #IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT Not supported format +* @retval #IMAGE_UTIL_ERROR_NO_SUCH_FILE No such file * * @pre image_util_decode_create() * @@ -92,7 +93,8 @@ int image_util_decode_set_input_path(image_util_decode_h handle, const char *pat * * @remarks One of image_util_decode_set_input_path() or image_util_decode_set_input_buffer() should be set.\n * If both are set then the latest input set, is considered.\n -* Finds out image type by reading the header of the image provided in input buffer. +* Finds out image type by reading the header of the image provided in input buffer.\n +* Since 6.0, this module supports WEBP image format. * * @param[in] handle The handle of image util decoding * @param[in] src_buffer The input image buffer diff --git a/include/image_util_encode.h b/include/image_util_encode.h index 8fe24da..0d47a8f 100644 --- a/include/image_util_encode.h +++ b/include/image_util_encode.h @@ -111,8 +111,8 @@ int image_util_encode_set_resolution(image_util_encode_h handle, unsigned long w * otherwise a negative error value * * @retval #IMAGE_UTIL_ERROR_NONE Successful -* @retval #IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT Not supported format * @retval #IMAGE_UTIL_ERROR_INVALID_PARAMETER Invalid parameter +* @retval #IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT Not supported format * * @pre image_util_encode_create() * @@ -146,8 +146,8 @@ int image_util_encode_set_colorspace(image_util_encode_h handle, image_util_colo * otherwise a negative error value * * @retval #IMAGE_UTIL_ERROR_NONE Successful -* @retval #IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT Not supported format * @retval #IMAGE_UTIL_ERROR_INVALID_PARAMETER Invalid parameter +* @retval #IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT Not supported format * * @pre image_util_encode_create() * @@ -176,9 +176,9 @@ int image_util_encode_set_quality(image_util_encode_h handle, int quality); * otherwise a negative error value * * @retval #IMAGE_UTIL_ERROR_NONE Successful -* @retval #IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT Not supported format * @retval #IMAGE_UTIL_ERROR_INVALID_PARAMETER Invalid parameter * @retval #IMAGE_UTIL_ERROR_INVALID_OPERATION Invalid operation +* @retval #IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT Not supported format * * @pre image_util_encode_create() * @@ -194,6 +194,37 @@ int image_util_encode_set_quality(image_util_encode_h handle, int quality); */ int image_util_encode_set_png_compression(image_util_encode_h handle, image_util_png_compression_e compression); +/** +* @brief Sets lossless compression of WEBP images. +* @since_tizen 6.0 +* +* @remarks If application does not set this, then the default value is false. +* +* @param[in] handle The handle of image util encoding +* @param[in] lossless The flag determining whether the compression is lossless or lossy: true for lossless, false for lossy +* +* @return @c 0 on success, +* otherwise a negative error value +* +* @retval #IMAGE_UTIL_ERROR_NONE Successful +* @retval #IMAGE_UTIL_ERROR_INVALID_PARAMETER Invalid parameter +* @retval #IMAGE_UTIL_ERROR_INVALID_OPERATION Invalid operation +* @retval #IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT Not supported format +* +* @pre image_util_encode_create() +* +* @post image_util_encode_run() / image_util_encode_run_async() +* @post image_util_encode_destroy() +* +* @see image_util_encode_create() +* @see image_util_encode_run_to_file() +* @see image_util_encode_run_to_buffer() +* @see image_util_encode_run_async_to_file() +* @see image_util_encode_run_async_to_buffer() +* @see image_util_encode_destroy() +*/ +int image_util_encode_set_webp_lossless(image_util_encode_h handle, bool lossless); + /** * @deprecated Deprecated since 5.5. Use image_util_agif_encode_add_frame() instead. * @brief Sets the time delay between each frame in the encoded animated GIF image. @@ -210,8 +241,8 @@ int image_util_encode_set_png_compression(image_util_encode_h handle, image_util * otherwise a negative error value * * @retval #IMAGE_UTIL_ERROR_NONE Successful -* @retval #IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT Not supported format * @retval #IMAGE_UTIL_ERROR_INVALID_PARAMETER Invalid parameter +* @retval #IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT Not supported format * * @pre image_util_encode_create() * @@ -428,6 +459,7 @@ int image_util_encode_run_async(image_util_encode_h handle, image_util_encode_co * http://tizen.org/privilege/externalstorage is required if @a file_path value is external storage.\n * Before 6.0, IMAGE_UTIL_COLORSPACE_RGBA8888 was the only supported colorspace for PNG. But since 6.0, this module supports more colorspaces for PNG. * To get supported colorspaces for PNG, you can use image_util_foreach_supported_colorspace().\n +* Since 6.0, this module supports WEBP, you can use image_util_foreach_supported_colorspace() to get supported colorspaces for WEBP.\n * * @param[in] handle The handle of image util encoding * @param[in] image The image handle for encoding @@ -437,11 +469,11 @@ int image_util_encode_run_async(image_util_encode_h handle, image_util_encode_co * otherwise a negative error value * * @retval #IMAGE_UTIL_ERROR_NONE Successful -* @retval #IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT Not supported format * @retval #IMAGE_UTIL_ERROR_PERMISSION_DENIED Permission denied * @retval #IMAGE_UTIL_ERROR_INVALID_PARAMETER Invalid parameter * @retval #IMAGE_UTIL_ERROR_INVALID_OPERATION Invalid operation * @retval #IMAGE_UTIL_ERROR_OUT_OF_MEMORY Out of memory +* @retval #IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT Not supported format * * @pre image_util_encode_create() * @@ -463,6 +495,7 @@ int image_util_encode_run_to_file(image_util_encode_h handle, image_util_image_h * To get supported colorspaces for JPEG format, you can use image_util_foreach_supported_colorspace().\n * Before 6.0, IMAGE_UTIL_COLORSPACE_RGBA8888 was the only supported colorspace for PNG. But since 6.0, this module supports more colorspaces for PNG. * To get supported colorspaces for PNG, you can use image_util_foreach_supported_colorspace().\n +* Since 6.0, this module supports WEBP, you can use image_util_foreach_supported_colorspace() to get supported colorspaces for WEBP.\n * * @param[in] handle The handle of image util encoding * @param[in] image The image handle for encoding @@ -473,10 +506,10 @@ int image_util_encode_run_to_file(image_util_encode_h handle, image_util_image_h * otherwise a negative error value * * @retval #IMAGE_UTIL_ERROR_NONE Successful -* @retval #IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT Not supported format * @retval #IMAGE_UTIL_ERROR_INVALID_PARAMETER Invalid parameter * @retval #IMAGE_UTIL_ERROR_INVALID_OPERATION Invalid operation * @retval #IMAGE_UTIL_ERROR_OUT_OF_MEMORY Out of memory +* @retval #IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT Not supported format * * @pre image_util_encode_create() * @@ -499,6 +532,7 @@ int image_util_encode_run_to_buffer(image_util_encode_h handle, image_util_image * http://tizen.org/privilege/externalstorage is required if @a file_path value is external storage.\n * Before 6.0, IMAGE_UTIL_COLORSPACE_RGBA8888 was the only supported colorspace for PNG. But since 6.0, this module supports more colorspaces for PNG. * To get supported colorspaces for PNG, you can use image_util_foreach_supported_colorspace().\n +* Since 6.0, this module supports WEBP, you can use image_util_foreach_supported_colorspace() to get supported colorspaces for WEBP.\n * * @param[in] handle The handle of image util encoding * @param[in] image The image handle for encoding @@ -534,6 +568,7 @@ int image_util_encode_run_async_to_file(image_util_encode_h handle, image_util_i * To get supported colorspaces for JPEG format, you can use image_util_foreach_supported_colorspace().\n * Before 6.0, IMAGE_UTIL_COLORSPACE_RGBA8888 was the only supported colorspace for PNG. But since 6.0, this module supports more colorspaces for PNG. * To get supported colorspaces for PNG, you can use image_util_foreach_supported_colorspace().\n +* Since 6.0, this module supports WEBP, you can use image_util_foreach_supported_colorspace() to get supported colorspaces for WEBP.\n * * @param[in] handle The handle of image util encoding * @param[in] image The image handle for encoding @@ -621,10 +656,10 @@ int image_util_agif_encode_create(image_util_agif_encode_h *handle); * otherwise a negative error value * * @retval #IMAGE_UTIL_ERROR_NONE Successful -* @retval #IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT Not supported format * @retval #IMAGE_UTIL_ERROR_INVALID_PARAMETER Invalid parameter * @retval #IMAGE_UTIL_ERROR_INVALID_OPERATION Invalid operation * @retval #IMAGE_UTIL_ERROR_OUT_OF_MEMORY Out of memory +* @retval #IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT Not supported format * * @pre image_util_agif_encode_create() * diff --git a/include/image_util_private.h b/include/image_util_private.h index 9d95ea7..ff08fc4 100644 --- a/include/image_util_private.h +++ b/include/image_util_private.h @@ -116,7 +116,7 @@ typedef struct { } transformation_s; #define IMAGE_UTIL_TYPE_CHECK(type) \ - image_util_retvm_if((type < IMAGE_UTIL_JPEG || type > IMAGE_UTIL_BMP), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid image type [%d]", type) + image_util_retvm_if((type < IMAGE_UTIL_JPEG || type > IMAGE_UTIL_WEBP), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid image type [%d]", type) #define IMAGE_UTIL_SUPPORT_TYPE_CHECK(value, support) \ image_util_retvm_if((value != support), IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT, "Not supported format") diff --git a/include/image_util_type.h b/include/image_util_type.h index b3ae80a..80ef349 100644 --- a/include/image_util_type.h +++ b/include/image_util_type.h @@ -171,6 +171,7 @@ typedef enum { IMAGE_UTIL_PNG, /**< Image format PNG */ IMAGE_UTIL_GIF, /**< Image format GIF */ IMAGE_UTIL_BMP, /**< Image format BMP */ + IMAGE_UTIL_WEBP, /**< Image format WEBP (Since 6.0) */ } image_util_type_e; /** diff --git a/src/image_util_decode.c b/src/image_util_decode.c index a43e666..3d2f870 100644 --- a/src/image_util_decode.c +++ b/src/image_util_decode.c @@ -60,7 +60,7 @@ static int _convert_decode_scale_tbl[] = { #define _NUM_OF_SCALE (sizeof(_convert_decode_scale_tbl)/sizeof(int)) #define _NOT_SUPPORTED_IMAGE_TYPE (-1) -#define IMG_HEADER_LENGTH 8 +#define IMG_HEADER_LENGTH 12 static int __image_util_decode_read_header(const char *path, unsigned char **buffer) { @@ -98,20 +98,23 @@ static int __image_util_decode_read_header(const char *path, unsigned char **buf static int __image_util_decode_check_image_type(const unsigned char *image_buffer, image_util_type_e *image_type) { - static char _JPEG_HEADER[] = { 0xFF, 0xD8 }; - static char _PNG_HEADER[] = { 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a }; - static char _GIF_HEADER[] = { 'G', 'I', 'F' }; - static char _BMP_HEADER[] = { 'B', 'M' }; + static unsigned char _JPEG_HEADER[] = { 0xFF, 0xD8 }; + static unsigned char _PNG_HEADER[] = { 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a }; + static unsigned char _GIF_HEADER[] = { 'G', 'I', 'F' }; + static unsigned char _BMP_HEADER[] = { 'B', 'M' }; + static unsigned char _WEBP_HEADER[] = { 0x57, 0x45, 0x42, 0x50 }; static struct { - char *header; - int size; image_util_type_e image_type; - } image_header[] = { - { _JPEG_HEADER, sizeof(_JPEG_HEADER), IMAGE_UTIL_JPEG }, - { _PNG_HEADER, sizeof(_PNG_HEADER), IMAGE_UTIL_PNG }, - { _GIF_HEADER, sizeof(_GIF_HEADER), IMAGE_UTIL_GIF }, - { _BMP_HEADER, sizeof(_BMP_HEADER), IMAGE_UTIL_BMP } + unsigned char *signature; + unsigned int size; + unsigned int offset; + } signature_info[] = { + { IMAGE_UTIL_JPEG, _JPEG_HEADER, sizeof(_JPEG_HEADER), 0 }, + { IMAGE_UTIL_PNG, _PNG_HEADER, sizeof(_PNG_HEADER), 0 }, + { IMAGE_UTIL_GIF, _GIF_HEADER, sizeof(_GIF_HEADER), 0 }, + { IMAGE_UTIL_BMP, _BMP_HEADER, sizeof(_BMP_HEADER), 0 }, + { IMAGE_UTIL_WEBP, _WEBP_HEADER, sizeof(_WEBP_HEADER), 8 } ,}; unsigned int i = 0; @@ -119,9 +122,9 @@ static int __image_util_decode_check_image_type(const unsigned char *image_buffe image_util_retvm_if(!image_type, IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid image_type"); *image_type = _NOT_SUPPORTED_IMAGE_TYPE; /* init */ - for (i = 0; i < sizeof(image_header) / sizeof(image_header[0]); i++) { - if (strncmp((const char *)image_buffer, image_header[i].header, image_header[i].size) == 0) { - *image_type = image_header[i].image_type; + for (i = 0; i < sizeof(signature_info) / sizeof(signature_info[0]); i++) { + if (memcmp((const char *)image_buffer + signature_info[i].offset, signature_info[i].signature, signature_info[i].size) == 0) { + *image_type = signature_info[i].image_type; break; } } @@ -276,6 +279,8 @@ static int __image_util_decode_internal(decode_s *_handle, mm_util_image_h *imag case IMAGE_UTIL_PNG: /* fall through */ case IMAGE_UTIL_BMP: + /* fall through */ + case IMAGE_UTIL_WEBP: { if (_handle->path) err = mm_util_decode_image_from_file(_handle->path, _handle->colorspace, image_info); @@ -367,6 +372,8 @@ static int __image_util_decode_run_from_file(image_util_decode_h handle, const c case IMAGE_UTIL_PNG: /* fall through */ case IMAGE_UTIL_BMP: + /* fall through */ + case IMAGE_UTIL_WEBP: ret = mm_util_decode_image_from_file(file_path, _handle->colorspace, image); break; @@ -416,6 +423,8 @@ static int __image_util_decode_run_from_buffer(image_util_decode_h handle, const case IMAGE_UTIL_PNG: /* fall through */ case IMAGE_UTIL_BMP: + /* fall through */ + case IMAGE_UTIL_WEBP: ret = mm_util_decode_image_from_buffer((void *)buffer, buffer_size, _handle->colorspace, image); break; diff --git a/src/image_util_encode.c b/src/image_util_encode.c index aeb75a0..d4229d2 100644 --- a/src/image_util_encode.c +++ b/src/image_util_encode.c @@ -239,6 +239,15 @@ int image_util_encode_set_png_compression(image_util_encode_h handle, image_util return _image_error_capi(mm_util_enc_opt_set_png_compression(_handle->enc_opt, compression)); } +int image_util_encode_set_webp_lossless(image_util_encode_h handle, bool lossless) +{ + encode_s *_handle = (encode_s *) handle; + + image_util_retvm_if(!_handle, IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle"); + + return _image_error_capi(mm_util_enc_opt_set_webp_lossless(_handle->enc_opt, lossless)); +} + int image_util_encode_set_gif_frame_delay_time(image_util_encode_h handle, unsigned long long delay_time) { int err = IMAGE_UTIL_ERROR_NONE; @@ -340,36 +349,35 @@ static int __image_util_encode_internal(encode_s * _handle) switch (_handle->image_type) { case IMAGE_UTIL_JPEG: - { - if (_handle->path) - err = mm_util_jpeg_encode_to_file(_src, _handle->quality, _handle->path); - else - err = mm_util_encode_to_jpeg_memory(_src, _handle->quality, _handle->dst_buffer, &_handle->dst_size); - } + if (_handle->path) + err = mm_util_jpeg_encode_to_file(_src, _handle->quality, _handle->path); + else + err = mm_util_encode_to_jpeg_memory(_src, _handle->quality, _handle->dst_buffer, &_handle->dst_size); break; case IMAGE_UTIL_GIF: - { - image_util_debug("[Count] source_count:%u, buffer:%u, resolution:%u, delay:%u", _handle->gif_encode_info.source_count, _handle->gif_encode_info.current_buffer_count, _handle->gif_encode_info.current_resolution_count, _handle->gif_encode_info.current_delay_count); - if ((_handle->gif_encode_info.source_count > 1) && ((_handle->gif_encode_info.source_count != _handle->gif_encode_info.current_buffer_count) || (_handle->gif_encode_info.source_count != _handle->gif_encode_info.current_resolution_count) || (_handle->gif_encode_info.source_count != _handle->gif_encode_info.current_delay_count))) { - image_util_error("Total frame count does not match with the data set, for animated gif encoding"); - return IMAGE_UTIL_ERROR_INVALID_OPERATION; - } - - if (_handle->path) - err = mm_util_encode_to_gif_file((mm_util_image_h *)_handle->gif_encode_info.sources, _handle->gif_encode_info.source_count, _handle->path); - else - err = mm_util_encode_to_gif_memory((mm_util_image_h *)_handle->gif_encode_info.sources, _handle->gif_encode_info.source_count, _handle->dst_buffer, &_handle->dst_size); + image_util_debug("[Count] source_count:%u, buffer:%u, resolution:%u, delay:%u", _handle->gif_encode_info.source_count, _handle->gif_encode_info.current_buffer_count, _handle->gif_encode_info.current_resolution_count, _handle->gif_encode_info.current_delay_count); + if ((_handle->gif_encode_info.source_count > 1) && + ((_handle->gif_encode_info.source_count != _handle->gif_encode_info.current_buffer_count) || + (_handle->gif_encode_info.source_count != _handle->gif_encode_info.current_resolution_count) || + (_handle->gif_encode_info.source_count != _handle->gif_encode_info.current_delay_count))) { + image_util_error("Total frame count does not match with the data set, for animated gif encoding"); + return IMAGE_UTIL_ERROR_INVALID_OPERATION; } + + if (_handle->path) + err = mm_util_encode_to_gif_file((mm_util_image_h *)_handle->gif_encode_info.sources, _handle->gif_encode_info.source_count, _handle->path); + else + err = mm_util_encode_to_gif_memory((mm_util_image_h *)_handle->gif_encode_info.sources, _handle->gif_encode_info.source_count, _handle->dst_buffer, &_handle->dst_size); break; case IMAGE_UTIL_PNG: /* fall through */ case IMAGE_UTIL_BMP: - { - if (_handle->path) - err = mm_util_encode_image_to_file(_src, _handle->enc_opt, _handle->path); - else - err = mm_util_encode_image_to_buffer(_src, _handle->enc_opt, _handle->dst_buffer, &_handle->dst_size); - } + /* fall through */ + case IMAGE_UTIL_WEBP: + if (_handle->path) + err = mm_util_encode_image_to_file(_src, _handle->enc_opt, _handle->path); + else + err = mm_util_encode_image_to_buffer(_src, _handle->enc_opt, _handle->dst_buffer, &_handle->dst_size); break; default: return IMAGE_UTIL_ERROR_INVALID_PARAMETER; @@ -414,6 +422,8 @@ static int __image_util_encode_run_to_file(image_util_encode_h handle, image_uti case IMAGE_UTIL_PNG: /* fall through */ case IMAGE_UTIL_BMP: + /* fall through */ + case IMAGE_UTIL_WEBP: ret = mm_util_encode_image_to_file(image, _handle->enc_opt, file_path); break; @@ -455,6 +465,8 @@ static int __image_util_encode_run_to_buffer(image_util_encode_h handle, image_u case IMAGE_UTIL_PNG: /* fall through */ case IMAGE_UTIL_BMP: + /* fall through */ + case IMAGE_UTIL_WEBP: ret = mm_util_encode_image_to_buffer(image, _handle->enc_opt, (void **)buffer, buffer_size); break; default: diff --git a/src/image_util_private.c b/src/image_util_private.c index f89300d..308fc69 100755 --- a/src/image_util_private.c +++ b/src/image_util_private.c @@ -45,93 +45,111 @@ static const image_format_mimetype_pair_s image_format_mimetype_table[] = { static const unsigned int image_format_mimetype_table_size = sizeof(image_format_mimetype_table) / sizeof(image_format_mimetype_pair_s); static int _convert_colorspace_tbl[] = { - MM_UTIL_COLOR_YUV420, /* IMAGE_UTIL_COLORSPACE_YUV420 */ - MM_UTIL_COLOR_YUV422, /* IMAGE_UTIL_COLORSPACE_YUV422 */ - MM_UTIL_COLOR_I420, /* IMAGE_UTIL_COLORSPACE_I420 */ - MM_UTIL_COLOR_NV12, /* IMAGE_UTIL_COLORSPACE_NV12 */ - MM_UTIL_COLOR_UYVY, /* IMAGE_UTIL_COLORSPACE_UYVY */ - MM_UTIL_COLOR_YUYV, /* IMAGE_UTIL_COLORSPACE_YUYV */ - MM_UTIL_COLOR_RGB16, /* IMAGE_UTIL_COLORSPACE_RGB565 */ - MM_UTIL_COLOR_RGB24, /* IMAGE_UTIL_COLORSPACE_RGB888 */ - MM_UTIL_COLOR_ARGB, /* IMAGE_UTIL_COLORSPACE_ARGB8888 */ - MM_UTIL_COLOR_BGRA, /* IMAGE_UTIL_COLORSPACE_BGRA8888 */ - MM_UTIL_COLOR_RGBA, /* IMAGE_UTIL_COLORSPACE_RGBA8888 */ - MM_UTIL_COLOR_BGRX, /* IMAGE_UTIL_COLORSPACE_BGRX8888 */ - MM_UTIL_COLOR_NV21, /* IMAGE_UTIL_COLORSPACE_NV12 */ - MM_UTIL_COLOR_NV16, /* IMAGE_UTIL_COLORSPACE_NV16 */ - MM_UTIL_COLOR_NV61, /* IMAGE_UTIL_COLORSPACE_NV61 */ + [IMAGE_UTIL_COLORSPACE_YV12] = MM_UTIL_COLOR_YUV420, + [IMAGE_UTIL_COLORSPACE_YUV422] = MM_UTIL_COLOR_YUV422, + [IMAGE_UTIL_COLORSPACE_I420] = MM_UTIL_COLOR_YUV420, + [IMAGE_UTIL_COLORSPACE_NV12] = MM_UTIL_COLOR_NV12, + [IMAGE_UTIL_COLORSPACE_UYVY] = MM_UTIL_COLOR_UYVY, + [IMAGE_UTIL_COLORSPACE_YUYV] = MM_UTIL_COLOR_YUYV, + [IMAGE_UTIL_COLORSPACE_RGB565] = MM_UTIL_COLOR_RGB16, + [IMAGE_UTIL_COLORSPACE_RGB888] = MM_UTIL_COLOR_RGB24, + [IMAGE_UTIL_COLORSPACE_ARGB8888] = MM_UTIL_COLOR_ARGB, + [IMAGE_UTIL_COLORSPACE_BGRA8888] = MM_UTIL_COLOR_BGRA, + [IMAGE_UTIL_COLORSPACE_RGBA8888] = MM_UTIL_COLOR_RGBA, + [IMAGE_UTIL_COLORSPACE_BGRX8888] = MM_UTIL_COLOR_BGRX, + [IMAGE_UTIL_COLORSPACE_NV21] = MM_UTIL_COLOR_NV21, + [IMAGE_UTIL_COLORSPACE_NV16] = MM_UTIL_COLOR_NV16, + [IMAGE_UTIL_COLORSPACE_NV61] = MM_UTIL_COLOR_NV61, }; static int _convert_jpeg_colorspace_tbl[] = { - MM_UTIL_COLOR_YUV420, /* IMAGE_UTIL_COLORSPACE_YUV420 */ - _NOT_SUPPORTED_COLORSPACE, /* IMAGE_UTIL_COLORSPACE_YUV422 */ - MM_UTIL_COLOR_YUV420, /* IMAGE_UTIL_COLORSPACE_I420 */ - MM_UTIL_COLOR_NV12, /* IMAGE_UTIL_COLORSPACE_NV12 */ - _NOT_SUPPORTED_COLORSPACE, /* IMAGE_UTIL_COLORSPACE_UYVY */ - _NOT_SUPPORTED_COLORSPACE, /* IMAGE_UTIL_COLORSPACE_YUYV */ - _NOT_SUPPORTED_COLORSPACE, /* IMAGE_UTIL_COLORSPACE_RGB565 */ - MM_UTIL_COLOR_RGB24, /* IMAGE_UTIL_COLORSPACE_RGB888 */ - MM_UTIL_COLOR_ARGB, /* IMAGE_UTIL_COLORSPACE_ARGB8888 */ - MM_UTIL_COLOR_BGRA, /* IMAGE_UTIL_COLORSPACE_BGRA8888 */ - MM_UTIL_COLOR_RGBA, /* IMAGE_UTIL_COLORSPACE_RGBA8888 */ - _NOT_SUPPORTED_COLORSPACE, /* IMAGE_UTIL_COLORSPACE_BGRX8888 */ - _NOT_SUPPORTED_COLORSPACE, /* IMAGE_UTIL_COLORSPACE_NV21 */ - _NOT_SUPPORTED_COLORSPACE, /* IMAGE_UTIL_COLORSPACE_NV16 */ - _NOT_SUPPORTED_COLORSPACE, /* IMAGE_UTIL_COLORSPACE_NV61 */ + [IMAGE_UTIL_COLORSPACE_YV12] = MM_UTIL_COLOR_YUV420, + [IMAGE_UTIL_COLORSPACE_YUV422] = _NOT_SUPPORTED_COLORSPACE, + [IMAGE_UTIL_COLORSPACE_I420] = MM_UTIL_COLOR_YUV420, + [IMAGE_UTIL_COLORSPACE_NV12] = MM_UTIL_COLOR_NV12, + [IMAGE_UTIL_COLORSPACE_UYVY] = _NOT_SUPPORTED_COLORSPACE, + [IMAGE_UTIL_COLORSPACE_YUYV] = _NOT_SUPPORTED_COLORSPACE, + [IMAGE_UTIL_COLORSPACE_RGB565] = _NOT_SUPPORTED_COLORSPACE, + [IMAGE_UTIL_COLORSPACE_RGB888] = MM_UTIL_COLOR_RGB24, + [IMAGE_UTIL_COLORSPACE_ARGB8888] = MM_UTIL_COLOR_ARGB, + [IMAGE_UTIL_COLORSPACE_BGRA8888] = MM_UTIL_COLOR_BGRA, + [IMAGE_UTIL_COLORSPACE_RGBA8888] = MM_UTIL_COLOR_RGBA, + [IMAGE_UTIL_COLORSPACE_BGRX8888] = _NOT_SUPPORTED_COLORSPACE, + [IMAGE_UTIL_COLORSPACE_NV21] = _NOT_SUPPORTED_COLORSPACE, + [IMAGE_UTIL_COLORSPACE_NV16] = _NOT_SUPPORTED_COLORSPACE, + [IMAGE_UTIL_COLORSPACE_NV61] = _NOT_SUPPORTED_COLORSPACE, }; static int _convert_png_colorspace_tbl[] = { - _NOT_SUPPORTED_COLORSPACE, /* IMAGE_UTIL_COLORSPACE_YUV420 */ - _NOT_SUPPORTED_COLORSPACE, /* IMAGE_UTIL_COLORSPACE_YUV422 */ - _NOT_SUPPORTED_COLORSPACE, /* IMAGE_UTIL_COLORSPACE_I420 */ - _NOT_SUPPORTED_COLORSPACE, /* IMAGE_UTIL_COLORSPACE_NV12 */ - _NOT_SUPPORTED_COLORSPACE, /* IMAGE_UTIL_COLORSPACE_UYVY */ - _NOT_SUPPORTED_COLORSPACE, /* IMAGE_UTIL_COLORSPACE_YUYV */ - _NOT_SUPPORTED_COLORSPACE, /* IMAGE_UTIL_COLORSPACE_RGB565 */ - _NOT_SUPPORTED_COLORSPACE, /* IMAGE_UTIL_COLORSPACE_RGB888 */ - MM_UTIL_COLOR_ARGB, /* IMAGE_UTIL_COLORSPACE_ARGB8888 */ - MM_UTIL_COLOR_BGRA, /* IMAGE_UTIL_COLORSPACE_BGRA8888 */ - MM_UTIL_COLOR_RGBA, /* IMAGE_UTIL_COLORSPACE_RGBA8888 */ - _NOT_SUPPORTED_COLORSPACE, /* IMAGE_UTIL_COLORSPACE_BGRX8888 */ - _NOT_SUPPORTED_COLORSPACE, /* IMAGE_UTIL_COLORSPACE_NV21 */ - _NOT_SUPPORTED_COLORSPACE, /* IMAGE_UTIL_COLORSPACE_NV16 */ - _NOT_SUPPORTED_COLORSPACE, /* IMAGE_UTIL_COLORSPACE_NV61 */ + [IMAGE_UTIL_COLORSPACE_YV12] = _NOT_SUPPORTED_COLORSPACE, + [IMAGE_UTIL_COLORSPACE_YUV422] = _NOT_SUPPORTED_COLORSPACE, + [IMAGE_UTIL_COLORSPACE_I420] = _NOT_SUPPORTED_COLORSPACE, + [IMAGE_UTIL_COLORSPACE_NV12] = _NOT_SUPPORTED_COLORSPACE, + [IMAGE_UTIL_COLORSPACE_UYVY] = _NOT_SUPPORTED_COLORSPACE, + [IMAGE_UTIL_COLORSPACE_YUYV] = _NOT_SUPPORTED_COLORSPACE, + [IMAGE_UTIL_COLORSPACE_RGB565] = _NOT_SUPPORTED_COLORSPACE, + [IMAGE_UTIL_COLORSPACE_RGB888] = _NOT_SUPPORTED_COLORSPACE, + [IMAGE_UTIL_COLORSPACE_ARGB8888] = MM_UTIL_COLOR_ARGB, + [IMAGE_UTIL_COLORSPACE_BGRA8888] = MM_UTIL_COLOR_BGRA, + [IMAGE_UTIL_COLORSPACE_RGBA8888] = MM_UTIL_COLOR_RGBA, + [IMAGE_UTIL_COLORSPACE_BGRX8888] = _NOT_SUPPORTED_COLORSPACE, + [IMAGE_UTIL_COLORSPACE_NV21] = _NOT_SUPPORTED_COLORSPACE, + [IMAGE_UTIL_COLORSPACE_NV16] = _NOT_SUPPORTED_COLORSPACE, + [IMAGE_UTIL_COLORSPACE_NV61] = _NOT_SUPPORTED_COLORSPACE, }; static int _convert_gif_colorspace_tbl[] = { - _NOT_SUPPORTED_COLORSPACE, /* IMAGE_UTIL_COLORSPACE_YUV420 */ - _NOT_SUPPORTED_COLORSPACE, /* IMAGE_UTIL_COLORSPACE_YUV422 */ - _NOT_SUPPORTED_COLORSPACE, /* IMAGE_UTIL_COLORSPACE_I420 */ - _NOT_SUPPORTED_COLORSPACE, /* IMAGE_UTIL_COLORSPACE_NV12 */ - _NOT_SUPPORTED_COLORSPACE, /* IMAGE_UTIL_COLORSPACE_UYVY */ - _NOT_SUPPORTED_COLORSPACE, /* IMAGE_UTIL_COLORSPACE_YUYV */ - _NOT_SUPPORTED_COLORSPACE, /* IMAGE_UTIL_COLORSPACE_RGB565 */ - _NOT_SUPPORTED_COLORSPACE, /* IMAGE_UTIL_COLORSPACE_RGB888 */ - _NOT_SUPPORTED_COLORSPACE, /* IMAGE_UTIL_COLORSPACE_ARGB8888 */ - _NOT_SUPPORTED_COLORSPACE, /* IMAGE_UTIL_COLORSPACE_BGRA8888 */ - MM_UTIL_COLOR_RGBA, /* IMAGE_UTIL_COLORSPACE_RGBA8888 */ - _NOT_SUPPORTED_COLORSPACE, /* IMAGE_UTIL_COLORSPACE_BGRX8888 */ - _NOT_SUPPORTED_COLORSPACE, /* IMAGE_UTIL_COLORSPACE_NV21 */ - _NOT_SUPPORTED_COLORSPACE, /* IMAGE_UTIL_COLORSPACE_NV16 */ - _NOT_SUPPORTED_COLORSPACE, /* IMAGE_UTIL_COLORSPACE_NV61 */ + [IMAGE_UTIL_COLORSPACE_YV12] = _NOT_SUPPORTED_COLORSPACE, + [IMAGE_UTIL_COLORSPACE_YUV422] = _NOT_SUPPORTED_COLORSPACE, + [IMAGE_UTIL_COLORSPACE_I420] = _NOT_SUPPORTED_COLORSPACE, + [IMAGE_UTIL_COLORSPACE_NV12] = _NOT_SUPPORTED_COLORSPACE, + [IMAGE_UTIL_COLORSPACE_UYVY] = _NOT_SUPPORTED_COLORSPACE, + [IMAGE_UTIL_COLORSPACE_YUYV] = _NOT_SUPPORTED_COLORSPACE, + [IMAGE_UTIL_COLORSPACE_RGB565] = _NOT_SUPPORTED_COLORSPACE, + [IMAGE_UTIL_COLORSPACE_RGB888] = _NOT_SUPPORTED_COLORSPACE, + [IMAGE_UTIL_COLORSPACE_ARGB8888] = _NOT_SUPPORTED_COLORSPACE, + [IMAGE_UTIL_COLORSPACE_BGRA8888] = _NOT_SUPPORTED_COLORSPACE, + [IMAGE_UTIL_COLORSPACE_RGBA8888] = MM_UTIL_COLOR_RGBA, + [IMAGE_UTIL_COLORSPACE_BGRX8888] = _NOT_SUPPORTED_COLORSPACE, + [IMAGE_UTIL_COLORSPACE_NV21] = _NOT_SUPPORTED_COLORSPACE, + [IMAGE_UTIL_COLORSPACE_NV16] = _NOT_SUPPORTED_COLORSPACE, + [IMAGE_UTIL_COLORSPACE_NV61] = _NOT_SUPPORTED_COLORSPACE, }; static int _convert_bmp_colorspace_tbl[] = { - _NOT_SUPPORTED_COLORSPACE, /* IMAGE_UTIL_COLORSPACE_YUV420 */ - _NOT_SUPPORTED_COLORSPACE, /* IMAGE_UTIL_COLORSPACE_YUV422 */ - _NOT_SUPPORTED_COLORSPACE, /* IMAGE_UTIL_COLORSPACE_I420 */ - _NOT_SUPPORTED_COLORSPACE, /* IMAGE_UTIL_COLORSPACE_NV12 */ - _NOT_SUPPORTED_COLORSPACE, /* IMAGE_UTIL_COLORSPACE_UYVY */ - _NOT_SUPPORTED_COLORSPACE, /* IMAGE_UTIL_COLORSPACE_YUYV */ - _NOT_SUPPORTED_COLORSPACE, /* IMAGE_UTIL_COLORSPACE_RGB565 */ - _NOT_SUPPORTED_COLORSPACE, /* IMAGE_UTIL_COLORSPACE_RGB888 */ - _NOT_SUPPORTED_COLORSPACE, /* IMAGE_UTIL_COLORSPACE_ARGB8888 */ - _NOT_SUPPORTED_COLORSPACE, /* IMAGE_UTIL_COLORSPACE_BGRA8888 */ - MM_UTIL_COLOR_RGBA, /* IMAGE_UTIL_COLORSPACE_RGBA8888 */ - _NOT_SUPPORTED_COLORSPACE, /* IMAGE_UTIL_COLORSPACE_BGRX8888 */ - _NOT_SUPPORTED_COLORSPACE, /* IMAGE_UTIL_COLORSPACE_NV21 */ - _NOT_SUPPORTED_COLORSPACE, /* IMAGE_UTIL_COLORSPACE_NV16 */ - _NOT_SUPPORTED_COLORSPACE, /* IMAGE_UTIL_COLORSPACE_NV61 */ + [IMAGE_UTIL_COLORSPACE_YV12] = _NOT_SUPPORTED_COLORSPACE, + [IMAGE_UTIL_COLORSPACE_YUV422] = _NOT_SUPPORTED_COLORSPACE, + [IMAGE_UTIL_COLORSPACE_I420] = _NOT_SUPPORTED_COLORSPACE, + [IMAGE_UTIL_COLORSPACE_NV12] = _NOT_SUPPORTED_COLORSPACE, + [IMAGE_UTIL_COLORSPACE_UYVY] = _NOT_SUPPORTED_COLORSPACE, + [IMAGE_UTIL_COLORSPACE_YUYV] = _NOT_SUPPORTED_COLORSPACE, + [IMAGE_UTIL_COLORSPACE_RGB565] = _NOT_SUPPORTED_COLORSPACE, + [IMAGE_UTIL_COLORSPACE_RGB888] = _NOT_SUPPORTED_COLORSPACE, + [IMAGE_UTIL_COLORSPACE_ARGB8888] = _NOT_SUPPORTED_COLORSPACE, + [IMAGE_UTIL_COLORSPACE_BGRA8888] = _NOT_SUPPORTED_COLORSPACE, + [IMAGE_UTIL_COLORSPACE_RGBA8888] = MM_UTIL_COLOR_RGBA, + [IMAGE_UTIL_COLORSPACE_BGRX8888] = _NOT_SUPPORTED_COLORSPACE, + [IMAGE_UTIL_COLORSPACE_NV21] = _NOT_SUPPORTED_COLORSPACE, + [IMAGE_UTIL_COLORSPACE_NV16] = _NOT_SUPPORTED_COLORSPACE, + [IMAGE_UTIL_COLORSPACE_NV61] = _NOT_SUPPORTED_COLORSPACE, +}; + +static int _convert_webp_colorspace_tbl[] = { + [IMAGE_UTIL_COLORSPACE_YV12] = _NOT_SUPPORTED_COLORSPACE, + [IMAGE_UTIL_COLORSPACE_YUV422] = _NOT_SUPPORTED_COLORSPACE, + [IMAGE_UTIL_COLORSPACE_I420] = _NOT_SUPPORTED_COLORSPACE, + [IMAGE_UTIL_COLORSPACE_NV12] = _NOT_SUPPORTED_COLORSPACE, + [IMAGE_UTIL_COLORSPACE_UYVY] = _NOT_SUPPORTED_COLORSPACE, + [IMAGE_UTIL_COLORSPACE_YUYV] = _NOT_SUPPORTED_COLORSPACE, + [IMAGE_UTIL_COLORSPACE_RGB565] = _NOT_SUPPORTED_COLORSPACE, + [IMAGE_UTIL_COLORSPACE_RGB888] = _NOT_SUPPORTED_COLORSPACE, + [IMAGE_UTIL_COLORSPACE_ARGB8888] = MM_UTIL_COLOR_ARGB, + [IMAGE_UTIL_COLORSPACE_BGRA8888] = MM_UTIL_COLOR_BGRA, + [IMAGE_UTIL_COLORSPACE_RGBA8888] = MM_UTIL_COLOR_RGBA, + [IMAGE_UTIL_COLORSPACE_BGRX8888] = _NOT_SUPPORTED_COLORSPACE, + [IMAGE_UTIL_COLORSPACE_NV21] = _NOT_SUPPORTED_COLORSPACE, + [IMAGE_UTIL_COLORSPACE_NV16] = _NOT_SUPPORTED_COLORSPACE, + [IMAGE_UTIL_COLORSPACE_NV61] = _NOT_SUPPORTED_COLORSPACE, }; unsigned int _get_number_of_colorspace(void) @@ -162,6 +180,9 @@ gboolean _is_supported_colorspace(image_util_colorspace_e colorspace, image_util case IMAGE_UTIL_BMP: image_util_retvm_if((_convert_bmp_colorspace_tbl[colorspace] == _NOT_SUPPORTED_COLORSPACE), FALSE, "[bmp] %d not supported format", colorspace); break; + case IMAGE_UTIL_WEBP: + image_util_retvm_if((_convert_webp_colorspace_tbl[colorspace] == _NOT_SUPPORTED_COLORSPACE), FALSE, "[webp] %d not supported format", colorspace); + break; default: image_util_retvm_if(TRUE, FALSE, "Invalid image type"); } @@ -199,6 +220,9 @@ int _convert_type_of_colorspace_with_image_type(const image_util_colorspace_e co case IMAGE_UTIL_BMP: new_colorspace = _convert_bmp_colorspace_tbl[colorspace]; break; + case IMAGE_UTIL_WEBP: + new_colorspace = _convert_webp_colorspace_tbl[colorspace]; + break; default: image_util_error("Invalid image type"); } diff --git a/test/image_util_testsuite.c b/test/image_util_testsuite.c index ebc86c5..4df94bb 100644 --- a/test/image_util_testsuite.c +++ b/test/image_util_testsuite.c @@ -35,8 +35,7 @@ #define MAX_AGIF_CNT 100 /* supports MAX_AGIF_CNT agif frames */ #define IMAGE_UTIL_COLOR_NUM IMAGE_UTIL_COLORSPACE_NV61 + 1 -#define SAFE_FREE(src) { if (src) {free(src); src = NULL; } } -#define SAFE_G_FREE(src) { if (src) {g_free(src); src = NULL; } } +#define SAFE_FREE(src) { g_free(src); src = NULL; } #define IS_RAW_FILE(x) ((g_strrstr(x, ".raw")) ? TRUE : FALSE) @@ -59,6 +58,8 @@ #define FILE_FOR_ENCODE tzplatform_mkpath(TZ_USER_CONTENT, "imgutil_test_encode") #define FILE_FOR_ENCODE_AGIF tzplatform_mkpath(TZ_USER_CONTENT, "imgutil_test_encode_agif") +#define IMAGE_UTIL_TYPE_MAX IMAGE_UTIL_WEBP + /* parameters for testsuite */ typedef enum { MAIN_MENU = 0, @@ -75,6 +76,7 @@ typedef enum { SET_COLOR_MENU, SET_RAW_COLOR_MENU, SET_COMPRESSION_MENU, + SET_LOSSLESS_MENU, SET_CONVERT_MENU, SET_CROP_MENU, SET_DELAY_MENU, @@ -132,6 +134,7 @@ typedef struct { image_util_type_e type; int quality; image_util_png_compression_e compression; + bool lossless; gboolean use_buffer; } test_encode_params_s; @@ -276,6 +279,7 @@ typedef enum { ENCODE_SET_TYPE = 0, ENCODE_SET_QUALITY, ENCODE_SET_COMPRESIION, + ENCODE_SET_LOSSLESS, ENCODE_SET_TO_BUFFER, ENCODE_RUN, ENCODE_RUN_ASYNC, @@ -295,6 +299,7 @@ static const test_encode_menu_s g_disp_encode_menu[ENCODE_MENU_MAX] = { { ENCODE_SET_TYPE, "set image_type (mand. default=IMAGE_UTIL_JPEG)" }, { ENCODE_SET_QUALITY, "set quality (opt. for jpeg only)" }, { ENCODE_SET_COMPRESIION, "set compression (opt. for png only)" }, + { ENCODE_SET_LOSSLESS, "set lossless (opt. for webp only)" }, { ENCODE_SET_TO_BUFFER, "set output buffer (opt. deprecated)" }, { ENCODE_RUN, "encode run (will be deprecated)" }, { ENCODE_RUN_ASYNC, "encode run async (will be deprecated)" }, @@ -337,7 +342,7 @@ typedef struct { static const test_encode_agif_menu_s g_disp_encode_agif_menu[ENCODE_AGIF_MENU_MAX] = { { ENCODE_AGIF_SET_DIR, "set directory" }, - { ENCODE_AGIF_SET_DELAY, "set dealy time (mand. default = 100)" }, + { ENCODE_AGIF_SET_DELAY, "set delay time (mand. default = 100)" }, { ENCODE_AGIF_SET_TO_BUFFER, "set output buffer (opt. will be deprecated)" }, { ENCODE_AGIF_RUN, "run agif (will be deprecated)" }, { ENCODE_AGIF_RUN_ASYNC, "run async agif (will be deprecated)" }, @@ -475,7 +480,10 @@ static void __display_menu(test_menu_state_e menu_state) __display_set("colorspace", "i420:2, rgb:7, argb:8, rgba:10"); break; case SET_COMPRESSION_MENU: - __display_set("comprssion", "0(NoC/HighQ)~9(MaxC/LowQ)"); + __display_set("compression", "0(Lowest/HighQ)~9(Max/LowQ)"); + break; + case SET_LOSSLESS_MENU: + __display_set("lossless", "0(false)/1(true)"); break; case SET_CROP_MENU: __display_set("crop", "(sx)x(sy)x(w)x(h) 0x0x1920x1080"); @@ -484,20 +492,20 @@ static void __display_menu(test_menu_state_e menu_state) __display_set("delay", "20~"); break; case SET_DOWNSCALE_MENU: - __display_set("downscale", "0(1/1)~3(1/8)"); + __display_set("downscale", "0(1/1), 1(1/2), 2(1/4), 3(1/8)"); break; case SET_QUALITY_MENU: __display_set("quality", "1(LowQ)~100(HighQ)"); break; case SET_RESIZE_MENU: case SET_SIZE_MENU: - __display_set("size", "1920x1080"); + __display_set("size", "(w)x(h) 1920x1080"); break; case SET_ROTATE_MENU: __display_set("rotation", "0:none, 1:90, 2:180, 3:270"); break; case SET_TYPE_MENU: - __display_set("image_type", "0:jpeg, 1:png, 2:gif, 3:bmp"); + __display_set("image_type", "0:jpeg, 1:png, 2:gif, 3:bmp, 4:webp"); break; /* set menus */ @@ -534,8 +542,9 @@ void __signal() static gboolean __read_file(char *path, void **data, size_t *length) { - FILE *fp = NULL; - long len = 0; + gchar *contents = NULL; + gsize len = 0; + GError *error = NULL; if (!path || !data || length == 0) { g_print("\t[__read_file] invalid data\n"); @@ -544,46 +553,15 @@ static gboolean __read_file(char *path, void **data, size_t *length) g_print("\t[__read_file] %s read\n", path); - fp = fopen(path, "r"); - if (fp == NULL) { - g_print("\t[__read_file] fopen failed (%d)\n", errno); - return FALSE; - } - - if (fseek(fp, 0, SEEK_END) < 0) { - g_print("\t[__read_file] fseek failed\n"); - fclose(fp); + if (!g_file_get_contents(path, &contents, &len, &error)) { + g_print("\t[__read_file] g_file_get_contents failed(%s)\n", (error ? error->message : "none")); + if (error) + g_error_free(error); return FALSE; } - len = ftell(fp); - if (len < 0) { - g_print("\t[__read_file] ftell failed\n"); - fclose(fp); - return FALSE; - } - - rewind(fp); - *data = (void *)calloc(1, (size_t)len); - if (*data == NULL) { - g_print("\t[__read_file] memory allocation failed\n"); - fclose(fp); - return FALSE; - } - - *length = fread(*data, 1, (size_t)len, fp); - if (*length != (size_t)len) { - g_print("\t[__read_file] fread failed\n"); - } - - fclose(fp); - - if (*data == NULL) { - *length = 0; - return FALSE; - } - - *length = (size_t)len; + *data = contents; + *length = len; g_print("\t[__read_file] %s %zu read DONE\n", path, *length); @@ -592,30 +570,15 @@ static gboolean __read_file(char *path, void **data, size_t *length) static gboolean __write_file(const char *path, void *data, size_t length) { - FILE *fp = NULL; - size_t len = 0; - - if (!path || !data || length == 0) { - g_print("\t[__write_file] invalid data\n"); - return FALSE; - } - - g_print("\t[__write_file] %s %p %zu write\n", path, data, length); + GError *error = NULL; - fp = fopen(path, "w"); - if (fp == NULL) { - g_print("\t[__write_file] fopen failed (%d)\n", errno); + if (!g_file_set_contents(path, (gchar *)data, (gsize)length, &error)) { + g_print("\t[__read_file] g_file_set_contents failed(%s)\n", (error ? error->message : "none")); + if (error) + g_error_free(error); return FALSE; } - len = fwrite(data, 1, length, fp); - if (len != length) { - g_print("\t[__write_file] fwrite failed\n"); - } - - fclose(fp); - fp = NULL; - g_print("\t[__write_file] %s write DONE\n", path); return TRUE; @@ -649,11 +612,6 @@ ERROR: } #endif -static void __queue_free_func(gpointer data) -{ - SAFE_FREE(data); -} - static gboolean __safe_atoui(char *buffer, unsigned int *ui) { char *end = NULL; @@ -740,48 +698,38 @@ static int __sort_compare(gconstpointer a, gconstpointer b, gpointer user_data) static gboolean __set_input_dir(const char *path) { - struct dirent *dp = NULL; - DIR *fd = NULL; + GDir *dir = NULL; + const gchar *filename = NULL; + GError *error = NULL; - if (path == NULL || strlen(path) == 0) + dir = g_dir_open(path, 0, &error); + if (!dir) { + g_print("invalid dir %s (%s)\n", path, error ? error->message : "none"); + g_error_free(error); return FALSE; - - if (!g_queue_agif_images) { - g_queue_agif_images = g_queue_new(); - if (!g_queue_agif_images) { - g_print("g_queue_new failed\n"); - return FALSE; - } } - fd = opendir(path); - if (fd == NULL) { - g_print("\tlistdir: can't open %s\n", path); - return FALSE; - } + if (g_queue_agif_images) + g_queue_free_full(g_queue_agif_images, g_free); - g_queue_free_full(g_queue_agif_images, __queue_free_func); + g_queue_agif_images = g_queue_new(); - /* read files in dir */ - while ((dp = readdir(fd)) != NULL) { - if (strlen(dp->d_name) == 0) - continue; - if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, "..")) - continue; /* skip self and parent */ + /* push files of dir into queue */ + while (1) { + filename = g_dir_read_name(dir); + if (!filename) + break; - g_queue_push_tail(g_queue_agif_images, g_strdup_printf("%s/%s", path, dp->d_name)); + g_queue_insert_sorted(g_queue_agif_images, g_strdup_printf("%s/%s", path, filename), __sort_compare, NULL); } - closedir(fd); + g_dir_close(dir); - if (g_queue_get_length(g_queue_agif_images) == 0) { - g_print("\tNo Test File in directory(%s)!\n", path); + if (g_queue_agif_images->length == 0) { + g_print("No test file in directory(%s)!\n", path); return FALSE; } - /* sort files */ - g_queue_sort(g_queue_agif_images, __sort_compare, NULL); - /* decode files of dir */ if (!__decode_file_in_dir()) { g_print("Fail to decode file from dir! %s\n", path); @@ -796,7 +744,7 @@ static gboolean __set_input_path(const char *path) if (path == NULL || strlen(path) == 0) return FALSE; - SAFE_G_FREE(g_input_data.path); + g_free(g_input_data.path); g_input_data.path = g_strdup(path); if (!g_input_data.path) { @@ -903,60 +851,69 @@ static int __get_raw_data(test_complex_data_s *test_data) } static unsigned int g_num_of_file = 0; -static void __set_auto_file(image_util_type_e image_type, char **path) +static const char *g_image_exts[] = { + "jpg", + "png", + "gif", + "bmp", + "webp", +}; +static void __get_auto_path(image_util_type_e image_type, char **path) { - char ext[4]; - - SAFE_G_FREE(*path); + char *_path = NULL; switch (image_type) { case IMAGE_UTIL_JPEG: - snprintf(ext, 4, "%s", "jpg"); - break; + /* fall through */ case IMAGE_UTIL_PNG: - snprintf(ext, 4, "%s", "png"); - break; + /* fall through */ case IMAGE_UTIL_GIF: - snprintf(ext, 4, "%s", "gif"); - break; + /* fall through */ case IMAGE_UTIL_BMP: - snprintf(ext, 4, "%s", "bmp"); + /* fall through */ + case IMAGE_UTIL_WEBP: + // do noting... break; default: g_print("Not supported encode format!\n"); return; } - *path = g_strdup_printf("%s_%02d.%s", FILE_FOR_AUTO, g_num_of_file++, ext); + _path = g_strdup_printf("%s_%02d.%s", FILE_FOR_AUTO, g_num_of_file++, g_image_exts[image_type]); + + g_free(*path); + *path = _path; - g_print("\t__set_auto_file: %s!\n", *path); + g_print("\t__get_auto_path: %s!\n", *path); } -static void __set_encode_file(image_util_type_e image_type, const char *base, char **path) +static void __get_encode_path(image_util_type_e image_type, const char *base, char **path) { - char ext[4]; - - SAFE_G_FREE(*path); + char *_path = NULL; switch (image_type) { case IMAGE_UTIL_JPEG: - snprintf(ext, 4, "%s", "jpg"); - break; + /* fall through */ case IMAGE_UTIL_PNG: - snprintf(ext, 4, "%s", "png"); - break; + /* fall through */ case IMAGE_UTIL_GIF: - snprintf(ext, 4, "%s", "gif"); - break; + /* fall through */ case IMAGE_UTIL_BMP: - snprintf(ext, 4, "%s", "bmp"); + /* fall through */ + case IMAGE_UTIL_WEBP: + // do noting... break; default: g_print("Not supported encode format!\n"); return; } - *path = g_strdup_printf("%s.%s", base, ext); + _path = g_strdup_printf("%s.%s", base, g_image_exts[image_type]); + + g_free(*path); + *path = _path; + + g_print("\t__get_encode_path: %s!\n", *path); } /* internal functions for testsuite */ @@ -1035,11 +992,8 @@ static void __encode_to_buffer_completed_cb(image_util_error_e error_code, unsig return; } - result->buffer = calloc(1, buffer_size); - if (result->buffer) { - memcpy(result->buffer, buffer, buffer_size); - result->buffer_size = buffer_size; - } + result->buffer = g_memdup(buffer, buffer_size); + __signal(); } @@ -1084,7 +1038,7 @@ static void __transform_completed2_cb(image_util_image_h dst, int error_code, vo /* test functions for testsuite */ -/* decode JPE, PNG, GIF and BMP with params +/* decode JPEG/PNG/GIF/BMP/WEBP with params * input : use path or buffer(buffer_size) * output : use image */ @@ -1207,7 +1161,7 @@ ERROR: return ret; } -/* encode JPE, PNG, GIF and BMP with params +/* encode JPEG/PNG/GIF/BMP/WEBP with params * input : use image * output : use path or buffer(buffer_size) */ @@ -1240,18 +1194,31 @@ static int __run_encode(test_encode_menu_e menu, test_complex_data_s *input, return ret; } - if (params->type == IMAGE_UTIL_JPEG) { + switch(params->type) { + case IMAGE_UTIL_JPEG: ret = image_util_encode_set_quality(handle, params->quality); if (ret != IMAGE_UTIL_ERROR_NONE) { - g_print("image_util_decode_set_input_buffer failed %d\n", ret); + g_print("image_util_encode_set_quality failed %d\n", ret); goto ERROR; } - } else if (params->type == IMAGE_UTIL_PNG) { + break; + case IMAGE_UTIL_PNG: ret = image_util_encode_set_png_compression(handle, params->compression); if (ret != IMAGE_UTIL_ERROR_NONE) { - g_print("image_util_decode_set_input_buffer failed %d\n", ret); + g_print("image_util_encode_set_png_compression failed %d\n", ret); goto ERROR; } + break; + case IMAGE_UTIL_WEBP: + ret = image_util_encode_set_webp_lossless(handle, params->lossless); + if (ret != IMAGE_UTIL_ERROR_NONE) { + g_print("image_util_encode_set_webp_lossless failed %d\n", ret); + goto ERROR; + } + break; + default: + /* do nothing... */ + break; } switch(menu) { @@ -1429,16 +1396,12 @@ static int __run_encode_agif_deprecated(test_encode_menu_e menu, test_complex_da return IMAGE_UTIL_ERROR_INVALID_PARAMETER; } - buffer = calloc(1, sizeof(char *) * input->image_cnt); - if (!buffer) { - g_print("Memory allocation failed %d\n", ret); - return IMAGE_UTIL_ERROR_OUT_OF_MEMORY; - } + buffer = g_malloc0(sizeof(unsigned char *) * input->image_cnt); ret = image_util_encode_create(IMAGE_UTIL_GIF, &handle); if (ret != IMAGE_UTIL_ERROR_NONE) { g_print("image_util_encode_create failed %d\n", ret); - SAFE_FREE(buffer); + g_free(buffer); return ret; } @@ -1533,9 +1496,9 @@ ERROR: image_util_encode_destroy(handle); for (i = 0; i < input->image_cnt; i++) - SAFE_FREE(buffer[i]); + g_free(buffer[i]); - SAFE_FREE(buffer); + g_free(buffer); return ret; } @@ -1732,7 +1695,7 @@ static int __run_auto(void) g_encode_params.type = IMAGE_UTIL_JPEG; g_encode_params.quality = 100; - __set_auto_file(g_encode_params.type, &g_encode_result.path); + __get_auto_path(g_encode_params.type, &g_encode_result.path); g_transform_params.crop_area.x = 0; g_transform_params.crop_area.y = 0; @@ -1750,7 +1713,7 @@ static int __run_auto(void) else g_print("Fail ENCODE_RUN_TO_FILE!!!\n"); - for (image_type = IMAGE_UTIL_JPEG; image_type <= IMAGE_UTIL_BMP; image_type++) { + for (image_type = IMAGE_UTIL_JPEG; image_type <= IMAGE_UTIL_TYPE_MAX; image_type++) { g_print("[[[ IMAGE_TYPE %d ]]]\n", image_type); ret = __run_decode(DECODE_RUN2, &g_encode_result, &g_decode_params, &g_decode_result); @@ -1768,7 +1731,7 @@ static int __run_auto(void) g_transform_params.has_crop = FALSE; - __set_auto_file(image_type, &encode_temp_result.path); + __get_auto_path(image_type, &encode_temp_result.path); ret = __run_encode(ENCODE_RUN_TO_FILE, &g_decode_result, &g_encode_params, &encode_temp_result); if (ret == IMAGE_UTIL_ERROR_NONE) g_print("Success ENCODE_RUN_TO_FILE!!!\n"); @@ -1790,7 +1753,7 @@ static int __run_auto(void) g_transform_params.has_resize = FALSE; - __set_auto_file(image_type, &encode_temp_result.path); + __get_auto_path(image_type, &encode_temp_result.path); ret = __run_encode(ENCODE_RUN_TO_BUFFER, &g_transform_result, &g_encode_params, &encode_temp_result); if (ret == IMAGE_UTIL_ERROR_NONE) g_print("Success ENCODE_RUN_TO_BUFFER!!!\n"); @@ -1813,8 +1776,8 @@ static int __run_auto(void) g_transform_params.has_rotation = FALSE; /* change next image_type */ - g_encode_params.type = ((image_type + 1 > IMAGE_UTIL_BMP) ? IMAGE_UTIL_BMP : (image_type + 1)); - __set_auto_file(g_encode_params.type, &g_encode_result.path); + g_encode_params.type = ((image_type == IMAGE_UTIL_TYPE_MAX) ? IMAGE_UTIL_TYPE_MAX : (image_type + 1)); + __get_auto_path(g_encode_params.type, &g_encode_result.path); ret = __run_encode(ENCODE_RUN_ASYNC_TO_BUFFER, &g_transform_result, &g_encode_params, &g_encode_result); if (ret == IMAGE_UTIL_ERROR_NONE) @@ -1828,7 +1791,7 @@ static int __run_auto(void) /* test functions for testsuite */ -/* interprete menu */ +/* interpret menu */ /* push result data-set of test to stack */ static void __data_push(test_complex_data_s *comp_data) @@ -1899,11 +1862,7 @@ static void __menu_move(test_menu_state_e new_menu) } } - data = calloc(1, sizeof(test_queue_menu_s)); - if (!data) { - g_print("Memory allocation failed\n"); - return; - } + data = g_new0(test_queue_menu_s, 1); #if DEBUG_QUEUE g_print("[menu move] %u -> %u\n", g_current_menu, new_menu); @@ -1944,7 +1903,7 @@ static void __menu_back(void) /* go to previous menu */ g_current_menu = data->menu_state; - SAFE_FREE(data); + g_free(data); } static void __quit(void) @@ -2009,6 +1968,9 @@ static void __interpret_encode(const char *cmd, unsigned int index) case ENCODE_SET_COMPRESIION: __menu_move(SET_COMPRESSION_MENU); break; + case ENCODE_SET_LOSSLESS: + __menu_move(SET_LOSSLESS_MENU); + break; case ENCODE_SET_TO_BUFFER: __menu_move(SET_TO_BUFFER_MENU); break; @@ -2022,7 +1984,7 @@ static void __interpret_encode(const char *cmd, unsigned int index) g_print("There is no test data for encode.\n"); break; } - __set_encode_file(g_encode_params.type, FILE_FOR_ENCODE, &g_encode_result.path); + __get_encode_path(g_encode_params.type, FILE_FOR_ENCODE, &g_encode_result.path); ret = __run_encode(index, input_data, &g_encode_params, &g_encode_result); if (ret == IMAGE_UTIL_ERROR_NONE) { g_print("Success to encode image!!!\n"); @@ -2059,7 +2021,7 @@ static void __interpret_encode_agif(const char *cmd, unsigned int index) g_print("There is no test data for decode.\n"); break; } - __set_encode_file(IMAGE_UTIL_GIF, FILE_FOR_ENCODE_AGIF, &g_encode_agif_result.path); + __get_encode_path(IMAGE_UTIL_GIF, FILE_FOR_ENCODE_AGIF, &g_encode_agif_result.path); ret = __run_encode_agif_deprecated(index, input_data, &g_encode_agif_params, &g_encode_agif_result); if (ret == IMAGE_UTIL_ERROR_NONE) { g_print("Success to encode image!!!\n"); @@ -2075,7 +2037,7 @@ static void __interpret_encode_agif(const char *cmd, unsigned int index) g_print("There is no test data for decode.\n"); break; } - __set_encode_file(IMAGE_UTIL_GIF, FILE_FOR_ENCODE_AGIF, &g_encode_agif_result.path); + __get_encode_path(IMAGE_UTIL_GIF, FILE_FOR_ENCODE_AGIF, &g_encode_agif_result.path); ret = __run_encode_agif(index, input_data, &g_encode_agif_params, &g_encode_agif_result); if (ret == IMAGE_UTIL_ERROR_NONE) { g_print("Success to encode image!!!\n"); @@ -2172,6 +2134,10 @@ static gboolean __interpret_set_menu(test_menu_state_e menu_state, const char *c g_encode_params.compression = index; g_print("Success to set compression (%u)\n", g_encode_params.compression); break; + case SET_LOSSLESS_MENU: + g_encode_params.lossless = (index == 0) ? false : true; + g_print("Success to set lossless (%u)\n", g_encode_params.lossless); + break; case SET_CONVERT_MENU: g_transform_params.convert_color = index; g_transform_params.has_convert_color = TRUE; @@ -2219,7 +2185,7 @@ static gboolean __interpret_set_menu(test_menu_state_e menu_state, const char *c break; case SET_TYPE_MENU: g_encode_params.type = index; - __set_encode_file(g_encode_params.type, FILE_FOR_ENCODE, &g_encode_result.path); + __get_encode_path(g_encode_params.type, FILE_FOR_ENCODE, &g_encode_result.path); g_print("Success to set image_type (%u)\n", g_encode_params.type); break; default: @@ -2350,6 +2316,7 @@ static void __interpret_cmd(char *cmd) case SET_COLOR_MENU: case SET_RAW_COLOR_MENU: case SET_COMPRESSION_MENU: + case SET_LOSSLESS_MENU: case SET_CONVERT_MENU: case SET_CROP_MENU: case SET_DELAY_MENU: @@ -2371,7 +2338,7 @@ static void __interpret_cmd(char *cmd) __display_menu(g_current_menu); return; } -/* interprete menu */ +/* interpret menu */ /* testsuite mainloop */ @@ -2424,18 +2391,18 @@ static void _destroy_data(void) { unsigned int i = 0; - g_queue_free_full(g_queue_menu, __queue_free_func); - g_queue_free_full(g_queue_agif_images, __queue_free_func); + g_queue_free_full(g_queue_menu, g_free); + g_queue_free_full(g_queue_agif_images, g_free); - SAFE_G_FREE(g_input_data.path); - SAFE_FREE(g_input_data.buffer); + g_free(g_input_data.path); + g_free(g_input_data.buffer); for (i = 0; i < g_input_data.image_cnt; i++) image_util_destroy_image(g_input_data.images[i]); - SAFE_FREE(g_decode_result.buffer); - SAFE_FREE(g_transform_result.buffer); - SAFE_FREE(g_encode_result.buffer); + g_free(g_decode_result.buffer); + g_free(g_transform_result.buffer); + g_free(g_encode_result.buffer); image_util_destroy_image(g_decode_result.image); image_util_destroy_image(g_transform_result.image); @@ -2478,7 +2445,7 @@ static void _display_help(const char *cmd) g_print("%s {directory} {test_mode} [for a-gif]\n", cmd); g_print("{test_mode} 0:auto, 1:decode, 2:encode, 3:a-gif, 4:transform\n"); g_print("\n[Note]\n"); - g_print(" The {file_path}/{directory} are mandotary. but the {test_mode} is optional.\n"); + g_print(" The {file_path}/{directory} are mandatory. but the {test_mode} is optional.\n"); g_print("\n[usage]\n"); g_print(" 1. %s test.jpg\n", cmd); g_print(" 2. %s test.jpg %d\n", cmd, TEST_AUTO);