From: hj kim Date: Tue, 19 Mar 2019 05:58:01 +0000 (+0900) Subject: [ACR-1393][Add/Deprecate] Update encoding APIs X-Git-Tag: submit/tizen/20190529.045235^0 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=ec2bb23727033d58809dc0706505b63caecd15d5;p=platform%2Fcore%2Fapi%2Fimage-util.git [ACR-1393][Add/Deprecate] Update encoding APIs Change-Id: I501cabbbcbe6e19096108d2f20906dd47668a72f --- diff --git a/decode-test/image_util_decode_encode_testsuite.c b/decode-test/image_util_decode_encode_testsuite.c index 9222f1e..a1a2235 100755 --- a/decode-test/image_util_decode_encode_testsuite.c +++ b/decode-test/image_util_decode_encode_testsuite.c @@ -601,6 +601,197 @@ gboolean test_encode() return TRUE; } +static void __encode_to_file_completed_cb(int error_code, void *user_data) +{ + fprintf(stderr, "__encode_to_file_completed_cb invoked [%d]\n", error_code); + _signal(); + + return; +} + +static void __encode_to_buffer_completed_cb(int error_code, unsigned char *buffer, size_t buffer_size, void *user_data) +{ + fprintf(stderr, "__encode_to_buffer_completed_cb invoked [%d]\n", error_code); + + if (_write_file(g_test_encode.out_path, buffer, buffer_size) == FALSE) + fprintf(stderr, "\tWrite the encoded result failed!\n"); + + _signal(); + + return; +} + +gboolean test_new_encode() +{ + int ret = IMAGE_UTIL_ERROR_NONE; + image_util_encode_h encoded = NULL; + image_util_image_h _image = NULL; + unsigned char *buffer = NULL; + size_t buffer_size = 0; + + + ret = image_util_encode_create(g_test_input.image_type, &encoded); + if (ret != IMAGE_UTIL_ERROR_NONE) + return FALSE; + + ret = image_util_create_image(g_test_decode[0].width, g_test_decode[0].height, IMAGE_UTIL_COLORSPACE_RGBA8888, g_test_decode[0].decoded, g_test_decode[0].decode_size, &_image); + if (ret != IMAGE_UTIL_ERROR_NONE) { + image_util_encode_destroy(encoded); + return FALSE; + } + + if (g_test_input.cmd == TEST_DECODE_FILE) { + ret = image_util_encode_run_to_file(encoded, _image, g_test_encode.out_path); + } else if (g_test_input.cmd == TEST_DECODE_MEM) { + ret = image_util_encode_run_to_buffer(encoded, _image, &buffer, &buffer_size); + } else if (g_test_input.cmd == TEST_DECODE_ASYNC) { + ret = image_util_encode_run_async_to_file(encoded, _image, g_test_encode.out_path, __encode_to_file_completed_cb, NULL); + if (ret == IMAGE_UTIL_ERROR_NONE) + _wait(); + } else if (g_test_input.cmd == TEST_DECODE_MEM_ASYNC) { + ret = image_util_encode_run_async_to_buffer(encoded, _image, __encode_to_buffer_completed_cb, NULL); + if (ret == IMAGE_UTIL_ERROR_NONE) + _wait(); + } + + image_util_encode_destroy(encoded); + + if (ret != IMAGE_UTIL_ERROR_NONE) { + fprintf(stderr, "\timage_util_encode_run_to_file failed!\n"); + if (buffer) + free(buffer); + return FALSE; + } + + if (g_test_input.cmd == TEST_DECODE_MEM) { + if (_write_file(g_test_encode.out_path, buffer, buffer_size) == FALSE) + fprintf(stderr, "\tWrite the encoded result failed!\n"); + } + + if (buffer) + free(buffer); + + return TRUE; +} + +gboolean test_new_decode_encode() +{ + int ret = IMAGE_UTIL_ERROR_NONE; + unsigned int i = 0; + image_util_decode_h decoded = NULL; + image_util_encode_h encoded = NULL; + unsigned char *buffer = NULL; + size_t buffer_size = 0; + + //Decode + ret = image_util_decode_create(&decoded); + if (ret != IMAGE_UTIL_ERROR_NONE) + return FALSE; + + if ((g_test_input.cmd == TEST_DECODE_MEM) || (g_test_input.cmd == TEST_DECODE_MEM_ASYNC)) + ret = image_util_decode_set_input_buffer(decoded, (unsigned char *)g_test_input.buffer, g_test_input.buffer_size); + else + ret = image_util_decode_set_input_path(decoded, g_test_decode[i].filepath); + + if (ret != IMAGE_UTIL_ERROR_NONE) { + image_util_decode_destroy(decoded); + return FALSE; + } + + if ((g_test_input.cmd == TEST_DECODE_ASYNC) || (g_test_input.cmd == TEST_DECODE_MEM_ASYNC)) { + ret = image_util_decode_run_async2(decoded, __decode_completed2_cb, NULL); + if (ret == IMAGE_UTIL_ERROR_NONE) + _wait(); + } else { + ret = image_util_decode_run2(decoded, &g_decoded_image); + } + + image_util_decode_destroy(decoded); + + //Encode + ret = image_util_encode_create(g_test_input.image_type, &encoded); + if (ret != IMAGE_UTIL_ERROR_NONE) + return FALSE; + + if (g_test_input.cmd == TEST_DECODE_FILE) { + ret = image_util_encode_run_to_file(encoded, g_decoded_image, g_test_encode.out_path); + } else if (g_test_input.cmd == TEST_DECODE_MEM) { + ret = image_util_encode_run_to_buffer(encoded, g_decoded_image, &buffer, &buffer_size); + + if (_write_file(g_test_encode.out_path, buffer, buffer_size) == FALSE) + fprintf(stderr, "\tWrite the encoded result failed!\n"); + + if (buffer) + free(buffer); + + } else if (g_test_input.cmd == TEST_DECODE_ASYNC) { + ret = image_util_encode_run_async_to_file(encoded, g_decoded_image, g_test_encode.out_path, __encode_to_file_completed_cb, NULL); + _wait(); + } else if (g_test_input.cmd == TEST_DECODE_MEM_ASYNC) { + ret = image_util_encode_run_async_to_buffer(encoded, g_decoded_image, __encode_to_buffer_completed_cb, NULL); + _wait(); + } + + image_util_encode_destroy(encoded); + + return TRUE; +} + +gboolean test_new_encode_agif() +{ + int ret = IMAGE_UTIL_ERROR_NONE; + image_util_agif_encode_h agif_enc = NULL; + image_util_image_h _image = NULL; + unsigned char *buffer = NULL; + size_t buffer_size = 0; + unsigned int i = 0; + + ret = image_util_agif_encode_create(&agif_enc); + if (ret != IMAGE_UTIL_ERROR_NONE) + return FALSE; + + // repeat start + for (i = 0; i < g_num_of_files; i++) { + if (g_test_decode[i].decode_result == FALSE) + continue; + + ret = image_util_create_image(g_test_decode[i].width, g_test_decode[i].height, IMAGE_UTIL_COLORSPACE_RGBA8888, g_test_decode[i].decoded, g_test_decode[i].decode_size, &_image); + if (ret != IMAGE_UTIL_ERROR_NONE) { + image_util_agif_encode_destroy(agif_enc); + return FALSE; + } + + ret = image_util_agif_encode_add_frame(agif_enc, _image, 50); /* 500ms */ + if (ret != IMAGE_UTIL_ERROR_NONE) { + image_util_destroy_image(_image); + image_util_agif_encode_destroy(agif_enc); + return FALSE; + } + + image_util_destroy_image(_image); + } + // repeat end + + if (g_test_input.cmd == GIFTEST_ENCODE_FILE) + ret = image_util_agif_encode_save_to_file(agif_enc, g_test_encode.out_path); + else if (g_test_input.cmd == GIFTEST_ENCODE_MEM) + ret = image_util_agif_encode_save_to_buffer(agif_enc, &buffer, &buffer_size); + else + fprintf(stderr, "\tDo not save the encoded GIF!\n"); + + image_util_agif_encode_destroy(agif_enc); + + if (g_test_input.cmd == GIFTEST_ENCODE_MEM) { + if (_write_file(g_test_encode.out_path, buffer, buffer_size) == FALSE) + fprintf(stderr, "\tWrite the encoded result failed!\n"); + } + + if (buffer) + free(buffer); + + return TRUE; +} + gboolean test_encode_gif() { int ret = 0; @@ -684,6 +875,14 @@ int main(int argc, char *argv[]) fprintf(stderr, "\tTests Start!\n"); +#if 0 + if (!test_new_decode_encode()) { + fprintf(stderr, "\tNew Decode Encode Tests failed!\n"); + _free_datas(); + return 0; + } +#endif + if (test_decode() == FALSE) { //if (test_new_decode() == FALSE) { fprintf(stderr, "\tDecode Tests failed!\n"); @@ -695,12 +894,14 @@ int main(int argc, char *argv[]) if ((g_test_input.cmd == GIFTEST_ENCODE_FILE) || (g_test_input.cmd == GIFTEST_ENCODE_MEM)) { if (test_encode_gif() == FALSE) { + //if (test_new_encode_agif() == FALSE) { fprintf(stderr, "\tEncode(gif) Tests failed!\n"); _free_datas(); return 0; } } else { if (test_encode() == FALSE) { + //if (test_new_encode() == FALSE) { fprintf(stderr, "\tEncode(default) Tests failed!\n"); _free_datas(); return 0; diff --git a/include/image_util_encode.h b/include/image_util_encode.h old mode 100755 new mode 100644 index 5bdfdcb..53fdf1f --- a/include/image_util_encode.h +++ b/include/image_util_encode.h @@ -46,17 +46,28 @@ extern "C" * @retval #IMAGE_UTIL_ERROR_INVALID_PARAMETER Invalid parameter * @retval #IMAGE_UTIL_ERROR_OUT_OF_MEMORY Out of memory * +* @post image_util_encode_run_to_file() +* @post image_util_encode_run_to_buffer() +* @post image_util_encode_run_async_to_file() +* @post image_util_encode_run_async_to_buffer() +* @post image_util_encode_destroy() +* +* @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_create(image_util_type_e image_type, image_util_encode_h *handle); /** +* @deprecated Deprecated since 5.5. Use image_util_create_image() instead. * @brief Sets the resolution of the encoded image. * @since_tizen 3.0 * * @remarks This should be called before calling image_util_encode_run().\n -* While encoding animated gif image, resolution should be set for each frame. +* While encoding animated GIF image, resolution should be set for each frame. * * @param[in] handle The handle of image util encoding * @param[in] width Width of the original image @@ -82,14 +93,15 @@ int image_util_encode_create(image_util_type_e image_type, image_util_encode_h * * @see image_util_encode_run_async() * @see image_util_encode_destroy() */ -int image_util_encode_set_resolution(image_util_encode_h handle, unsigned long width, unsigned long height); +int image_util_encode_set_resolution(image_util_encode_h handle, unsigned long width, unsigned long height) TIZEN_DEPRECATED_API; /** +* @deprecated Deprecated since 5.5. Use image_util_create_image() instead. * @brief Sets the colorspace format for image encoding. * @since_tizen 3.0 * -* @remarks The default colorspace is IMAGE_UTIL_COLORSPACE_RGBA8888.\n -* Use image_util_foreach_supported_colorspace to get supported colorspaces for each image format.\n +* @remarks The default colorspace is #IMAGE_UTIL_COLORSPACE_RGBA8888.\n +* Use image_util_foreach_supported_colorspace() to get supported colorspaces for each image format.\n * Errors would be returned if not supported. * * @param[in] handle The handle of image util encoding @@ -118,14 +130,14 @@ int image_util_encode_set_resolution(image_util_encode_h handle, unsigned long w * @see image_util_encode_run_async() * @see image_util_encode_destroy() */ -int image_util_encode_set_colorspace(image_util_encode_h handle, image_util_colorspace_e colorspace); +int image_util_encode_set_colorspace(image_util_encode_h handle, image_util_colorspace_e colorspace) TIZEN_DEPRECATED_API; /** * @brief Sets the quality for image encoding. * @since_tizen 3.0 * * @remarks If application does not set this, then by default quality of 75 is set.\n -* Quality is supported for JPEG format. IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT will be returned for other formats. +* Quality is supported for JPEG format. #IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT will be returned for other formats. * * @param[in] handle The handle of image util encoding * @param[in] quality Encoding quality from 1~100 @@ -143,21 +155,19 @@ int image_util_encode_set_colorspace(image_util_encode_h handle, image_util_colo * @post image_util_encode_destroy() * * @see image_util_encode_create() -* @see image_util_encode_set_resolution() -* @see image_util_encode_set_input_buffer() -* @see image_util_encode_set_output_path() -* @see image_util_encode_set_output_buffer() -* @see image_util_encode_run() -* @see image_util_encode_run_async() +* @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_quality(image_util_encode_h handle, int quality); /** -* @brief Sets the compression value of png image encoding(0~9). +* @brief Sets the compression value of PNG image encoding(0~9). * @since_tizen 3.0 * -* @remarks If application does not set this, then default compression of 6 is set. +* @remarks If application does not set this, then the default value is #IMAGE_UTIL_PNG_COMPRESSION_6. * * @param[in] handle The handle of image util encoding * @param[in] compression The compression value valid from 0~9 @@ -176,22 +186,21 @@ int image_util_encode_set_quality(image_util_encode_h handle, int quality); * @post image_util_encode_destroy() * * @see image_util_encode_create() -* @see image_util_encode_set_resolution() -* @see image_util_encode_set_input_buffer() -* @see image_util_encode_set_output_path() -* @see image_util_encode_set_output_buffer() -* @see image_util_encode_run() -* @see image_util_encode_run_async() +* @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_png_compression(image_util_encode_h handle, image_util_png_compression_e compression); /** -* @brief Sets the time delay between each frame in the encoded animated gif image. +* @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. * @since_tizen 3.0 * -* @remarks In case animated gif image if this is not set then there will be no delay between each frame.\n -* This should be set for each frame in the animated gif image.\n +* @remarks In case animated GIF image if this is not set then there will be no delay between each frame.\n +* This should be set for each frame in the animated GIF image.\n * This can be set a different value for each frame, which results in different delay time between different frames. * * @param[in] handle The handle of image util encoding @@ -218,16 +227,17 @@ int image_util_encode_set_png_compression(image_util_encode_h handle, image_util * @see image_util_encode_run_async() * @see image_util_encode_destroy() */ -int image_util_encode_set_gif_frame_delay_time(image_util_encode_h handle, unsigned long long delay_time); +int image_util_encode_set_gif_frame_delay_time(image_util_encode_h handle, unsigned long long delay_time) TIZEN_DEPRECATED_API; /** +* @deprecated Deprecated since 5.5. Use image_util_create_image() instead. * @brief Sets the input buffer from which to encode. * @since_tizen 3.0 * * @remarks Either image_util_encode_set_output_path() or image_util_encode_set_output_buffer() should be set.\n -* By default the input buffer colorspace will be considered as IMAGE_UTIL_COLORSPACE_RGBA8888.\n -* Use image_util_encode_set_colorspace to change the colorspace.\n -* While encoding animated gif image, input buffer should be set for each frame. +* By default the input buffer colorspace will be considered as #IMAGE_UTIL_COLORSPACE_RGBA8888.\n +* Use image_util_encode_set_colorspace() to change the colorspace.\n +* While encoding animated GIF image, input buffer should be set for each frame. * * @param[in] handle The handle of image util decoding * @param[in] src_buffer The input image buffer @@ -253,9 +263,10 @@ int image_util_encode_set_gif_frame_delay_time(image_util_encode_h handle, unsig * @see image_util_encode_run_async() * @see image_util_encode_destroy() */ -int image_util_encode_set_input_buffer(image_util_encode_h handle, const unsigned char *src_buffer); +int image_util_encode_set_input_buffer(image_util_encode_h handle, const unsigned char *src_buffer) TIZEN_DEPRECATED_API; /** +* @deprecated Deprecated since 5.5. Use image_util_encode_run_to_file() or image_util_encode_run_async_to_file() instead. * @brief Sets the output path to which to encoded buffer will be written to. * @since_tizen 3.0 * @@ -288,17 +299,18 @@ int image_util_encode_set_input_buffer(image_util_encode_h handle, const unsigne * @see image_util_encode_run_async() * @see image_util_encode_destroy() */ -int image_util_encode_set_output_path(image_util_encode_h handle, const char *path); +int image_util_encode_set_output_path(image_util_encode_h handle, const char *path) TIZEN_DEPRECATED_API; /** +* @deprecated Deprecated since 5.5. Use image_util_encode_run_to_buffer() or image_util_encode_run_async_to_buffer() instead. * @brief Sets the output buffer to which to encoded buffer will be written to. * @since_tizen 3.0 * * @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 -* Before 4.0, output buffer setting is not supported for bmp. IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT will be returned for bmp.\n -* Since 4.0, output buffer setting has been supported for bmp. Applications can set the output buffer to write encoded bmp.\n -* In case of gif encoding, the output buffer will be completely available only after image_util_encode_destroy(). +* Before 4.0, output buffer setting is not supported for BMP. #IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT will be returned for BMP.\n +* Since 4.0, output buffer setting has been supported for BMP. Applications can set the output buffer to write encoded BMP.\n +* In case of GIF encoding, the output buffer will be completely available only after image_util_encode_destroy(). * @a dst_buffer should be released after @c image_util_encode_run() or @c image_util_encode_run_async(). * * @param[in] handle The handle of image util encoding @@ -324,18 +336,19 @@ int image_util_encode_set_output_path(image_util_encode_h handle, const char *pa * @see image_util_encode_run_async() * @see image_util_encode_destroy() */ -int image_util_encode_set_output_buffer(image_util_encode_h handle, unsigned char **dst_buffer); +int image_util_encode_set_output_buffer(image_util_encode_h handle, unsigned char **dst_buffer) TIZEN_DEPRECATED_API; /** +* @deprecated Deprecated since 5.5. Use image_util_encode_run_to_file() or image_util_encode_run_to_buffer() instead. * @brief Starts encoding of the image and fills the output buffer, set using image_util_encode_set_output_buffer() or image_util_encode_set_output_path(). * @since_tizen 3.0 * * @remarks The output will be stored in the pointer set to image_util_encode_set_output_buffer() or image_util_encode_set_output_path().\n * The function executes synchronously.\n -* 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 +* When any of the functions at the pre-condition 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. +* In case of animated GIF encoding, call image_util_encode_run() for each frame to encode progressively. * * @param[in] handle The handle of image util encoding * @param[out] size Size of the encoded image @@ -362,18 +375,19 @@ int image_util_encode_set_output_buffer(image_util_encode_h handle, unsigned cha * @see image_util_encode_set_output_buffer() * @see image_util_encode_destroy() */ -int image_util_encode_run(image_util_encode_h handle, unsigned long long *size); +int image_util_encode_run(image_util_encode_h handle, unsigned long long *size) TIZEN_DEPRECATED_API; /** +* @deprecated Deprecated since 5.5. Use image_util_encode_run_async_to_file() or image_util_encode_run_async_to_buffer() instead. * @brief Starts encoding of the image and fills the output buffer, set using image_util_encode_set_output_buffer() or image_util_encode_set_output_path(). * @since_tizen 3.0 * * @remarks The output will be stored in the pointer set to image_util_encode_set_output_buffer() or image_util_encode_set_output_path().\n * The function executes asynchronously, which contains complete callback.\n -* 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 +* When any of the functions at the pre-condition 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. +* In case of animated GIF encoding, call image_util_encode_run_async() for each frame to encode progressively. * * @param[in] handle The handle of image util encoding * @param[in] callback The callback function to be invoked @@ -401,7 +415,140 @@ int image_util_encode_run(image_util_encode_h handle, unsigned long long *size); * @see image_util_encode_set_output_buffer() * @see image_util_encode_destroy() */ -int image_util_encode_run_async(image_util_encode_h handle, image_util_encode_completed_cb callback, void *user_data); +int image_util_encode_run_async(image_util_encode_h handle, image_util_encode_completed_cb callback, void *user_data) TIZEN_DEPRECATED_API; + +/** +* @brief Encodes the image to a file with the given encode handle. +* @details The function executes synchronously. +* @since_tizen 5.5 +* +* @remarks If any of the functions at the pre-condition are not called, #IMAGE_UTIL_ERROR_INVALID_PARAMETER is returned.\n +* The only supported colorspace for BMP, GIf and PNG is #IMAGE_UTIL_COLORSPACE_RGBA8888.\n +* Use image_util_foreach_supported_colorspace() to get supported colorspaces for JPEG format.\n +* http://tizen.org/privilege/mediastorage is needed if @a file_path points to media storage.\n +* http://tizen.org/privilege/externalstorage is needed if @a file_path points to external storage. +* +* @param[in] handle The handle of image util encoding +* @param[in] image The image handle for encoding +* @param[in] file_path The file path for encoding image +* +* @return @c 0 on success, +* 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 +* +* @pre image_util_encode_create() +* +* @post image_util_encode_destroy() +* +* @see image_util_encode_create() +* @see image_util_encode_destroy() +*/ +int image_util_encode_run_to_file(image_util_encode_h handle, image_util_image_h image, const char *file_path); + +/** +* @brief Encodes the image to a buffer with the given encode handle. +* @details The function executes synchronously. +* @since_tizen 5.5 +* +* @remarks If any of the functions at the pre-condition are not called, #IMAGE_UTIL_ERROR_INVALID_PARAMETER is returned.\n +* The @a buffer should be released using free().\n +* The only supported colorspace for BMP, GIf and PNG is #IMAGE_UTIL_COLORSPACE_RGBA8888.\n +* Use image_util_foreach_supported_colorspace() to get supported colorspaces for JPEG format. +* +* @param[in] handle The handle of image util encoding +* @param[in] image The image handle for encoding +* @param[out] buffer The buffer that encoded image is stored +* @param[out] buffer_size The size of the buffer +* +* @return @c 0 on success, +* 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 +* +* @pre image_util_encode_create() +* +* @post image_util_encode_destroy() +* +* @see image_util_encode_create() +* @see image_util_encode_destroy() +*/ +int image_util_encode_run_to_buffer(image_util_encode_h handle, image_util_image_h image, unsigned char **buffer, size_t *buffer_size); + +/** +* @brief Encodes the image to a file with the given encode handle asynchronously. +* @details The output will be stored in @a file_path. And the function executes asynchronously. +* @since_tizen 5.5 +* +* @remarks If any of the functions at the pre-condition are not called, #IMAGE_UTIL_ERROR_INVALID_PARAMETER is returned.\n +* The only supported colorspace for BMP, GIf and PNG is #IMAGE_UTIL_COLORSPACE_RGBA8888.\n +* Use image_util_foreach_supported_colorspace() to get supported colorspaces for JPEG format.\n +* http://tizen.org/privilege/mediastorage is needed if @a file_path points to media storage.\n +* http://tizen.org/privilege/externalstorage is needed if @a file_path points to external storage. +* +* @param[in] handle The handle of image util encoding +* @param[in] image The image handle for encoding +* @param[in] file_path The file path for encoding image +* @param[in] completed_cb The callback function to be invoked +* @param[in] user_data The user data to be passed to the callback function +* +* @return @c 0 on success, +* otherwise a negative error value +* +* @retval #IMAGE_UTIL_ERROR_NONE Successful +* @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 +* +* @pre image_util_encode_create() +* +* @post image_util_encode_destroy() +* +* @see image_util_encode_create() +* @see image_util_encode_destroy() +*/ +int image_util_encode_run_async_to_file(image_util_encode_h handle, image_util_image_h image, const char *file_path, image_util_encode_to_file_completed_cb completed_cb, void *user_data); + +/** +* @brief Encodes the image to a buffer with the given encode handle asynchronously. +* @details The output will be stored in a buffer provided by the @a completed_cb callback. +* @since_tizen 5.5 +* +* @remarks If any of the @pre function is not called, #IMAGE_UTIL_ERROR_INVALID_PARAMETER is returned.\n +* The only supported colorspace for BMP, GIf and PNG is #IMAGE_UTIL_COLORSPACE_RGBA8888.\n +* Use image_util_foreach_supported_colorspace() to get supported colorspaces for JPEG format. +* +* @param[in] handle The handle of image util encoding +* @param[in] image The image handle for encoding +* @param[in] completed_cb The callback function to be invoked +* @param[in] user_data The user data to be passed to the callback function +* +* @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_OUT_OF_MEMORY Out of memory +* +* @pre image_util_encode_create() +* +* @post image_util_encode_destroy() +* +* @see image_util_encode_create() +* @see image_util_encode_destroy() +*/ +int image_util_encode_run_async_to_buffer(image_util_encode_h handle, image_util_image_h image, image_util_encode_to_buffer_completed_cb completed_cb, void *user_data); /** * @brief Destroys the image encoding handle. @@ -424,6 +571,165 @@ int image_util_encode_run_async(image_util_encode_h handle, image_util_encode_co */ int image_util_encode_destroy(image_util_encode_h handle); +/** +* @brief Creates a handle of animated GIF encoding. +* @since_tizen 5.5 +* +* @remarks The @a handle should be released using image_util_agif_encode_destroy(). +* +* @param[out] handle The handle of animated GIF encoding +* +* @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_OUT_OF_MEMORY Out of memory +* +* @post image_util_agif_encode_destroy() +* +* @see image_util_agif_encode_add_frame() +* @see image_util_agif_encode_save_to_file() +* @see image_util_agif_encode_save_to_buffer() +* @see image_util_agif_encode_destroy() +* +*/ +int image_util_agif_encode_create(image_util_agif_encode_h *handle); + +/** +* @brief Encodes an image and adds the encoded image to the frames of the animated GIF. +* @since_tizen 5.5 +* +* @remarks This function should be called for each @a image which you want to add to the animated GIF. Eeach @a image should be the same size.\n +* The Supported colorspace is #IMAGE_UTIL_COLORSPACE_RGBA8888.\n +* You should call image_util_agif_encode_save_to_file() or image_util_agif_encode_save_to_buffer() to save the animated GIF.\n +* If you call this function after image_util_agif_encode_save_to_file() or image_util_agif_encode_save_to_buffer() function is called, +* this function will encode a new animated GIF. +* +* @param[in] handle The handle of animated GIF encoding +* @param[in] image The handle of the image for each frame +* @param[in] time_delay The time delay between @a image and next image, in 0.01sec units +* +* @return @c 0 on success, +* 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 +* +* @pre image_util_agif_encode_create() +* +* @post image_util_agif_encode_save_to_file() +* @post image_util_agif_encode_save_to_buffer() +* @post image_util_agif_encode_destroy() +* +* @see image_util_agif_encode_create() +* @see image_util_agif_encode_save_to_file() +* @see image_util_agif_encode_save_to_buffer() +* @see image_util_agif_encode_destroy() +* +*/ +int image_util_agif_encode_add_frame(image_util_agif_encode_h handle, image_util_image_h image, unsigned int time_delay); + +/** +* @brief Saves the animated GIF image to the file. +* @details After the data has been written to a file, the file cannot be modified (it's not possible to add frames to it).\n +* The encoder can still be used after the data is written. For example, the following is correct:\n +* +* 1. Add frames 1-10 to an encoder\n +* 2. Save encoder data to file B1\n +* 3. Add more frames (11-20) to the same encoder\n +* 4. Save encoder data to a different file (B2)\n +* +* It would not be possible to save the data to B1 in point 4. +* @since_tizen 5.5 +* +* @remarks http://tizen.org/privilege/mediastorage is needed if @a file_path points to media storage.\n +* http://tizen.org/privilege/externalstorage is needed if @a file_path points to external storage. +* +* @param[in] handle The handle of the animated GIF encoding +* @param[in] file_path The file path for saving the animated GIF +* +* @return @c 0 on success, +* otherwise a negative error value +* +* @retval #IMAGE_UTIL_ERROR_NONE Successful +* @retval #IMAGE_UTIL_ERROR_PERMISSION_DENIED Permission denied +* @retval #IMAGE_UTIL_ERROR_INVALID_PARAMETER Invalid parameter +* @retval #IMAGE_UTIL_ERROR_OUT_OF_MEMORY Out of memory +* @retval #IMAGE_UTIL_ERROR_NO_SUCH_FILE No such file +* +* @pre image_util_agif_encode_create() +* +* @post image_util_agif_encode_destroy() +* +* @see image_util_agif_encode_create() +* @see image_util_agif_encode_add_frame() +* @see image_util_agif_encode_destroy() +* +*/ +int image_util_agif_encode_save_to_file(image_util_agif_encode_h handle, const char *file_path); + +/** +* @brief Saves the animated GIF image to the buffer. +* @details After the data has been written to a buffer, the buffer cannot be modified (it's not possible to add frames to it).\n +* The encoder can still be used after the data is written. For example, the following is correct:\n +* +* 1. Add frames 1-10 to an encoder\n +* 2. Save encoder data to buffer B1\n +* 3. Add more frames (11-20) to the same encoder\n +* 4. Save encoder data to a different buffer (B2)\n +* +* It would not be possible to save the data to B1 in point 4. +* @since_tizen 5.5 +* +* @remarks The @a buffer should be released using free() after using it. +* +* @param[in] handle The handle of the animated GIF encoding +* @param[out] buffer The buffer in which the animated GIF is saved +* @param[out] buffer_size The size of the buffer +* +* @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_OUT_OF_MEMORY Out of memory +* +* @pre image_util_agif_encode_create() +* +* @post image_util_agif_encode_destroy() +* +* @see image_util_agif_encode_create() +* @see image_util_agif_encode_add_frame() +* @see image_util_agif_encode_destroy() +* +*/ +int image_util_agif_encode_save_to_buffer(image_util_agif_encode_h handle, unsigned char **buffer, size_t *buffer_size); + +/** +* @brief Destroys the handle of animated GIF encoding. +* @since_tizen 5.5 +* +* @remarks Any created animated GIF encoding handle created should be destroyed. +* +* @param[in] handle The handle of the animated GIF encoding +* +* @return @c 0 on success, +* otherwise a negative error value +* +* @retval #IMAGE_UTIL_ERROR_NONE Successful +* @retval #IMAGE_UTIL_ERROR_INVALID_PARAMETER Invalid parameter +* +* @pre image_util_agif_encode_create() +* +* @see image_util_agif_encode_create() +* +*/ +int image_util_agif_encode_destroy(image_util_agif_encode_h handle); + /** * @} */ @@ -432,4 +738,4 @@ int image_util_encode_destroy(image_util_encode_h handle); } #endif -#endif /* __TIZEN_MULTIMEDIA_IMAGE_UTIL_ENCODE_H__ */ \ No newline at end of file +#endif /* __TIZEN_MULTIMEDIA_IMAGE_UTIL_ENCODE_H__ */ diff --git a/include/image_util_private.h b/include/image_util_private.h old mode 100755 new mode 100644 index 72e6772..921d13d --- a/include/image_util_private.h +++ b/include/image_util_private.h @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -37,6 +38,7 @@ extern "C" #define FONT_COLOR_RESET "\033[0m" #define FONT_COLOR_RED "\033[31m" #define FONT_COLOR_YELLOW "\033[33m" +#define FONT_COLOR_CYAN "\033[36m" #define image_util_debug(fmt, arg...) do { \ LOGD(FONT_COLOR_RESET""fmt""FONT_COLOR_RESET, ##arg); \ @@ -58,6 +60,10 @@ extern "C" LOGD(FONT_COLOR_YELLOW""FONT_COLOR_RESET); \ } while (0) +#define image_util_sec_debug(fmt, arg...) do { \ + SECURE_LOGD(FONT_COLOR_CYAN#fmt FONT_COLOR_RESET, ##arg); \ + } while (0) + #define image_util_retm_if(expr, fmt, arg...) do { \ if (expr) { \ LOGE(FONT_COLOR_RED""fmt""FONT_COLOR_RESET, ##arg); \ @@ -129,6 +135,16 @@ typedef struct { image_util_encode_completed_cb image_encode_completed_cb; } encode_cb_s; +typedef struct { + void *user_data; + image_util_encode_to_file_completed_cb image_encode_to_file_cb; +} encode_to_file_cb_s; + +typedef struct { + void *user_data; + image_util_encode_to_buffer_completed_cb image_encode_to_buffer_cb; +} encode_to_buffer_cb_s; + typedef struct { mm_image_info_s **sources; unsigned int source_count; @@ -144,7 +160,7 @@ typedef struct { mm_image_info_s src; void **dst_buffer; size_t dst_size; - char *path; + gchar *path; int quality; image_util_png_compression_e compression; gif_encode_s gif_encode_info; @@ -152,8 +168,19 @@ typedef struct { /* for async */ GThread *thread; + image_util_image_h new_src; + encode_to_file_cb_s *encode_to_file_cb; + encode_to_buffer_cb_s *encode_to_buffer_cb; } encode_s; +typedef struct { + void *handle; + + /* for async */ + GThread *thread; + GAsyncQueue *queue; +} encode_agif_s; + typedef struct { image_util_type_e image_type; void *src_buffer; @@ -182,6 +209,8 @@ gboolean is_supported_colorspace(image_util_colorspace_e colorspace, image_util_ unsigned int get_number_of_colorspace(void); int convert_type_of_colorspace(const image_util_colorspace_e colorspace); int convert_type_of_colorspace_with_image_type(const image_util_colorspace_e colorspace, const image_util_type_e type); + +int _check_valid_file(const char *path, int mode); int _image_error_capi(int error_code); /** diff --git a/include/image_util_type.h b/include/image_util_type.h old mode 100755 new mode 100644 index 696cedd..241b429 --- a/include/image_util_type.h +++ b/include/image_util_type.h @@ -248,6 +248,7 @@ typedef void (*image_util_decode_completed2_cb) (int error_code, image_util_imag /** * @ingroup CAPI_MEDIA_IMAGE_UTIL_ENCODE_DECODE_MODULE +* @deprecated Deprecated since 5.5. Use image_util_encode_run_async_to_file() or image_util_encode_run_async_to_buffer() instead. * @brief Called when Image-util encoding is finished just before returning the output. * @since_tizen 3.0 * @@ -263,7 +264,51 @@ typedef void (*image_util_decode_completed2_cb) (int error_code, image_util_imag * * @pre image_util_encode_run() will invoke this function. */ -typedef void (*image_util_encode_completed_cb) (int error_code, void *user_data, unsigned long long size); +typedef void (*image_util_encode_completed_cb) (int error_code, void *user_data, unsigned long long size) TIZEN_DEPRECATED_API; + +/** +* @ingroup CAPI_MEDIA_IMAGE_UTIL_ENCODE_DECODE_MODULE +* @brief Called when image encoding is finished just after storing the output to file. +* @since_tizen 5.5 +* +* @remarks The output will be stored in the file set using image_util_encode_run_to_file(). \n +* The callback is called in a separate thread (not in the main loop). +* +* @param[in] error_code The error code of image util encoding \n +* #IMAGE_UTIL_ERROR_NONE Successful \n +* #IMAGE_UTIL_ERROR_INVALID_PARAMETER Invalid parameter \n +* #IMAGE_UTIL_ERROR_INVALID_OPERATION Invalid operation \n +* #IMAGE_UTIL_ERROR_OUT_OF_MEMORY Out of memory \n +* #IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT Not supported format +* @param[in] user_data The user data passed from the callback registration function +* +* @pre image_util_encode_run_to_file() will invoke this function. +*/ +typedef void (*image_util_encode_to_file_completed_cb) (image_util_error_e error_code, void *user_data); + +/** +* @ingroup CAPI_MEDIA_IMAGE_UTIL_ENCODE_DECODE_MODULE +* @brief Called when image encoding is finished just after storing the output to buffer. +* @since_tizen 5.5 +* +* @remarks The output will be stored in the @a buffer. \n +* The callback is called in a separate thread (not in the main loop).\n +* The @a buffer should not be released by the application.\n +* The @a buffer can be used only in the callback. To use outside, make a copy. +* +* @param[in] error_code The error code of image util encoding \n +* #IMAGE_UTIL_ERROR_NONE Successful \n +* #IMAGE_UTIL_ERROR_INVALID_PARAMETER Invalid parameter \n +* #IMAGE_UTIL_ERROR_INVALID_OPERATION Invalid operation \n +* #IMAGE_UTIL_ERROR_OUT_OF_MEMORY Out of memory \n +* #IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT Not supported format +* @param[in] buffer The buffer for the encoded image +* @param[in] buffer_size The size of the buffer for the encoded image +* @param[in] user_data The user data passed from the callback registration function +* +* @pre image_util_encode_run_to_buffer() will invoke this function. +*/ +typedef void (*image_util_encode_to_buffer_completed_cb) (image_util_error_e error_code, unsigned char *buffer, size_t buffer_size, void *user_data); /** * @ingroup CAPI_MEDIA_IMAGE_UTIL_ENCODE_DECODE_MODULE @@ -279,6 +324,13 @@ typedef void *image_util_decode_h; */ typedef void *image_util_encode_h; +/** +* @ingroup CAPI_MEDIA_IMAGE_UTIL_ENCODE_DECODE_MODULE +* @brief Image-util animation encoding handle. +* @since_tizen 5.5 +*/ +typedef void *image_util_agif_encode_h; + /** * @} */ diff --git a/packaging/capi-media-image-util.spec b/packaging/capi-media-image-util.spec index eb3c586..a2d9073 100755 --- a/packaging/capi-media-image-util.spec +++ b/packaging/capi-media-image-util.spec @@ -1,6 +1,6 @@ Name: capi-media-image-util Summary: A Image Utility library in Tizen Native API -Version: 0.1.49 +Version: 0.2.0 Release: 2 Group: Multimedia/API License: Apache-2.0 diff --git a/src/image_util_encode.c b/src/image_util_encode.c old mode 100755 new mode 100644 index 116a438..6aef251 --- a/src/image_util_encode.c +++ b/src/image_util_encode.c @@ -60,8 +60,14 @@ static void __free_source_buffer(encode_s *handle) { unsigned int i = 0; + image_util_retm_if(!handle, "Invalid handle"); + + if (handle->image_type != IMAGE_UTIL_GIF) + return; + + image_util_retm_if(!handle->gif_encode_info.sources, "Invalid sources"); + image_util_fenter(); - image_util_retm_if(handle == NULL || handle->gif_encode_info.sources == NULL, "Invalid handle"); for (i = 0; i < handle->gif_encode_info.source_count; i++) { IMAGE_UTIL_SAFE_FREE(handle->gif_encode_info.sources[i]); @@ -93,6 +99,11 @@ int image_util_encode_create(image_util_type_e image_type, image_util_encode_h * _handle->src.color = IMAGE_UTIL_COLORSPACE_RGBA8888; + _handle->thread = NULL; + _handle->new_src = NULL; + _handle->encode_to_file_cb = NULL; + _handle->encode_to_buffer_cb = NULL; + if (_handle->image_type == IMAGE_UTIL_GIF) { _handle->gif_encode_info.source_count = 0; _handle->gif_encode_info.current_buffer_count = 0; @@ -111,6 +122,8 @@ int image_util_encode_create(image_util_type_e image_type, image_util_encode_h * *handle = (image_util_encode_h) _handle; + image_util_fleave(); + return err; } @@ -119,6 +132,8 @@ int image_util_encode_set_resolution(image_util_encode_h handle, unsigned long w int err = IMAGE_UTIL_ERROR_NONE; encode_s *_handle = (encode_s *) handle; + image_util_warning("DEPRECATION WARNING: image_util_encode_set_resolution() is deprecated and will be removed from next release. Use image_util_create_image() instead."); + image_util_retvm_if(_handle == NULL, IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle"); image_util_retvm_if((width == 0 || height == 0), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid resolution w : [%lu] h : [%lu]", width, height); @@ -146,6 +161,8 @@ int image_util_encode_set_colorspace(image_util_encode_h handle, image_util_colo { encode_s *_handle = (encode_s *) handle; + image_util_warning("DEPRECATION WARNING: image_util_encode_set_colorspace() is deprecated and will be removed from next release. Use image_util_create_image() instead."); + image_util_retvm_if(_handle == NULL, IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle"); IMAGE_UTIL_TYPE_CHECK(_handle->image_type); @@ -193,6 +210,8 @@ int image_util_encode_set_gif_frame_delay_time(image_util_encode_h handle, unsig image_util_retvm_if(_handle == NULL, IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle"); IMAGE_UTIL_SUPPORT_TYPE_CHECK(_handle->image_type, IMAGE_UTIL_GIF); + image_util_warning("DEPRECATION WARNING: image_util_encode_set_gif_frame_delay_time() is deprecated and will be removed from next release. Use image_util_set_delay_time() instead."); + image_util_retvm_if((delay_time > INT_MAX), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid delay time"); /* multi-src for a-gif */ @@ -212,6 +231,8 @@ int image_util_encode_set_input_buffer(image_util_encode_h handle, const unsigne int err = IMAGE_UTIL_ERROR_NONE; encode_s *_handle = (encode_s *) handle; + image_util_warning("DEPRECATION WARNING: image_util_encode_set_input_buffer() is deprecated and will be removed from next release. Use image_util_create_image() instead."); + image_util_retvm_if(_handle == NULL, IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle"); image_util_retvm_if((src_buffer == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid input buffer"); @@ -235,6 +256,8 @@ int image_util_encode_set_output_path(image_util_encode_h handle, const char *pa { encode_s *_handle = (encode_s *) handle; + image_util_warning("DEPRECATION WARNING: image_util_encode_set_output_path() is deprecated and will be removed from next release. Use image_util_encode_run_to_file() or image_util_encode_run_async_to_file() instead."); + image_util_retvm_if(handle == NULL, IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle"); image_util_retvm_if(!IMAGE_UTIL_STRING_VALID(path), IMAGE_UTIL_ERROR_NO_SUCH_FILE, "Invalid path"); @@ -253,6 +276,8 @@ int image_util_encode_set_output_buffer(image_util_encode_h handle, unsigned cha { encode_s *_handle = (encode_s *) handle; + image_util_warning("DEPRECATION WARNING: image_util_encode_set_output_buffer() is deprecated and will be removed from next release. Use image_util_encode_run_to_buffer() or image_util_encode_run_async_to_buffer() instead."); + image_util_retvm_if(_handle == NULL, IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle"); image_util_retvm_if(dst_buffer == NULL, IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid output buffer"); @@ -263,7 +288,7 @@ int image_util_encode_set_output_buffer(image_util_encode_h handle, unsigned cha return IMAGE_UTIL_ERROR_NONE; } -static int _image_util_encode_internal(encode_s * _handle) +static int __image_util_encode_internal(encode_s * _handle) { int err = MM_UTIL_ERROR_NONE; mm_util_image_h _src = NULL; @@ -331,42 +356,138 @@ static int _image_util_encode_internal(encode_s * _handle) return _image_error_capi(err); } -int image_util_encode_run(image_util_encode_h handle, unsigned long long *size) +static int __image_util_encode_run_to_file(image_util_encode_h handle, image_util_image_h image, const char *file_path) { - int err = IMAGE_UTIL_ERROR_NONE; + int ret = IMAGE_UTIL_ERROR_NONE; encode_s *_handle = (encode_s *) handle; - image_util_retvm_if(_handle == NULL, IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle"); - image_util_retvm_if(_handle->dst_buffer != NULL && size == NULL, IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid parameter"); + image_util_fenter(); - err = _image_util_encode_internal(_handle); - image_util_retvm_if((err != IMAGE_UTIL_ERROR_NONE), err, "_image_util_encode_internal failed"); + image_util_retvm_if(!_handle, IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid handle"); + image_util_retvm_if(!image, IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid image"); + ret = _check_valid_file(file_path, O_RDWR); + image_util_retvm_if(ret != IMAGE_UTIL_ERROR_NONE, ret, "_check_valid_file failed (%d)", ret); - if (size) - *size = _handle->dst_size; + image_util_sec_debug("Image type [%d]. Save to file_path [%s]", _handle->image_type, file_path); - return err; + switch (_handle->image_type) { + case IMAGE_UTIL_JPEG: + ret = mm_util_jpeg_encode_to_file(image, _handle->quality, file_path); + break; + + case IMAGE_UTIL_PNG: + ret = mm_util_encode_to_png_file(image, _handle->compression, file_path); + break; + + case IMAGE_UTIL_GIF: + ret = mm_util_encode_to_gif_file(&image, 1, file_path); + break; + + case IMAGE_UTIL_BMP: + ret = mm_util_encode_bmp_to_file(image, file_path); + break; + + default: + return IMAGE_UTIL_ERROR_INVALID_PARAMETER; + break; + } + + image_util_fleave(); + + return _image_error_capi(ret); +} + +static int __image_util_encode_run_to_buffer(image_util_encode_h handle, image_util_image_h image, unsigned char **buffer, size_t *buffer_size) +{ + int ret = IMAGE_UTIL_ERROR_NONE; + encode_s *_handle = (encode_s *) handle; + + image_util_retvm_if(!_handle, IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid handle"); + image_util_retvm_if(!image, IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid image"); + image_util_retvm_if(!buffer, IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid buffer"); + image_util_retvm_if(!buffer_size, IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid buffer_size"); + + image_util_fenter(); + + switch (_handle->image_type) { + case IMAGE_UTIL_JPEG: + ret = mm_util_encode_to_jpeg_memory(image, _handle->quality, (void **)buffer, buffer_size); + break; + + case IMAGE_UTIL_PNG: + ret = mm_util_encode_to_png_memory(image, _handle->compression, (void **)buffer, buffer_size); + break; + + case IMAGE_UTIL_GIF: + ret = mm_util_encode_to_gif_memory(&image, 1, (void **)buffer, buffer_size); + break; + + case IMAGE_UTIL_BMP: + ret = mm_util_encode_bmp_to_memory(image, (void **)buffer, buffer_size); + break; + default: + return IMAGE_UTIL_ERROR_INVALID_PARAMETER; + break; + } + + image_util_fleave(); + + return _image_error_capi(ret); } gpointer _image_util_encode_thread(gpointer data) { + int ret = IMAGE_UTIL_ERROR_NONE; encode_s *_handle = (encode_s *) data; - int err = IMAGE_UTIL_ERROR_NONE; + unsigned char *buffer = NULL; + size_t buffer_size = 0; image_util_retvm_if((_handle == NULL), NULL, "Invalid Handle"); - err = _image_util_encode_internal(_handle); - if (err == IMAGE_UTIL_ERROR_NONE) - image_util_debug("Success - encode_internal"); - else - image_util_error("Error - encode_internal"); + if (_handle->new_src) { //new encode + if (_handle->path) { + ret = __image_util_encode_run_to_file((image_util_encode_h) data, _handle->new_src, _handle->path); + + if (_handle->encode_to_file_cb) { + image_util_debug("call encode_to_file_cb [%d]", ret); + _handle->encode_to_file_cb->image_encode_to_file_cb(ret, _handle->encode_to_file_cb->user_data); + } else { + image_util_error("No encode_to_file_cb"); + } + + mm_image_destroy_image(_handle->new_src); + IMAGE_UTIL_SAFE_FREE(_handle->encode_to_file_cb); + IMAGE_UTIL_SAFE_G_FREE(_handle->path); + + } else { + ret = __image_util_encode_run_to_buffer((image_util_encode_h) data, _handle->new_src, &buffer, &buffer_size); + if (_handle->encode_to_buffer_cb) { + image_util_debug("call encode_to_buffer_cb"); + _handle->encode_to_buffer_cb->image_encode_to_buffer_cb(ret, buffer, buffer_size, _handle->encode_to_buffer_cb->user_data); + } else { + image_util_error("No encode_to_buffer_cb"); + } + + mm_image_destroy_image(_handle->new_src); + IMAGE_UTIL_SAFE_FREE(_handle->encode_to_buffer_cb); + IMAGE_UTIL_SAFE_FREE(buffer); + } + + } else { //old encode + ret = __image_util_encode_internal(_handle); + if (ret == IMAGE_UTIL_ERROR_NONE) + image_util_debug("Success - encode_internal"); + else + image_util_error("Error - encode_internal"); + + if (_handle->_encode_cb) { + image_util_debug("completed_cb"); + _handle->_encode_cb->image_encode_completed_cb(ret, _handle->_encode_cb->user_data, _handle->dst_size); + } - if (_handle->_encode_cb) { - image_util_debug("completed_cb"); - _handle->_encode_cb->image_encode_completed_cb(err, _handle->_encode_cb->user_data, _handle->dst_size); + IMAGE_UTIL_SAFE_FREE(_handle->_encode_cb); } - IMAGE_UTIL_SAFE_FREE(_handle->_encode_cb); _handle->thread = NULL; image_util_debug("exit thread"); @@ -385,11 +506,32 @@ static int _image_util_encode_create_thread(encode_s * handle) return IMAGE_UTIL_ERROR_NONE; } +int image_util_encode_run(image_util_encode_h handle, unsigned long long *size) +{ + int err = IMAGE_UTIL_ERROR_NONE; + encode_s *_handle = (encode_s *) handle; + + image_util_warning("DEPRECATION WARNING: image_util_encode_run() is deprecated and will be removed from next release. Use image_util_encode_run_to_file() or image_util_encode_run_to_buffer() instead."); + + image_util_retvm_if(_handle == NULL, IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle"); + image_util_retvm_if(_handle->dst_buffer != NULL && size == NULL, IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid parameter"); + + err = __image_util_encode_internal(_handle); + image_util_retvm_if((err != IMAGE_UTIL_ERROR_NONE), err, "__image_util_encode_internal failed"); + + if (size) + *size = _handle->dst_size; + + return err; +} + int image_util_encode_run_async(image_util_encode_h handle, image_util_encode_completed_cb completed_cb, void *user_data) { int err = IMAGE_UTIL_ERROR_NONE; encode_s *_handle = (encode_s *) handle; + image_util_warning("DEPRECATION WARNING: image_util_encode_run_async() is deprecated and will be removed from next release. Use image_util_encode_run_async_to_file() or image_util_encode_run_async_to_buffer() instead."); + image_util_retvm_if(_handle == NULL, IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle"); image_util_retvm_if((_handle->image_type != IMAGE_UTIL_GIF && __is_invalid_image_info(_handle->src)), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid input"); image_util_retvm_if((_handle->image_type == IMAGE_UTIL_GIF && (_handle->gif_encode_info.sources == NULL || __is_invalid_image_info(*_handle->gif_encode_info.sources[0]))), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid input"); @@ -415,6 +557,93 @@ int image_util_encode_run_async(image_util_encode_h handle, image_util_encode_co return err; } +int image_util_encode_run_to_file(image_util_encode_h handle, image_util_image_h image, const char *file_path) +{ + return __image_util_encode_run_to_file(handle, image, file_path); +} + +int image_util_encode_run_to_buffer(image_util_encode_h handle, image_util_image_h image, unsigned char **buffer, size_t *buffer_size) +{ + return __image_util_encode_run_to_buffer(handle, image, buffer, buffer_size); +} + +int image_util_encode_run_async_to_file(image_util_encode_h handle, image_util_image_h image, const char *file_path, image_util_encode_to_file_completed_cb completed_cb, void *user_data) +{ + int ret = IMAGE_UTIL_ERROR_NONE; + encode_s *_handle = (encode_s *) handle; + + image_util_retvm_if(!_handle, IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid handle"); + image_util_retvm_if(!image, IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid image"); + image_util_retvm_if(!completed_cb, IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid completed_cb"); + ret = _check_valid_file(file_path, O_RDWR); + image_util_retvm_if(ret != IMAGE_UTIL_ERROR_NONE, ret, "_check_valid_file failed (%d)", ret); + + image_util_fenter(); + + ret = mm_image_clone_image(image, &_handle->new_src); + image_util_retvm_if(ret != MM_UTIL_ERROR_NONE, IMAGE_UTIL_ERROR_INVALID_OPERATION, "Fail to mm_image_clone_image"); + + _handle->encode_to_file_cb = (encode_to_file_cb_s *) calloc(1, sizeof(encode_to_file_cb_s)); + if (!_handle->encode_to_file_cb) { + image_util_error("Out of memory"); + mm_image_destroy_image(_handle->new_src); + + return IMAGE_UTIL_ERROR_OUT_OF_MEMORY; + } + + _handle->path = g_strdup(file_path); + + _handle->encode_to_file_cb->user_data = user_data; + _handle->encode_to_file_cb->image_encode_to_file_cb = completed_cb; + + ret = _image_util_encode_create_thread(_handle); + if (ret != IMAGE_UTIL_ERROR_NONE) { + mm_image_destroy_image(_handle->new_src); + IMAGE_UTIL_SAFE_FREE(_handle->encode_to_file_cb); + IMAGE_UTIL_SAFE_G_FREE(_handle->path); + } + + image_util_fleave(); + + return ret; +} + +int image_util_encode_run_async_to_buffer(image_util_encode_h handle, image_util_image_h image, image_util_encode_to_buffer_completed_cb completed_cb, void *user_data) +{ + int ret = IMAGE_UTIL_ERROR_NONE; + encode_s *_handle = (encode_s *) handle; + + image_util_retvm_if(!_handle, IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid handle"); + image_util_retvm_if(!image, IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid image"); + image_util_retvm_if(!completed_cb, IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid completed_cb"); + + image_util_fenter(); + + ret = mm_image_clone_image(image, &_handle->new_src); + image_util_retvm_if(ret != MM_UTIL_ERROR_NONE, IMAGE_UTIL_ERROR_INVALID_OPERATION, "Fail to mm_image_clone_image"); + + _handle->encode_to_buffer_cb = (encode_to_buffer_cb_s *) calloc(1, sizeof(encode_to_buffer_cb_s)); + if (!_handle->encode_to_buffer_cb) { + image_util_error("Out of memory"); + mm_image_destroy_image(_handle->new_src); + + return IMAGE_UTIL_ERROR_OUT_OF_MEMORY; + } + + _handle->encode_to_buffer_cb->user_data = user_data; + _handle->encode_to_buffer_cb->image_encode_to_buffer_cb = completed_cb; + + ret = _image_util_encode_create_thread(_handle); + if (ret != IMAGE_UTIL_ERROR_NONE) { + mm_image_destroy_image(_handle->new_src); + IMAGE_UTIL_SAFE_FREE(_handle->encode_to_buffer_cb); + } + + image_util_fleave(); + + return ret; +} + int image_util_encode_destroy(image_util_encode_h handle) { int err = IMAGE_UTIL_ERROR_NONE; @@ -432,8 +661,94 @@ int image_util_encode_destroy(image_util_encode_h handle) __free_source_buffer(_handle); - IMAGE_UTIL_SAFE_FREE(_handle->path); + IMAGE_UTIL_SAFE_G_FREE(_handle->path); IMAGE_UTIL_SAFE_FREE(_handle); return err; } + +int image_util_agif_encode_create(image_util_agif_encode_h *handle) +{ + int ret = IMAGE_UTIL_ERROR_NONE; + mm_gif_file_h _handle = NULL; + + image_util_retvm_if(!handle, IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle"); + + ret = mm_util_gif_encode_create(&_handle); + if (ret != MM_UTIL_ERROR_NONE) { + image_util_error("mm_util_gif_encode_create is failed (%d)", ret); + IMAGE_UTIL_SAFE_FREE(_handle); + return _image_error_capi(ret); + } + + *handle = (image_util_agif_encode_h)_handle; + + return ret; +} + +int image_util_agif_encode_add_frame(image_util_agif_encode_h handle, image_util_image_h image, unsigned int time_delay) +{ + int ret = IMAGE_UTIL_ERROR_NONE; + mm_gif_file_h _handle = (mm_gif_file_h)handle; + + image_util_retvm_if(!handle, IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle"); + + ret = mm_image_set_delay_time((mm_util_image_h)image, time_delay); + if (ret != MM_UTIL_ERROR_NONE) { + image_util_error("mm_image_set_delay_time is failed (%d)", ret); + return _image_error_capi(ret); + } + + ret = mm_util_gif_encode_add_image(_handle, (mm_image_info_s *)image); + if (ret != MM_UTIL_ERROR_NONE) { + image_util_error("mm_util_gif_encode_add_image is failed (%d)", ret); + return _image_error_capi(ret); + } + + return ret; +} + +int image_util_agif_encode_save_to_file(image_util_agif_encode_h handle, const char *file_path) +{ + int ret = IMAGE_UTIL_ERROR_NONE; + mm_gif_file_h _handle = (mm_gif_file_h)handle; + + image_util_retvm_if(!handle, IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle"); + + ret = mm_util_gif_encode_set_file(_handle, file_path); + image_util_retvm_if(ret != MM_UTIL_ERROR_NONE, _image_error_capi(ret), "mm_util_gif_encode_set_file is failed (%d)", ret); + + ret = mm_util_gif_encode_save(_handle); + image_util_retvm_if(ret != MM_UTIL_ERROR_NONE, _image_error_capi(ret), "mm_util_gif_encode_save is failed (%d)", ret); + + return ret; +} + +int image_util_agif_encode_save_to_buffer(image_util_agif_encode_h handle, unsigned char **buffer, size_t *buffer_size) +{ + int ret = IMAGE_UTIL_ERROR_NONE; + mm_gif_file_h _handle = (mm_gif_file_h)handle; + + image_util_retvm_if(!handle, IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle"); + + ret = mm_util_gif_encode_set_mem(_handle, (void **)buffer, buffer_size); + image_util_retvm_if(ret != MM_UTIL_ERROR_NONE, _image_error_capi(ret), "mm_util_gif_encode_set_mem is failed (%d)", ret); + + ret = mm_util_gif_encode_save(_handle); + image_util_retvm_if(ret != MM_UTIL_ERROR_NONE, _image_error_capi(ret), "mm_util_gif_encode_save is failed (%d)", ret); + + return ret; +} + +int image_util_agif_encode_destroy(image_util_agif_encode_h handle) +{ + mm_gif_file_h _handle = (mm_gif_file_h)handle; + + image_util_fenter(); + + image_util_retvm_if(!handle, IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle"); + + mm_util_gif_encode_destroy(_handle); + + return IMAGE_UTIL_ERROR_NONE; +} diff --git a/src/image_util_private.c b/src/image_util_private.c index efcc59a..411752d 100755 --- a/src/image_util_private.c +++ b/src/image_util_private.c @@ -14,6 +14,9 @@ * limitations under the License. */ +#include +#include +#include #include #include @@ -184,6 +187,30 @@ int convert_type_of_colorspace_with_image_type(const image_util_colorspace_e col return new_colorspace; } +int _check_valid_file(const char *path, int mode) +{ + int ret = IMAGE_UTIL_ERROR_NONE; + int fd = 0; + + image_util_retvm_if(!path, IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid path"); + + fd = open(path, mode); + + if (fd < 0) { + if (errno == EACCES || errno == EPERM) { + image_util_error("Fail to open path[%s]: Permission Denied", path); + ret = IMAGE_UTIL_ERROR_PERMISSION_DENIED; + } else { + image_util_error("Fail to open path[%s]: Invalid Path", path); + ret = IMAGE_UTIL_ERROR_INVALID_PARAMETER; + } + } else { + close(fd); + } + + return ret; +} + int _image_error_capi(int error_code) { if (error_code != MM_UTIL_ERROR_NONE)