ADD_SUBDIRECTORY(magick)
ADD_SUBDIRECTORY(webp)
ADD_SUBDIRECTORY(anim)
+ADD_SUBDIRECTORY(heif)
IF(UNIX)
--- /dev/null
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+SET(fw_name "mmutil_heif")
+
+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
+ ../jpeg/include
+)
+
+SET(dependents "dlog glib-2.0 heif")
+
+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 heif)
+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-heif)
+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) 2021 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_HEIF_H__
+#define __MM_UTIL_HEIF_H__
+
+#include "mm_util_type.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+int mm_util_decode_heif_from_file(const char *path, mm_util_color_format_e format, mm_util_image_h *decoded_image);
+int mm_util_decode_heif_from_buffer(const void *buf, size_t buf_size, mm_util_color_format_e format, mm_util_image_h *decoded_image);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*__MM_UTIL_HEIF_H__*/
--- /dev/null
+/*
+* Copyright (c) 2021 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 <glib.h>
+#include <heif.h>
+
+#include "mm_util_heif.h"
+#include "mm_util_private.h"
+#include "mm_util_image.h"
+
+
+static int __mm_util_error(int error_code)
+{
+ switch (error_code) {
+ case LIBHEIF_ERROR_NONE:
+ return MM_UTIL_ERROR_NONE;
+
+ case LIBHEIF_ERROR_INVALID_PARAMETER:
+ return MM_UTIL_ERROR_INVALID_PARAMETER;
+
+ case LIBHEIF_ERROR_NOT_SUPPORTED:
+ return MM_UTIL_ERROR_NOT_SUPPORTED_FORMAT;
+
+ case LIBHEIF_ERROR_PERMISSION_DENIED:
+ // fall through
+ case LIBHEIF_ERROR_INVALID_OPERATION:
+ // fall through
+ default:
+ return MM_UTIL_ERROR_INVALID_OPERATION;
+ }
+
+}
+
+static heif_color_format_e __get_heif_color_format(mm_util_color_format_e color_format)
+{
+ switch(color_format) {
+ case MM_UTIL_COLOR_YUV420:
+ return HEIF_COLOR_FORMAT_YUV420P;
+ case MM_UTIL_COLOR_RGB24:
+ return HEIF_COLOR_FORMAT_RGB24;
+ case MM_UTIL_COLOR_ARGB:
+ return HEIF_COLOR_FORMAT_ARGB;
+ case MM_UTIL_COLOR_BGRA:
+ return HEIF_COLOR_FORMAT_BGRA;
+ case MM_UTIL_COLOR_RGBA:
+ return HEIF_COLOR_FORMAT_RGBA;
+ default:
+ return HEIF_COLOR_FORMAT_NONE;
+ }
+}
+
+static mm_util_color_format_e __get_mm_color_format(heif_color_format_e color_format)
+{
+ switch(color_format) {
+ case HEIF_COLOR_FORMAT_YUV420P:
+ return MM_UTIL_COLOR_YUV420;
+ case HEIF_COLOR_FORMAT_RGB24:
+ return MM_UTIL_COLOR_RGB24;
+ case HEIF_COLOR_FORMAT_ARGB:
+ return MM_UTIL_COLOR_ARGB;
+ case HEIF_COLOR_FORMAT_BGRA:
+ return MM_UTIL_COLOR_BGRA;
+ case HEIF_COLOR_FORMAT_RGBA:
+ return MM_UTIL_COLOR_RGBA;
+ default:
+ return MM_UTIL_COLOR_NUM;
+ }
+}
+
+static mm_util_image_h __get_mm_image(heif_image_h image)
+{
+ int ret = LIBHEIF_ERROR_NONE;
+ mm_util_image_h mm_image = NULL;
+ unsigned int width = 0, height = 0;
+ heif_color_format_e color = HEIF_COLOR_FORMAT_NONE;
+ unsigned char *data = NULL;
+ size_t size = 0;
+
+ ret = heif_image_get_image(image, &width, &height, &color, &data, &size);
+ mm_util_retvm_if(ret != LIBHEIF_ERROR_NONE, NULL, "heif_decode_image_from_file is failed (%d)", ret);
+
+ ret = mm_image_create_image(width, height, __get_mm_color_format(color), (void *)data, size, &mm_image);
+ mm_util_retvm_if(ret != LIBHEIF_ERROR_NONE, NULL, "mm_image_create_image is failed (%d)", ret);
+
+ return mm_image;
+}
+
+int mm_util_decode_heif_from_file(const char *path, mm_util_color_format_e format, mm_util_image_h *decoded_image)
+{
+ int ret = LIBHEIF_ERROR_NONE;
+ heif_image_h image = NULL;
+
+ mm_util_retvm_if(!decoded_image, MM_UTIL_ERROR_INVALID_PARAMETER, "invalid decoded_image");
+
+ ret = heif_decode_image_from_file(path, __get_heif_color_format(format), &image);
+ mm_util_retvm_if(ret != LIBHEIF_ERROR_NONE, __mm_util_error(ret), "heif_decode_image_from_file is failed (%d)", ret);
+
+ *decoded_image = __get_mm_image(image);
+
+ heif_image_free(image);
+
+ return MM_UTIL_ERROR_NONE;
+}
+
+int mm_util_decode_heif_from_buffer(const void *buf, size_t buf_size, mm_util_color_format_e format, mm_util_image_h *decoded_image)
+{
+ int ret = LIBHEIF_ERROR_NONE;
+ heif_image_h image = NULL;
+
+ mm_util_retvm_if(!decoded_image, MM_UTIL_ERROR_INVALID_PARAMETER, "invalid decoded_image");
+
+ ret = heif_decode_image_from_buffer((unsigned char *)buf, buf_size, __get_heif_color_format(format), &image);
+ mm_util_retvm_if(ret != LIBHEIF_ERROR_NONE, __mm_util_error(ret), "heif_decode_image_from_buffer is failed (%d)", ret);
+
+ *decoded_image = __get_mm_image(image);
+
+ heif_image_free(image);
+
+ return MM_UTIL_ERROR_NONE;
+}
--- /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_heif")
+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 -Werror")
+
+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_jpeg)
+ENDFOREACH()
--- /dev/null
+/*
+* Copyright (c) 2021 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 <glib.h>
+
+#include <mm_util_heif.h>
+#include <mm_util_image.h>
+#include <mm_util_jpeg.h>
+
+#define SAFE_FREE(x) { g_free(x); x = NULL; }
+#define SAFE_IMAGE_FREE(x) { if (x != NULL) { mm_image_destroy_image(x); x = NULL; } }
+
+typedef enum {
+ TEST_AUTO,
+ TEST_DECODE_FILE,
+ TEST_DECODE_BUFFER,
+ TEST_NUM,
+} heif_test_mode_e;
+
+static char *MODE_TO_STR[] = {
+ "AUTO",
+ "DECODE_FILE",
+ "DECODE_BUFFER",
+ "",
+};
+
+/* for arguments */
+static int g_test_mode = 0;
+static char *g_path = NULL;
+static int g_color = MM_UTIL_COLOR_RGB24;
+
+/* for reading file */
+static gchar *g_readed_data = NULL;
+static gsize g_readed_size = 0;
+
+/* for saving result */
+static const char *g_test_filename[TEST_NUM][MM_UTIL_COLOR_NUM] = {
+ [TEST_AUTO] = {
+ NULL,
+ },
+ [TEST_DECODE_FILE] = {
+ [MM_UTIL_COLOR_YUV420] = "/opt/usr/home/owner/media/test_heif_file_yuv420p.jpg",
+ [MM_UTIL_COLOR_YUV422] = NULL,
+ [MM_UTIL_COLOR_I420] = NULL,
+ [MM_UTIL_COLOR_NV12] = NULL,
+ [MM_UTIL_COLOR_UYVY] = NULL,
+ [MM_UTIL_COLOR_YUYV] = NULL,
+ [MM_UTIL_COLOR_RGB16] = NULL,
+ [MM_UTIL_COLOR_RGB24] = "/opt/usr/home/owner/media/test_heif_file_rgb24.jpg",
+ [MM_UTIL_COLOR_ARGB] = "/opt/usr/home/owner/media/test_heif_file_argb.jpg",
+ [MM_UTIL_COLOR_BGRA] = "/opt/usr/home/owner/media/test_heif_file_bgra.jpg",
+ [MM_UTIL_COLOR_RGBA] = "/opt/usr/home/owner/media/test_heif_file_rgba.jpg",
+ [MM_UTIL_COLOR_BGRX] = NULL,
+ [MM_UTIL_COLOR_NV12_TILED] = NULL,
+ [MM_UTIL_COLOR_NV16] = NULL,
+ [MM_UTIL_COLOR_NV61] = NULL,
+ [MM_UTIL_COLOR_NV21] = NULL,
+ [MM_UTIL_COLOR_GRAYSCALE] = NULL,
+ },
+ [TEST_DECODE_BUFFER] = {
+ [MM_UTIL_COLOR_YUV420] = "/opt/usr/home/owner/media/test_heif_buff_yuv420p.jpg",
+ [MM_UTIL_COLOR_YUV422] = NULL,
+ [MM_UTIL_COLOR_I420] = NULL,
+ [MM_UTIL_COLOR_NV12] = NULL,
+ [MM_UTIL_COLOR_UYVY] = NULL,
+ [MM_UTIL_COLOR_YUYV] = NULL,
+ [MM_UTIL_COLOR_RGB16] = NULL,
+ [MM_UTIL_COLOR_RGB24] = "/opt/usr/home/owner/media/test_heif_buff_rgb24.jpg",
+ [MM_UTIL_COLOR_ARGB] = "/opt/usr/home/owner/media/test_heif_buff_argb.jpg",
+ [MM_UTIL_COLOR_BGRA] = "/opt/usr/home/owner/media/test_heif_buff_bgra.jpg",
+ [MM_UTIL_COLOR_RGBA] = "/opt/usr/home/owner/media/test_heif_buff_rgba.jpg",
+ [MM_UTIL_COLOR_BGRX] = NULL,
+ [MM_UTIL_COLOR_NV12_TILED] = NULL,
+ [MM_UTIL_COLOR_NV16] = NULL,
+ [MM_UTIL_COLOR_NV61] = NULL,
+ [MM_UTIL_COLOR_NV21] = NULL,
+ [MM_UTIL_COLOR_GRAYSCALE] = NULL,
+ },
+};
+
+static mm_util_image_h g_decoded_data = NULL;
+
+static gboolean __get_input_data(const char *argv, const long min, const long max, int *data)
+{
+ if (!argv || strlen(argv) == 0)
+ return FALSE;
+
+ if (!data)
+ return FALSE;
+
+ long temp = g_ascii_strtoll(argv, NULL, 10);
+ if (temp < min || temp > max)
+ return FALSE;
+
+ *data = (int)temp;
+
+ return TRUE;
+}
+
+static void __print_help(const char *argv0)
+{
+ g_print("\t[usage]\n");
+ g_print("\t\t1. decode : %s mode path color_format(opt.)\n", argv0);
+ g_print("\t\t2. mode : 0 - auto, 1 - decode from file, 2 - decode from memory\n");
+ g_print("\t\t\t e.g. %s 0 test.heif\n", argv0);
+ g_print("\t\t\t e.g. %s 1 test.heif 7\n", argv0);
+}
+
+static gboolean __get_arguments(int argc, char *argv[])
+{
+ if (!__get_input_data(argv[1], TEST_AUTO, TEST_NUM - 1, &g_test_mode)) {
+ g_print("\t[HEIF_testsuite] wrong mode(%s) for test\n", argv[1]);
+ __print_help(argv[0]);
+ return FALSE;
+ }
+
+ g_path = g_strdup(argv[2]);
+
+ if (g_test_mode == TEST_AUTO) {
+ // do nothing
+ } else if (g_test_mode == TEST_DECODE_FILE) {
+ if (!__get_input_data(argv[3], MM_UTIL_COLOR_YUV420, MM_UTIL_COLOR_NUM - 1, &g_color))
+ g_print("\t[HEIF_testsuite] color is default(%d)\n", g_color);
+ } else if (g_test_mode == TEST_DECODE_BUFFER) {
+ if (!__get_input_data(argv[3], MM_UTIL_COLOR_YUV420, MM_UTIL_COLOR_NUM - 1, &g_color))
+ g_print("\t[HEIF_testsuite] color is default(%d)\n", g_color);
+ } else {
+ g_print("\t[HEIF_testsuite] wrong mode for test %s\n", argv[1]);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static gboolean __test_decode(const heif_test_mode_e mode, mm_util_color_format_e color, const char *path)
+{
+ int ret = 0;
+ GError *error = NULL;
+
+ if (!path) {
+ g_print("\t[HEIF_testsuite] No-Error\n");
+ return TRUE;
+ }
+
+ /* test decoding heif */
+ if (mode == TEST_DECODE_FILE) {
+ ret = mm_util_decode_heif_from_file(g_path, color, &g_decoded_data);
+ if (ret != MM_UTIL_ERROR_NONE) {
+ g_print("\t[HEIF_testsuite] mm_util_decode_heif_from_file failed %d\n", ret);
+ return FALSE;
+ }
+ } else if (mode == TEST_DECODE_BUFFER) {
+ if (!g_file_get_contents(g_path, &g_readed_data, &g_readed_size, &error)) {
+ g_print("\t[HEIF_testsuite] reading file error(%s)\n", (error ? error->message : "none"));
+ if (error)
+ g_error_free(error);
+ return FALSE;
+ }
+
+ ret = mm_util_decode_heif_from_buffer(g_readed_data, g_readed_size, color, &g_decoded_data);
+ if (ret != MM_UTIL_ERROR_NONE) {
+ g_print("\t[HEIF_testsuite] mm_util_decode_heif_from_buffer failed %d\n", ret);
+ return FALSE;
+ }
+ }
+
+ ret = mm_util_jpeg_encode_to_file(g_decoded_data, 100, path);
+ if (ret != MM_UTIL_ERROR_NONE) {
+ g_print("\t[HEIF_testsuite] mm_util_jpeg_encode_to_file failed %d : %s\n", ret, path);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static gboolean __test_auto()
+{
+ heif_test_mode_e test_mode = TEST_DECODE_FILE;
+ mm_util_color_format_e color = MM_UTIL_COLOR_YUV420;
+ gboolean result = FALSE;
+
+ while (test_mode < TEST_NUM) {
+ g_print("\t[HEIF_testsuite] >>>>>>>>>>>>>>>>>>>>>> \'%s\' TEST START\n", MODE_TO_STR[test_mode]);
+ /* test decoding heif */
+ if ((test_mode == TEST_DECODE_FILE) || (test_mode == TEST_DECODE_BUFFER)) {
+ for (color = MM_UTIL_COLOR_YUV420; color < MM_UTIL_COLOR_NUM; color++) {
+ result |= __test_decode(test_mode, color, g_test_filename[test_mode][color]);
+ SAFE_FREE(g_readed_data);
+ SAFE_IMAGE_FREE(g_decoded_data);
+ }
+ }
+
+ g_print("\t[HEIF_testsuite] >>>>>>>>>>>>>>>>>>>>>> \'%s\' TEST %s\n",
+ MODE_TO_STR[test_mode], (result) ? "SUCCESS" : "FAIL");
+ test_mode++;
+ }
+
+ return TRUE;
+}
+
+int main(int argc, char *argv[])
+{
+ if (argc < 2) {
+ __print_help(argv[0]);
+ return 0;
+ }
+
+ if (!__get_arguments(argc, argv)) {
+ g_print("\t[HEIF_testsuite] _get_arguments failed\n");
+ goto out;
+ }
+
+ /* test all functions automatically */
+ if (g_test_mode == TEST_AUTO) {
+ if (!__test_auto())
+ g_print("\t[HEIF_testsuite] _test_auto failed\n");
+ goto out;
+ }
+
+ /* test decoding heif */
+ if ((g_test_mode == TEST_DECODE_FILE) || (g_test_mode == TEST_DECODE_BUFFER)) {
+ if (!__test_decode(g_test_mode, g_color, g_test_filename[g_test_mode][g_color]))
+ g_print("\t[HEIF_testsuite] _test_decode(%s) failed\n", MODE_TO_STR[g_test_mode]);
+ }
+
+out:
+ g_free(g_path);
+ SAFE_FREE(g_readed_data);
+ SAFE_IMAGE_FREE(g_decoded_data);
+
+ return 0;
+}
Name: libmm-utility
Summary: Multimedia Framework Utility Library
-Version: 0.2.5
+Version: 0.3.0
Release: 0
Group: System/Libraries
License: Apache-2.0
BuildRequires: pkgconfig(libwebpmux)
BuildRequires: giflib-devel
BuildRequires: pkgconfig(GraphicsMagick)
+BuildRequires: pkgconfig(heif)
%if 0%{?gtests:1}
BuildRequires: pkgconfig(gmock)
%endif