ADD_SUBDIRECTORY(jpeg)
ADD_SUBDIRECTORY(magick)
ADD_SUBDIRECTORY(webp)
+ADD_SUBDIRECTORY(anim)
IF(UNIX)
--- /dev/null
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+SET(fw_name "mmutil_anim")
+
+PROJECT(${fw_name})
+
+SET(VERSION_MAJOR 0)
+SET(VERSION "${VERSION_MAJOR}.0.0")
+SET(CMAKE_INSTALL_PREFIX /usr)
+SET(PREFIX ${CMAKE_INSTALL_PREFIX})
+
+SET(INC_DIR
+ include
+)
+INCLUDE_DIRECTORIES(${INC_DIR}
+ ../common/include
+ ../magick/include
+)
+
+SET(dependents "dlog glib-2.0")
+
+INCLUDE(FindPkgConfig)
+pkg_check_modules(${fw_name} REQUIRED ${dependents})
+FOREACH(flag ${${fw_name}_CFLAGS})
+ SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -fPIC -Wall -Werror")
+SET(CMAKE_C_FLAGS_DEBUG "-O0 -g")
+
+IF("${ARCH}" STREQUAL "arm")
+ ADD_DEFINITIONS("-DTARGET")
+ENDIF("${ARCH}" STREQUAL "arm")
+
+ADD_DEFINITIONS("-DPREFIX=\"${CMAKE_INSTALL_PREFIX}\"")
+ADD_DEFINITIONS("-DLIBPREFIX=\"${LIB_INSTALL_DIR}\"")
+ADD_DEFINITIONS("-DTIZEN_DEBUG")
+
+SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed -Wl,--rpath=${LIB_INSTALL_DIR}")
+
+aux_source_directory(. SOURCES)
+ADD_LIBRARY(${fw_name} SHARED ${SOURCES})
+TARGET_LINK_LIBRARIES(${fw_name} ${${fw_name}_LDFLAGS} mmutil_common)
+SET_TARGET_PROPERTIES(${fw_name}
+ PROPERTIES
+ VERSION ${VERSION}
+ SOVERSION ${VERSION_MAJOR}
+ CLEAN_DIRECT_OUTPUT 1
+)
+
+INSTALL(TARGETS ${fw_name} DESTINATION ${LIB_INSTALL_DIR})
+INSTALL(
+ DIRECTORY ${INC_DIR}/ DESTINATION include/mmf
+ FILES_MATCHING
+ PATTERN "*_internal.h" EXCLUDE
+ PATTERN "*_private.h" EXCLUDE
+ PATTERN "${INC_DIR}/*.h"
+)
+
+SET(PC_NAME mmutil-anim)
+SET(PC_LDFLAGS -l${fw_name})
+SET(PC_FILE_NAME ${PC_NAME}.pc.in)
+
+CONFIGURE_FILE(
+ ${PC_FILE_NAME}
+ ${CMAKE_CURRENT_SOURCE_DIR}/${PC_NAME}.pc
+ @ONLY
+)
+INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${PC_NAME}.pc DESTINATION ${LIB_INSTALL_DIR}/pkgconfig)
+
+ADD_SUBDIRECTORY(test)
+#IF(BUILD_GTESTS)
+# ADD_SUBDIRECTORY(unittest)
+#ENDIF(BUILD_GTESTS)
--- /dev/null
+/*
+* Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#ifndef __MM_UTIL_ANIM_H__
+#define __MM_UTIL_ANIM_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdbool.h>
+#include "mm_util_type.h"
+
+typedef void *mm_util_anim_enc_h;
+
+int mm_util_anim_enc_create(mm_util_anim_codec_type type, mm_util_anim_enc_h *anim_enc_h);
+int mm_util_anim_enc_set_bgcolor(mm_util_anim_enc_h anim_enc_h, unsigned char r, unsigned char g, unsigned char b, unsigned char a);
+int mm_util_anim_enc_set_loop_count(mm_util_anim_enc_h anim_enc_h, unsigned int loop_count);
+int mm_util_anim_enc_set_lossless(mm_util_anim_enc_h anim_enc_h, bool lossless);
+int mm_util_anim_enc_add_image(mm_util_anim_enc_h anim_enc_h, mm_util_image_h image);
+int mm_util_anim_enc_save_to_file(mm_util_anim_enc_h anim_enc_h, const char *path);
+int mm_util_anim_enc_save_to_buffer(mm_util_anim_enc_h anim_enc_h, unsigned char **buf, size_t *buf_size);
+void mm_util_anim_enc_destroy(mm_util_anim_enc_h anim_enc_h);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /*__MM_UTIL_ANIM_H__*/
--- /dev/null
+/*
+* Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#include <stdio.h>
+#include <dlfcn.h> /* for dlopen, dlsym and dlclose */
+#include <glib.h>
+
+#include "mm_util_anim.h"
+#include "mm_util_private.h"
+
+typedef anim_enc_module_t *(*ANIM_ENC_REGISTER)(void);
+
+typedef struct {
+ void *dl_h;
+ anim_enc_module_t *module;
+ void *enc_h;
+} anim_enc_t;
+
+static const char *mm_util_anim_libs[] = {
+ LIBPREFIX"/libmmutil_gif.so", /* IMG_CODEC_GIF */
+ LIBPREFIX"/libmmutil_webp.so", /* IMG_CODEC_WEBP */
+ NULL,
+};
+
+static int __anim_open_module(mm_util_anim_codec_type type, anim_enc_t *anim_enc)
+{
+ void *dl_handle = NULL;
+ void *module_register = NULL;
+ anim_enc_module_t *module = NULL;
+
+ mm_util_retvm_if(!anim_enc, MM_UTIL_ERROR_INVALID_PARAMETER, "invalid anim_enc_h");
+ mm_util_retvm_if((type >= ANIM_CODEC_UNKNOWN_TYPE) || !mm_util_anim_libs[type], MM_UTIL_ERROR_NOT_SUPPORTED_FORMAT,
+ "invalid type(%d)", type);
+
+ dl_handle = dlopen(mm_util_anim_libs[type], RTLD_LAZY);
+ mm_util_retvm_if(!dl_handle, MM_UTIL_ERROR_INVALID_OPERATION, "%s", dlerror());
+
+ module_register = dlsym(dl_handle, "anim_enc_module_register");
+ if (!module_register) {
+ mm_util_error("Error! can't register module: %s", dlerror());
+ goto FAIL;
+ }
+
+ module = ((ANIM_ENC_REGISTER)module_register)();
+ if (!module) {
+ mm_util_error("Error! module_register");
+ goto FAIL;
+ }
+
+ anim_enc->dl_h = dl_handle;
+ anim_enc->module = module;
+
+ return MM_UTIL_ERROR_NONE;
+
+FAIL:
+ dlclose(dl_handle);
+ return MM_UTIL_ERROR_INVALID_OPERATION;
+}
+
+static void __anim_close_module(anim_enc_t *anim_enc)
+{
+ if (!anim_enc || !anim_enc->dl_h)
+ return;
+
+ g_free(anim_enc->module);
+ anim_enc->module = NULL;
+
+ dlclose(anim_enc->dl_h);
+ anim_enc->dl_h = NULL;
+}
+
+int mm_util_anim_enc_create(mm_util_anim_codec_type type, mm_util_anim_enc_h *anim_enc_h)
+{
+ int ret = MM_UTIL_ERROR_NONE;
+ anim_enc_t *anim_enc = NULL;
+
+ mm_util_retvm_if(!anim_enc_h, MM_UTIL_ERROR_INVALID_PARAMETER, "invalid anim_enc_h");
+
+ anim_enc = g_new0(anim_enc_t, 1);
+
+ ret = __anim_open_module(type, anim_enc);
+ if (ret != MM_UTIL_ERROR_NONE) {
+ mm_util_error("Error! __open_module");
+ goto FAIL;
+ }
+
+ if (!anim_enc->module->create) {
+ mm_util_error("Error! not supported create (%d)", ret);
+ ret = MM_UTIL_ERROR_NOT_SUPPORTED_FORMAT;
+ goto FAIL;
+ }
+
+ ret = anim_enc->module->create(&(anim_enc->enc_h));
+ if (ret != MM_UTIL_ERROR_NONE) {
+ mm_util_error("Error! module->create (%d)", ret);
+ goto FAIL;
+ }
+
+ *anim_enc_h = anim_enc;
+ return MM_UTIL_ERROR_NONE;
+
+FAIL:
+ __anim_close_module(anim_enc);
+ g_free(anim_enc);
+ return ret;
+}
+
+int mm_util_anim_enc_set_bgcolor(mm_util_anim_enc_h anim_enc_h, unsigned char r, unsigned char g, unsigned char b, unsigned char a)
+{
+ anim_enc_t *anim_enc = (anim_enc_t *)anim_enc_h;
+
+ mm_util_retvm_if(!anim_enc_h, MM_UTIL_ERROR_INVALID_PARAMETER, "invalid anim_enc_h");
+ mm_util_retvm_if(!anim_enc->module, MM_UTIL_ERROR_INVALID_PARAMETER, "invalid module");
+ mm_util_retvm_if(!anim_enc->module->set_bgcolor, MM_UTIL_ERROR_NOT_SUPPORTED_FORMAT, "not supported format");
+
+ return anim_enc->module->set_bgcolor(anim_enc->enc_h, a, r, g, b);
+}
+
+int mm_util_anim_enc_set_loop_count(mm_util_anim_enc_h anim_enc_h, unsigned int loop_count)
+{
+ anim_enc_t *anim_enc = (anim_enc_t *)anim_enc_h;
+
+ mm_util_retvm_if(!anim_enc_h, MM_UTIL_ERROR_INVALID_PARAMETER, "invalid anim_enc_h");
+ mm_util_retvm_if(!anim_enc->module, MM_UTIL_ERROR_INVALID_PARAMETER, "invalid module");
+ mm_util_retvm_if(!anim_enc->module->set_loop_count, MM_UTIL_ERROR_NOT_SUPPORTED_FORMAT, "not supported format");
+
+ return anim_enc->module->set_loop_count(anim_enc->enc_h, loop_count);
+}
+
+int mm_util_anim_enc_set_lossless(mm_util_anim_enc_h anim_enc_h, bool lossless)
+{
+ anim_enc_t *anim_enc = (anim_enc_t *)anim_enc_h;
+
+ mm_util_retvm_if(!anim_enc_h, MM_UTIL_ERROR_INVALID_PARAMETER, "invalid anim_enc_h");
+ mm_util_retvm_if(!anim_enc->module, MM_UTIL_ERROR_INVALID_PARAMETER, "invalid module");
+ mm_util_retvm_if(!anim_enc->module->set_lossless, MM_UTIL_ERROR_NOT_SUPPORTED_FORMAT, "not supported format");
+
+ return anim_enc->module->set_lossless(anim_enc->enc_h, lossless);
+}
+
+int mm_util_anim_enc_add_image(mm_util_anim_enc_h anim_enc_h, mm_util_image_h image)
+{
+ anim_enc_t *anim_enc = (anim_enc_t *)anim_enc_h;
+
+ mm_util_retvm_if(!anim_enc_h, MM_UTIL_ERROR_INVALID_PARAMETER, "invalid anim_enc_h");
+ mm_util_retvm_if(!anim_enc->module, MM_UTIL_ERROR_INVALID_PARAMETER, "invalid module");
+ mm_util_retvm_if(!anim_enc->module->add_image, MM_UTIL_ERROR_NOT_SUPPORTED_FORMAT, "not supported format");
+
+ return anim_enc->module->add_image(anim_enc->enc_h, image);
+}
+
+int mm_util_anim_enc_save_to_file(mm_util_anim_enc_h anim_enc_h, const char *path)
+{
+ anim_enc_t *anim_enc = (anim_enc_t *)anim_enc_h;
+
+ mm_util_retvm_if(!anim_enc_h, MM_UTIL_ERROR_INVALID_PARAMETER, "invalid anim_enc_h");
+ mm_util_retvm_if(!anim_enc->module, MM_UTIL_ERROR_INVALID_PARAMETER, "invalid module");
+ mm_util_retvm_if(!anim_enc->module->save_to_file, MM_UTIL_ERROR_NOT_SUPPORTED_FORMAT, "not supported format");
+
+ return anim_enc->module->save_to_file(anim_enc->enc_h, path);
+}
+
+int mm_util_anim_enc_save_to_buffer(mm_util_anim_enc_h anim_enc_h, unsigned char **buf, size_t *buf_size)
+{
+ anim_enc_t *anim_enc = (anim_enc_t *)anim_enc_h;
+
+ mm_util_retvm_if(!anim_enc_h, MM_UTIL_ERROR_INVALID_PARAMETER, "invalid anim_enc_h");
+ mm_util_retvm_if(!anim_enc->module, MM_UTIL_ERROR_INVALID_PARAMETER, "invalid module");
+ mm_util_retvm_if(!anim_enc->module->save_to_buffer, MM_UTIL_ERROR_NOT_SUPPORTED_FORMAT, "not supported format");
+
+ return anim_enc->module->save_to_buffer(anim_enc->enc_h, (void **)buf, buf_size);
+}
+
+void mm_util_anim_enc_destroy(mm_util_anim_enc_h anim_enc_h)
+{
+ anim_enc_t *anim_enc = (anim_enc_t *)anim_enc_h;
+
+ if (!anim_enc_h)
+ return;
+
+ if (anim_enc->module && anim_enc->module->destroy)
+ anim_enc->module->destroy(anim_enc->enc_h);
+
+ __anim_close_module(anim_enc);
+
+ g_free(anim_enc);
+}
--- /dev/null
+prefix=@PREFIX@
+exec_prefix=/usr
+libdir=@LIB_INSTALL_DIR@
+includedir=/usr/include/mmf
+
+Name : @PC_NAME@
+Description : Multimedia Framework Utility Library
+Requires :
+Version : @VERSION@
+Libs : -L${libdir} @PC_LDFLAGS@
+Cflags : -I${includedir}
--- /dev/null
+SET(fw_name "mmutil_anim")
+SET(fw_test "${fw_name}-test")
+
+INCLUDE(FindPkgConfig)
+pkg_check_modules(${fw_test} REQUIRED glib-2.0 dlog libtzplatform-config)
+FOREACH(flag ${${fw_test}_CFLAGS})
+ SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -Wall -fPIE")
+
+aux_source_directory(. sources)
+FOREACH(src ${sources})
+ GET_FILENAME_COMPONENT(src_name ${src} NAME_WE)
+ MESSAGE("${src_name}")
+ ADD_EXECUTABLE(${src_name} ${src})
+ TARGET_LINK_LIBRARIES(${src_name} ${fw_name} ${${fw_test}_LDFLAGS} mmutil_common mmutil_magick)
+ENDFOREACH()
--- /dev/null
+/*
+* Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <glib.h>
+#include <limits.h>
+
+#include <mm_util_anim.h>
+#include <mm_util_image.h>
+#include <mm_util_magick.h>
+#include <tzplatform_config.h>
+
+#define TEST_STRING_VALID(str) ((str != NULL && strlen(str) > 0) ? TRUE : FALSE)
+
+#define WEBP_ENCODE_FILE_PATH tzplatform_mkpath(TZ_USER_CONTENT, "anim_test_enc_file.webp")
+#define WEBP_ENCODE_MEM_PATH tzplatform_mkpath(TZ_USER_CONTENT, "anim_test_enc_mem.webp")
+#define GIF_ENCODE_FILE_PATH tzplatform_mkpath(TZ_USER_CONTENT, "anim_test_enc_file.gif")
+#define GIF_ENCODE_MEM_PATH tzplatform_mkpath(TZ_USER_CONTENT, "anim_test_enc_mem.gif")
+
+/* for test parameters */
+#define TEST_COLOR_SPACE MM_UTIL_COLOR_RGBA
+#define TEST_DELAY_TIME 500 // 500ms
+#define TEST_LOOP_COUNT 3 // if loop_count is 0, it is infinite loop
+
+static char *g_path = NULL;
+
+/* for reading files */
+static GQueue *g_queue_files = NULL;
+static GQueue *g_queue_images = NULL;
+
+/* for test parameters */
+static uint8_t g_bgcolor[] = { 0xFF, 0x00, 0x00, 0x00 }; // black
+
+static void __decode_func(gpointer data, gpointer user_data)
+{
+ int ret = MM_UTIL_ERROR_NONE;
+ char *path = (char *)data;
+ mm_util_image_h image = NULL;
+
+ if (!TEST_STRING_VALID(path)) {
+ g_print("\t[ANIM_testsuite] invalid path %s\n", path);
+ return;
+ }
+
+ ret = mm_util_decode_image_from_file(path, TEST_COLOR_SPACE, &image);
+ if (ret != MM_UTIL_ERROR_NONE) {
+ g_print("\t[ANIM_testsuite] mm_util_decode_image_from_file failed %d\n", ret);
+ return;
+ }
+
+ ret = mm_image_set_delay_time(image, TEST_DELAY_TIME);
+ if (ret != MM_UTIL_ERROR_NONE) {
+ g_print("\t[ANIM_testsuite] mm_image_set_delay_time failed %d\n", ret);
+ return;
+ }
+
+ g_queue_push_tail(g_queue_images, image);
+}
+
+static gboolean __decode_files_in_queue()
+{
+ if (g_queue_images)
+ g_queue_free_full(g_queue_images, mm_image_destroy_image);
+
+ g_queue_images = g_queue_new();
+
+ g_queue_foreach(g_queue_files, __decode_func, NULL);
+
+ if (g_queue_images->length == 0) {
+ g_print("\t[ANIM_testsuite] no test image\n");
+ return FALSE;
+ }
+
+ g_print("[ANIM_testsuite] %u images have been decoded.\n", g_queue_images->length);
+
+ return TRUE;
+}
+
+static int __sort_compare(gconstpointer a, gconstpointer b, gpointer user_data)
+{
+ const char *_a = (const char *)a;
+ const char *_b = (const char *)b;
+ if (strlen(_a) < strlen(_b))
+ return -1;
+
+ if (strlen(_a) > strlen(_b))
+ return 1;
+
+ return g_ascii_strcasecmp(_a, _b);
+}
+
+static gboolean __set_input_dir(const char *path)
+{
+ GDir *dir = NULL;
+ const gchar *filename = NULL;
+ GError *g_error = NULL;
+
+ g_print("[ANIM_testsuite] path: %s\n", path);
+
+ dir = g_dir_open(path, 0, &g_error);
+ if (!dir) {
+ g_print("\t[ANIM_testsuite] invalid directory: %s (%s)\n", path, g_error ? g_error->message : "none");
+ if (g_error)
+ g_error_free(g_error);
+ return FALSE;
+ }
+
+ if (g_queue_files)
+ g_queue_free_full(g_queue_files, g_free);
+
+ g_queue_files = g_queue_new();
+
+ /* push files of dir into queue */
+ while (1) {
+ filename = g_dir_read_name(dir);
+ if (!filename)
+ break;
+
+ g_queue_insert_sorted(g_queue_files, g_strdup_printf("%s/%s", path, filename), __sort_compare, NULL);
+ }
+
+ g_dir_close(dir);
+
+ if (g_queue_files->length == 0) {
+ g_print("\t[ANIM_testsuite] no test file in directory!\n");
+ return FALSE;
+ }
+
+ /* decode files of dir */
+ if (!__decode_files_in_queue()) {
+ g_print("\t[ANIM_testsuite] fail to decode images!\n");
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static void __print_help(const char *argv0)
+{
+ fprintf(stderr, "\t[usage] Encode animation webp with images\n");
+ fprintf(stderr, "\t\t1. encode : %s directory(has numeric named files)\n", argv0);
+ fprintf(stderr, "\t\t2. support jpeg/png/gif/bmp/webp files to animation webp\n");
+}
+
+static gboolean __get_arguments(int argc, char *argv[])
+{
+ g_path = g_strdup(argv[1]);
+
+ if (!TEST_STRING_VALID(g_path)) {
+ fprintf(stderr, "\t[ANIM_testsuite] invalid path %s\n", argv[1]);
+ return FALSE;
+ }
+
+ if (!__set_input_dir(g_path)) {
+ fprintf(stderr, "\t[ANIM_testsuite] __set_input_dir failed\n");
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static void __add_image(gpointer data, gpointer user_data)
+{
+ mm_util_anim_enc_h anim_enc = (mm_util_anim_enc_h)user_data;
+ int ret = 0;
+
+ if (!anim_enc) {
+ fprintf(stderr, "\t[ANIM_testsuite] invalid user_data\n");
+ return ;
+ }
+
+ ret = mm_util_anim_enc_add_image(anim_enc, (mm_util_image_h)data);
+ if (ret != MM_UTIL_ERROR_NONE)
+ fprintf(stderr, "\t[ANIM_testsuite] mm_util_webp_anim_enc_add_image failed : %d\n", ret);
+}
+
+static gboolean __test_encode_to_file(mm_util_img_codec_type type, const char *path)
+{
+ int ret = 0;
+ mm_util_anim_enc_h anim_enc = NULL;
+
+ fprintf(stderr, "[ANIM_testsuite] The test begins: %d, %s\n", type, path);
+
+ ret = mm_util_anim_enc_create(type, &anim_enc);
+ if (ret != MM_UTIL_ERROR_NONE) {
+ fprintf(stderr, "\t[ANIM_testsuite] mm_util_webp_anim_enc_create failed : %d\n", ret);
+ return FALSE;
+ }
+
+ ret = mm_util_anim_enc_set_bgcolor(anim_enc, g_bgcolor[0], g_bgcolor[1], g_bgcolor[2], g_bgcolor[3]);
+ if (ret != MM_UTIL_ERROR_NONE) {
+ fprintf(stderr, "\t[ANIM_testsuite] mm_util_webp_anim_enc_set_bgcolor failed : %d\n", ret);
+ if (ret != MM_UTIL_ERROR_NOT_SUPPORTED_FORMAT)
+ goto END;
+ }
+
+ ret = mm_util_anim_enc_set_loop_count(anim_enc, TEST_LOOP_COUNT);
+ if (ret != MM_UTIL_ERROR_NONE) {
+ fprintf(stderr, "\t[ANIM_testsuite] mm_util_webp_anim_enc_set_loop_count failed : %d\n", ret);
+ if (ret != MM_UTIL_ERROR_NOT_SUPPORTED_FORMAT)
+ goto END;
+ }
+
+ ret = mm_util_anim_enc_set_lossless(anim_enc, TRUE);
+ if (ret != MM_UTIL_ERROR_NONE) {
+ fprintf(stderr, "\t[ANIM_testsuite] mm_util_anim_enc_set_lossless failed : %d\n", ret);
+ if (ret != MM_UTIL_ERROR_NOT_SUPPORTED_FORMAT)
+ goto END;
+ }
+
+ g_queue_foreach(g_queue_images, __add_image, anim_enc);
+
+ ret = mm_util_anim_enc_save_to_file(anim_enc, path);
+ if (ret != MM_UTIL_ERROR_NONE)
+ fprintf(stderr, "\t[ANIM_testsuite] mm_util_encode_webp_to_file failed : %d\n", ret);
+
+END:
+ mm_util_anim_enc_destroy(anim_enc);
+
+ fprintf(stderr, "[ANIM_testsuite] The test ended\n");
+
+ if (ret != MM_UTIL_ERROR_NONE)
+ return FALSE;
+
+ return TRUE;
+}
+
+static gboolean __test_encode_to_buffer(mm_util_img_codec_type type, const char *path)
+{
+ int ret = 0;
+ mm_util_anim_enc_h anim_enc = NULL;
+ /* for encoding webp to memory */
+ unsigned char *encoded_data = NULL;
+ size_t encoded_size = 0;
+ GError *g_error = NULL;
+
+ fprintf(stderr, "[ANIM_testsuite] The test begins: %d, %s\n", type, path);
+
+ ret = mm_util_anim_enc_create(type, &anim_enc);
+ if (ret != MM_UTIL_ERROR_NONE) {
+ fprintf(stderr, "\t[ANIM_testsuite] mm_util_webp_anim_enc_create failed : %d\n", ret);
+ return FALSE;
+ }
+
+ ret = mm_util_anim_enc_set_bgcolor(anim_enc, g_bgcolor[0], g_bgcolor[1], g_bgcolor[2], g_bgcolor[3]);
+ if (ret != MM_UTIL_ERROR_NONE) {
+ fprintf(stderr, "\t[ANIM_testsuite] mm_util_webp_anim_enc_set_bgcolor failed : %d\n", ret);
+ if (ret != MM_UTIL_ERROR_NOT_SUPPORTED_FORMAT)
+ goto END;
+ }
+
+ ret = mm_util_anim_enc_set_loop_count(anim_enc, TEST_LOOP_COUNT);
+ if (ret != MM_UTIL_ERROR_NONE) {
+ fprintf(stderr, "\t[ANIM_testsuite] mm_util_webp_anim_enc_set_loop_count failed : %d\n", ret);
+ if (ret != MM_UTIL_ERROR_NOT_SUPPORTED_FORMAT)
+ goto END;
+ }
+
+ ret = mm_util_anim_enc_set_lossless(anim_enc, true);
+ if (ret != MM_UTIL_ERROR_NONE) {
+ fprintf(stderr, "\t[ANIM_testsuite] mm_util_anim_enc_set_lossless failed : %d\n", ret);
+ if (ret != MM_UTIL_ERROR_NOT_SUPPORTED_FORMAT)
+ goto END;
+ }
+
+ g_queue_foreach(g_queue_images, __add_image, anim_enc);
+
+ ret = mm_util_anim_enc_save_to_buffer(anim_enc, &encoded_data, &encoded_size);
+ if (ret != MM_UTIL_ERROR_NONE) {
+ fprintf(stderr, "\t[ANIM_testsuite] mm_util_webp_anim_enc_save_to_buffer failed : %d\n", ret);
+ goto END;
+ }
+
+ if (!g_file_set_contents(path, (gchar *)encoded_data, (gssize)encoded_size, &g_error)) {
+ fprintf(stderr, "\t[ANIM_testsuite] g_file_set_contents failed : %s\n", g_error ? g_error->message : "none");
+ if (g_error)
+ g_error_free(g_error);
+ }
+
+END:
+ mm_util_anim_enc_destroy(anim_enc);
+ g_free(encoded_data);
+
+ fprintf(stderr, "[ANIM_testsuite] The test ended\n");
+
+ if (ret != MM_UTIL_ERROR_NONE)
+ return FALSE;
+
+ return TRUE;
+}
+
+int main(int argc, char *argv[])
+{
+ if (argc < 2) {
+ __print_help(argv[0]);
+ return 0;
+ }
+
+ if (FALSE == __get_arguments(argc, argv)) {
+ fprintf(stderr, "\t[ANIM_testsuite] _get_arguments failed\n");
+ goto out;
+ }
+
+ /* test encoding webp animation to file */
+ if (FALSE == __test_encode_to_file(ANIM_CODEC_WEBP, WEBP_ENCODE_FILE_PATH)) {
+ fprintf(stderr, "\t[ANIM_testsuite] __test_encode_to_file failed\n");
+ goto out;
+ }
+
+ /* test encoding webp animation to buffer */
+ if (FALSE == __test_encode_to_buffer(ANIM_CODEC_WEBP, WEBP_ENCODE_MEM_PATH)) {
+ fprintf(stderr, "\t[ANIM_testsuite] __test_encode_to_buffer failed\n");
+ goto out;
+ }
+
+ /* test encoding agif animation to file */
+ if (FALSE == __test_encode_to_file(ANIM_CODEC_GIF, GIF_ENCODE_FILE_PATH)) {
+ fprintf(stderr, "\t[ANIM_testsuite] __test_encode_to_file failed\n");
+ goto out;
+ }
+
+ /* test encoding agif animation to buffer */
+ if (FALSE == __test_encode_to_buffer(ANIM_CODEC_GIF, GIF_ENCODE_MEM_PATH)) {
+ fprintf(stderr, "\t[ANIM_testsuite] __test_encode_to_buffer failed\n");
+ goto out;
+ }
+
+out:
+ g_free(g_path);
+ g_queue_free_full(g_queue_images, mm_image_destroy_image);
+ g_queue_free_full(g_queue_files, g_free);
+
+ return 0;
+}
+
#define __MM_UTIL_PRIVATE_H__
#include <glib.h>
+#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include "mm_util_type.h"
#define IS_VALID_COLOR(color) mm_util_is_valid_color_format(color)
#define IS_VALID_IMAGE(image) mm_image_is_valid_image(image)
+typedef int (*ANIM_ENC_CREATE)(void *);
+typedef int (*ANIM_ENC_SET_BG_COLOR)(void *, unsigned char, unsigned char, unsigned char, unsigned char);
+typedef int (*ANIM_ENC_SET_LOOP_COUNT)(void *, unsigned int);
+typedef int (*ANIM_ENC_SET_LOSSLESS)(void *, bool);
+typedef int (*ANIM_ENC_ADD_IMAGE)(void *, mm_util_image_h);
+typedef int (*ANIM_ENC_SAVE_TO_FILE)(void *, const char *);
+typedef int (*ANIM_ENC_SAVE_TO_BUFFER)(void *, void **, size_t *);
+typedef void (*ANIM_ENC_DESTROY)(void *);
+
+typedef struct {
+ ANIM_ENC_CREATE create;
+ ANIM_ENC_SET_BG_COLOR set_bgcolor;
+ ANIM_ENC_SET_LOOP_COUNT set_loop_count;
+ ANIM_ENC_SET_LOSSLESS set_lossless;
+ ANIM_ENC_ADD_IMAGE add_image;
+ ANIM_ENC_SAVE_TO_FILE save_to_file;
+ ANIM_ENC_SAVE_TO_BUFFER save_to_buffer;
+ ANIM_ENC_DESTROY destroy;
+} anim_enc_module_t;
+
gboolean mm_util_is_valid_color_format(mm_util_color_format_e color);
int mm_util_safe_fopen(const char *path, const char *mode, FILE **fp);
MM_UTIL_ROTATE_NUM /**< Number of rotation types */
} mm_util_rotate_type_e;
+typedef enum {
+ IMG_CODEC_JPEG = 0,
+ IMG_CODEC_PNG,
+ IMG_CODEC_GIF,
+ IMG_CODEC_BMP,
+ IMG_CODEC_WEBP,
+ IMG_CODEC_WBMP = 100, // used by only media-content
+ IMG_CODEC_UNKNOWN_TYPE,
+} mm_util_img_codec_type;
+
+typedef enum {
+ ANIM_CODEC_GIF = 0,
+ ANIM_CODEC_WEBP,
+ ANIM_CODEC_UNKNOWN_TYPE,
+} mm_util_anim_codec_type;
+
typedef struct {
unsigned int width;
unsigned int height;
/* a-gif extras */
int mm_util_gif_encode_create(mm_gif_file_h *gif_file_h);
-int mm_util_gif_encode_set_file(mm_gif_file_h gif_file_h, const char *file_path);
-int mm_util_gif_encode_set_mem(mm_gif_file_h gif_file_h, void **buffer, size_t *buffer_size);
+int mm_util_gif_encode_set_loop_count(mm_gif_file_h gif_file_h, unsigned int loop_count);
int mm_util_gif_encode_add_image(mm_gif_file_h gif_file_h, mm_image_info_s * gif_image_h);
-int mm_util_gif_encode_save(mm_gif_file_h gif_file_h);
+int mm_util_gif_encode_save_to_file(mm_gif_file_h gif_file_h, const char *path);
+int mm_util_gif_encode_save_to_buffer(mm_gif_file_h gif_file_h, void **buffer, size_t *buffer_size);
void mm_util_gif_encode_destroy(mm_gif_file_h gif_file_h);
/* a-gif extras */
typedef struct {
GifFileType *GifFile; /**< GifFile opened */
char *filename;
+ unsigned int loop_count;
void **enc_buffer; /**< Encoded output data attached to callback */
size_t *enc_buffer_size;
gif_io_buf_s io_buf;
static int __gif_encode_close_file(GifFileType *gft)
{
- mm_util_fenter();
- mm_util_retvm_if(gft == NULL, MM_UTIL_ERROR_INVALID_PARAMETER, "Invalid parameter");
+ int gif_error = E_GIF_SUCCEEDED;
- if (EGifCloseFile(gft, NULL) == GIF_ERROR) {
- mm_util_error("could not close file");
+ mm_util_retvm_if(!gft, MM_UTIL_ERROR_INVALID_PARAMETER, "Invalid parameter");
+
+ if (EGifCloseFile(gft, &gif_error) == GIF_ERROR) {
+ mm_util_error("could not close file (%d) ", gif_error);
return MM_UTIL_ERROR_INVALID_OPERATION;
}
- gft = NULL;
return MM_UTIL_ERROR_NONE;
}
-static int __write_gif_to_file(gif_file_s *handle)
+static int __write_gif_to_file(gif_file_s *handle, const char *path)
{
int ret = MM_UTIL_ERROR_NONE;
FILE *fp = NULL;
mm_util_retvm_if(!handle, MM_UTIL_ERROR_INVALID_PARAMETER, "Invalid handle");
mm_util_retvm_if((!handle->io_buf.buf || handle->io_buf.buf_size == 0), MM_UTIL_ERROR_INVALID_PARAMETER, "Invalid io_buf");
- mm_util_retvm_if(!MMUTIL_STRING_VALID(handle->filename), MM_UTIL_ERROR_INVALID_PARAMETER, "Invalid filename");
+ mm_util_retvm_if(!MMUTIL_STRING_VALID(path), MM_UTIL_ERROR_INVALID_PARAMETER, "Invalid path");
- ret = mm_util_safe_fopen(handle->filename, "wb", &fp);
+ ret = mm_util_safe_fopen(path, "wb", &fp);
mm_util_retvm_if(ret != MM_UTIL_ERROR_NONE, ret, "mm_util_safe_fopen fail (%d)", ret);
ret = mm_util_safe_fwrite(fp, handle->io_buf.buf, handle->io_buf.buf_size);
return ret;
}
-static int __write_gif_to_buffer(gif_file_s *handle)
+static int __write_gif_to_buffer(gif_file_s *handle, void **buffer, size_t *buffer_size)
{
mm_util_retvm_if(!handle, MM_UTIL_ERROR_INVALID_PARAMETER, "Invalid handle");
mm_util_retvm_if(!handle->io_buf.buf || handle->io_buf.buf_size == 0, MM_UTIL_ERROR_INVALID_PARAMETER, "Invalid io_buf");
- mm_util_retvm_if(!handle->enc_buffer || !handle->enc_buffer_size, MM_UTIL_ERROR_INVALID_PARAMETER, "Invalid buffer");
+ mm_util_retvm_if(!buffer || !buffer_size, MM_UTIL_ERROR_INVALID_PARAMETER, "Invalid buffer");
- *handle->enc_buffer = g_memdup(handle->io_buf.buf, handle->io_buf.buf_size);;
- *handle->enc_buffer_size = handle->io_buf.buf_size;
+ *buffer = g_memdup(handle->io_buf.buf, handle->io_buf.buf_size);;
+ *buffer_size = handle->io_buf.buf_size;
return MM_UTIL_ERROR_NONE;
}
mm_util_retvm_if(byte_count == 0, MM_UTIL_ERROR_INVALID_PARAMETER, "Invalid parameter");
mm_util_retvm_if(ext_block == NULL, MM_UTIL_ERROR_INVALID_PARAMETER, "Invalid parameter");
- /* get allocated extention block */
+ /* get allocated extension block */
_ext_block = g_new0(ExtensionBlock, 1);
_ext_block->Function = function;
return MM_UTIL_ERROR_NONE;
}
+static void __gif_image_destroy_ext_block(ExtensionBlock *ext_block)
+{
+ if (!ext_block)
+ return;
+
+ g_free(ext_block->Bytes);
+ g_free(ext_block);
+}
+
static int __gif_image_write_ext_block(gif_file_s *gif_file, unsigned int delay_time)
{
int ret = MM_UTIL_ERROR_NONE;
}
/* release extension blocks */
- g_free(_ext_block->Bytes);
- g_free(_ext_block);
+ __gif_image_destroy_ext_block(_ext_block);
return MM_UTIL_ERROR_NONE;
}
-int mm_util_gif_encode_create(mm_gif_file_h *gif_file_h)
+static int __gif_image_write_loop_count(gif_file_s *gif_file, unsigned int loop_count)
{
- gif_file_s *gif_file = NULL;
+#define EXT_BLCOK_COUNT 2
+#define APP_EXT_BLOCK_DATA "NETSCAPE2.0"
+#define APP_EXT_BLOCK_SIZE strlen(APP_EXT_BLOCK_DATA)
+#define SUB_BLOCK_SIZE 3
+ int ret = MM_UTIL_ERROR_NONE;
+ ExtensionBlock *app_ext_block = NULL;
+ ExtensionBlock *app_sub_block = NULL;
- mm_util_retvm_if(!gif_file_h, MM_UTIL_ERROR_INVALID_PARAMETER, "Invalid handle");
+ ret = __gif_image_create_ext_block(APPLICATION_EXT_FUNC_CODE, APP_EXT_BLOCK_SIZE, &app_ext_block);
+ mm_util_retvm_if(ret != MM_UTIL_ERROR_NONE, ret, "__gif_image_create_ext_block failed");
- gif_file = g_new0(gif_file_s, 1);
+ memcpy(app_ext_block->Bytes, APP_EXT_BLOCK_DATA, APP_EXT_BLOCK_SIZE);
- *gif_file_h = (mm_gif_file_h)gif_file;
+ ret = __gif_image_create_ext_block(CONTINUE_EXT_FUNC_CODE, SUB_BLOCK_SIZE, &app_sub_block);
+ if (ret != MM_UTIL_ERROR_NONE) {
+ mm_util_error("__gif_image_create_ext_block failed");
+ goto END;
+ }
- return MM_UTIL_ERROR_NONE;
+ app_sub_block->Bytes[0] = 1; /* index of sub block for netscape */
+ app_sub_block->Bytes[1] = loop_count & 0xff;
+ app_sub_block->Bytes[2] = (loop_count >> 8) & 0xff;
+
+ if (EGifPutExtensionLeader(gif_file->GifFile, app_ext_block->Function) == GIF_ERROR) {
+ mm_util_error("EGifPutExtensionLeader failed");
+ ret = MM_UTIL_ERROR_INVALID_OPERATION;
+ goto END;
+ }
+
+ if (EGifPutExtensionBlock(gif_file->GifFile, app_ext_block->ByteCount, app_ext_block->Bytes) == GIF_ERROR) {
+ mm_util_error("EGifPutExtensionBlock(app_ext_block) failed");
+ ret = MM_UTIL_ERROR_INVALID_OPERATION;
+ goto END;
+ }
+
+ if (EGifPutExtensionBlock(gif_file->GifFile, app_sub_block->ByteCount, app_sub_block->Bytes) == GIF_ERROR) {
+ mm_util_error("EGifPutExtensionBlock(app_sub_block) failed");
+ ret = MM_UTIL_ERROR_INVALID_OPERATION;
+ goto END;
+ }
+
+ if (EGifPutExtensionTrailer(gif_file->GifFile) == GIF_ERROR) {
+ mm_util_error("EGifPutExtensionTrailer failed");
+ ret = MM_UTIL_ERROR_INVALID_OPERATION;
+ goto END;
+ }
+
+END:
+ __gif_image_destroy_ext_block(app_ext_block);
+ __gif_image_destroy_ext_block(app_sub_block);
+
+ return ret;
}
-int mm_util_gif_encode_set_file(mm_gif_file_h gif_file_h, const char *file_path)
+int mm_util_gif_encode_create(mm_gif_file_h *gif_file_h)
{
- gif_file_s *gif_file = (gif_file_s *)gif_file_h;
+ gif_file_s *gif_file = NULL;
- mm_util_retvm_if(!gif_file, MM_UTIL_ERROR_INVALID_PARAMETER, "Invalid handle");
- mm_util_retvm_if(!MMUTIL_STRING_VALID(file_path), MM_UTIL_ERROR_INVALID_PARAMETER, "Invalid file_path");
+ mm_util_retvm_if(!gif_file_h, MM_UTIL_ERROR_INVALID_PARAMETER, "Invalid gif_file_h");
- g_free(gif_file->filename);
- gif_file->filename = g_strdup(file_path);
+ gif_file = g_new0(gif_file_s, 1);
+
+ gif_file->loop_count = 1;
+
+ *gif_file_h = (mm_gif_file_h)gif_file;
return MM_UTIL_ERROR_NONE;
}
-int mm_util_gif_encode_set_mem(mm_gif_file_h gif_file_h, void **buffer, size_t *buffer_size)
+int mm_util_gif_encode_set_loop_count(mm_gif_file_h gif_file_h, unsigned int loop_count)
{
gif_file_s *gif_file = (gif_file_s *)gif_file_h;
- mm_util_retvm_if(!gif_file, MM_UTIL_ERROR_INVALID_PARAMETER, "Invalid handle");
- mm_util_retvm_if(!buffer, MM_UTIL_ERROR_INVALID_PARAMETER, "Invalid buffer");
- mm_util_retvm_if(!buffer_size, MM_UTIL_ERROR_INVALID_PARAMETER, "Invalid buffer_size");
+ mm_util_retvm_if(!gif_file, MM_UTIL_ERROR_INVALID_PARAMETER, "Invalid gif_file_h");
- gif_file->enc_buffer = buffer;
- gif_file->enc_buffer_size = buffer_size;
+ gif_file->loop_count = loop_count;
return MM_UTIL_ERROR_NONE;
}
int ret = MM_UTIL_ERROR_NONE;
gif_file_s *gif_file = (gif_file_s *)gif_file_h;
- mm_util_retvm_if(gif_file == NULL, MM_UTIL_ERROR_INVALID_PARAMETER, "Invalid parameter");
+ mm_util_retvm_if(gif_file == NULL, MM_UTIL_ERROR_INVALID_PARAMETER, "Invalid gif_file_h");
mm_util_retvm_if(gif_file->GifFile != NULL, MM_UTIL_ERROR_INVALID_OPERATION, "Encoding has already started");
mm_util_fenter();
return MM_UTIL_ERROR_INVALID_OPERATION;
}
+ /* Write extension block for loop count */
+ ret = __gif_image_write_loop_count(gif_file, gif_file->loop_count);
+ if (ret != MM_UTIL_ERROR_NONE) {
+ __gif_encode_close_file(gif_file->GifFile);
+ mm_util_error("__gif_image_write_loop_count failed");
+ }
+
mm_util_fleave();
- return MM_UTIL_ERROR_NONE;
+ return ret;
}
int mm_util_gif_encode_add_image(mm_gif_file_h gif_file_h, mm_image_info_s *gif_image_h)
mm_image_info_s *gif_image = (mm_image_info_s *)gif_image_h;
mm_util_fenter();
- mm_util_retvm_if(gif_file == NULL, MM_UTIL_ERROR_INVALID_PARAMETER, "Invalid parameter");
+ mm_util_retvm_if(gif_file == NULL, MM_UTIL_ERROR_INVALID_PARAMETER, "Invalid gif_file_h");
mm_util_retvm_if(gif_image == NULL, MM_UTIL_ERROR_INVALID_PARAMETER, "Invalid parameter");
mm_util_retvm_if((gif_image->width == 0) || (gif_image->height == 0), MM_UTIL_ERROR_INVALID_PARAMETER, "Invalid parameter");
mm_util_retvm_if(gif_image->data == NULL, MM_UTIL_ERROR_INVALID_PARAMETER, "Invalid parameter");
}
/* Write graphic control block */
- ret = __gif_image_write_ext_block(gif_file, gif_image->delay_time);
+ ret = __gif_image_write_ext_block(gif_file, gif_image->delay_time / 10);
mm_util_retvm_if(ret != MM_UTIL_ERROR_NONE, ret, "__gif_image_write_ext_block failed");
/* Write image description & data */
return MM_UTIL_ERROR_NONE;
}
-int mm_util_gif_encode_save(mm_gif_file_h gif_file_h)
+int mm_util_gif_encode_save_to_file(mm_gif_file_h gif_file_h, const char *path)
{
int ret = MM_UTIL_ERROR_NONE;
gif_file_s *gif_file = (gif_file_s *)gif_file_h;
- mm_util_retvm_if(gif_file == NULL, MM_UTIL_ERROR_INVALID_PARAMETER, "Invalid parameter");
- mm_util_retvm_if(gif_file->GifFile == NULL, MM_UTIL_ERROR_INVALID_OPERATION, "Encoding has not started");
+ mm_util_retvm_if(!gif_file_h, MM_UTIL_ERROR_INVALID_PARAMETER, "Invalid gif_file_h");
+ mm_util_retvm_if(!MMUTIL_STRING_VALID(path), MM_UTIL_ERROR_INVALID_PARAMETER, "Invalid path");
+ mm_util_retvm_if(!gif_file->GifFile, MM_UTIL_ERROR_INVALID_OPERATION, "Encoding has not started");
mm_util_retvm_if(gif_file->GifFile->ImageCount <= 0, MM_UTIL_ERROR_INVALID_OPERATION, "No frame has encoded");
mm_util_fenter();
ret = __gif_encode_close_file(gif_file->GifFile);
+ mm_util_retvm_if(ret != MM_UTIL_ERROR_NONE, ret, "__gif_encode_close_file failed");
gif_file->GifFile = NULL;
+
+ ret = __write_gif_to_file(gif_file, path);
+ mm_util_retvm_if(ret != MM_UTIL_ERROR_NONE, ret, "__write_gif_to_file failed (%d)", ret);
+
+ MMUTIL_SAFE_FREE(gif_file->io_buf.buf);
+ gif_file->io_buf.buf_size = 0;
+
+ return ret;
+}
+
+int mm_util_gif_encode_save_to_buffer(mm_gif_file_h gif_file_h, void **buffer, size_t *buffer_size)
+{
+ int ret = MM_UTIL_ERROR_NONE;
+ gif_file_s *gif_file = (gif_file_s *)gif_file_h;
+
+ mm_util_retvm_if(!gif_file_h, MM_UTIL_ERROR_INVALID_PARAMETER, "Invalid gif_file_h");
+ mm_util_retvm_if(!buffer || !buffer_size, MM_UTIL_ERROR_INVALID_PARAMETER, "Invalid buffer");
+ mm_util_retvm_if(!gif_file->GifFile, MM_UTIL_ERROR_INVALID_OPERATION, "Encoding has not started");
+ mm_util_retvm_if(gif_file->GifFile->ImageCount <= 0, MM_UTIL_ERROR_INVALID_OPERATION, "No frame has encoded");
+
+ mm_util_fenter();
+
+ ret = __gif_encode_close_file(gif_file->GifFile);
mm_util_retvm_if(ret != MM_UTIL_ERROR_NONE, ret, "__gif_encode_close_file failed");
+ gif_file->GifFile = NULL;
- if (gif_file->filename != NULL)
- ret = __write_gif_to_file(gif_file);
- else if (gif_file->enc_buffer != NULL)
- ret = __write_gif_to_buffer(gif_file);
+ ret = __write_gif_to_buffer(gif_file, buffer, buffer_size);
+ mm_util_retvm_if(ret != MM_UTIL_ERROR_NONE, ret, "__write_gif_to_buffer failed (%d)", ret);
MMUTIL_SAFE_FREE(gif_file->io_buf.buf);
gif_file->io_buf.buf_size = 0;
ret = mm_util_gif_encode_create(&gif_file_h);
mm_util_retvm_if(ret != MM_UTIL_ERROR_NONE, ret, "mm_util_gif_encode_create failed %d", ret);
- ret = mm_util_gif_encode_set_file(gif_file_h, file_path);
- if (ret != MM_UTIL_ERROR_NONE) {
- mm_util_error("mm_util_gif_encode_set_file failed");
- mm_util_gif_encode_destroy(gif_file_h);
- return ret;
- }
-
for (i = 0; i < image_count; i++) {
ret = mm_util_gif_encode_add_image(gif_file_h, _images[i]);
if (ret != MM_UTIL_ERROR_NONE) {
}
}
- ret = mm_util_gif_encode_save(gif_file_h);
+ ret = mm_util_gif_encode_save_to_file(gif_file_h, file_path);
if (ret != MM_UTIL_ERROR_NONE)
- mm_util_error("mm_util_gif_encode_save failed");
+ mm_util_error("mm_util_gif_encode_save_to_file failed (%d)", ret);
mm_util_gif_encode_destroy(gif_file_h);
ret = mm_util_gif_encode_create(&gif_file_h);
mm_util_retvm_if(ret != MM_UTIL_ERROR_NONE, ret, "mm_util_gif_encode_create failed %d", ret);
- ret = mm_util_gif_encode_set_mem(gif_file_h, buffer, size);
- if (ret != MM_UTIL_ERROR_NONE) {
- mm_util_error("mm_util_gif_encode_set_mem failed");
- mm_util_gif_encode_destroy(gif_file_h);
- return ret;
- }
-
for (i = 0; i < image_count; i++) {
ret = mm_util_gif_encode_add_image(gif_file_h, _images[i]);
if (ret != MM_UTIL_ERROR_NONE) {
}
}
- ret = mm_util_gif_encode_save(gif_file_h);
+ ret = mm_util_gif_encode_save_to_buffer(gif_file_h, buffer, size);
if (ret != MM_UTIL_ERROR_NONE)
- mm_util_error("mm_util_gif_encode_save failed");
+ mm_util_error("mm_util_gif_encode_save_to_buffer failed (%d)", ret);
mm_util_gif_encode_destroy(gif_file_h);
mm_util_retm_if(gif_file == NULL, "Invalid parameter");
- if (gif_file->GifFile != NULL) {
+ if (gif_file->GifFile) {
ret = __gif_encode_close_file(gif_file->GifFile);
mm_util_retm_if(ret != MM_UTIL_ERROR_NONE, "__gif_encode_close_file failed");
}
MMUTIL_SAFE_FREE(gif_file->io_buf.buf);
g_free(gif_file);
}
+
+anim_enc_module_t *anim_enc_module_register(void)
+{
+ anim_enc_module_t *module = NULL;
+
+ mm_util_fenter();
+
+ module = g_new0(anim_enc_module_t, 1);
+
+ module->create = (ANIM_ENC_CREATE)mm_util_gif_encode_create;
+ module->set_bgcolor = NULL;
+ module->set_loop_count = (ANIM_ENC_SET_LOOP_COUNT)mm_util_gif_encode_set_loop_count;
+ module->set_lossless = NULL;
+ module->add_image = (ANIM_ENC_ADD_IMAGE)mm_util_gif_encode_add_image;
+ module->save_to_file = (ANIM_ENC_SAVE_TO_FILE)mm_util_gif_encode_save_to_file;
+ module->save_to_buffer = (ANIM_ENC_SAVE_TO_BUFFER)mm_util_gif_encode_save_to_buffer;
+ module->destroy = (ANIM_ENC_DESTROY)mm_util_gif_encode_destroy;
+
+ mm_util_fleave();
+
+ return module;
+}
typedef void *mm_util_enc_opt_h;
-typedef enum {
- IMG_CODEC_JPEG = 0,
- IMG_CODEC_PNG,
- IMG_CODEC_GIF,
- IMG_CODEC_BMP,
- IMG_CODEC_WEBP,
- IMG_CODEC_WBMP = 100, // used by only media-content
- IMG_CODEC_UNKNOWN_TYPE,
-} mm_util_img_codec_type;
-
int mm_util_rotate_B_B(mm_util_image_h src_handle, mm_util_rotate_type_e rotation, mm_util_image_h *dst_handle);
int mm_util_rotate_B_P(mm_util_image_h src_handle, mm_util_rotate_type_e rotation, const char *dst_path);
int mm_util_rotate_P_B(const char *src_path, mm_util_rotate_type_e rotation, mm_util_color_format_e req_format, mm_util_image_h *dst_handle);
%defattr(-,root,root,-)
%{_libdir}/*.so.*
%{_libdir}/libmmutil_imgcv.so
+%{_libdir}/libmmutil_gif.so
+%{_libdir}/libmmutil_webp.so
%if 0%{?gtests:1}
%{_bindir}/gtest*
%{_bindir}/libmm*unittest*
anim_enc = g_new0(mm_util_webp_anim_enc_t, 1);
anim_enc->anim_params.bgcolor = 0xFFFFFFFF; // white
anim_enc->anim_params.loop_count = 0; // infinite
- anim_enc->lossless = false;
+ anim_enc->lossless = false; // lossy
*anim_enc_h = anim_enc;
__webp_anim_enc_deinit((mm_util_webp_anim_enc_t *)anim_enc_h);
g_free(anim_enc_h);
}
+
+anim_enc_module_t *anim_enc_module_register(void)
+{
+ anim_enc_module_t *module = NULL;
+
+ mm_util_fenter();
+
+ module = g_new0(anim_enc_module_t, 1);
+
+ module->create = (ANIM_ENC_CREATE)mm_util_webp_anim_enc_create;
+ module->set_bgcolor = (ANIM_ENC_SET_BG_COLOR)mm_util_webp_anim_enc_set_bgcolor;
+ module->set_loop_count = (ANIM_ENC_SET_LOOP_COUNT)mm_util_webp_anim_enc_set_loop_count;
+ module->set_lossless = (ANIM_ENC_SET_LOSSLESS)mm_util_webp_anim_enc_set_lossless;
+ module->add_image = (ANIM_ENC_ADD_IMAGE)mm_util_webp_anim_enc_add_image;
+ module->save_to_file = (ANIM_ENC_SAVE_TO_FILE)mm_util_webp_anim_enc_save_to_file;
+ module->save_to_buffer = (ANIM_ENC_SAVE_TO_BUFFER)mm_util_webp_anim_enc_save_to_buffer;
+ module->destroy = (ANIM_ENC_DESTROY)mm_util_webp_anim_enc_destroy;
+
+ mm_util_fleave();
+
+ return module;
+}