/* commons for testsuite */
#define MAX_STRING_LEN PATH_MAX
-#define MAX_AGIF_CNT 100 /* supports MAX_AGIF_CNT agif frames */
+#define MAX_AGIF_CNT 100 /* supports MAX_AGIF_CNT agif and animation frames */
#define IMAGE_UTIL_COLOR_NUM IMAGE_UTIL_COLORSPACE_NV61 + 1
#define SAFE_FREE(src) { g_free(src); src = NULL; }
#define FILE_FOR_AUTO tzplatform_mkpath(TZ_USER_CONTENT, "imgutil_test_auto")
#define FILE_FOR_ENCODE tzplatform_mkpath(TZ_USER_CONTENT, "imgutil_test_encode")
#define FILE_FOR_ENCODE_AGIF tzplatform_mkpath(TZ_USER_CONTENT, "imgutil_test_encode_agif")
+#define FILE_FOR_ENCODE_ANIM tzplatform_mkpath(TZ_USER_CONTENT, "imgutil_test_encode_anim")
#define IMAGE_UTIL_TYPE_MAX IMAGE_UTIL_WEBP
DECODE_MENU,
ENCODE_MENU,
ENCODE_AGIF_MENU,
+ ENCODE_ANIM_MENU,
TRANSFORM_MENU,
/* set menu */
SET_CONVERT_MENU,
SET_CROP_MENU,
SET_DELAY_MENU,
+ SET_BG_COLOR_MENU,
SET_DIR_MENU,
SET_DOWNSCALE_MENU,
SET_QUALITY_MENU,
SET_ROTATE_MENU,
SET_SIZE_MENU,
SET_TYPE_MENU,
+ SET_ANIM_TYPE_MENU,
SET_LAST_MENU,
} test_menu_state_e;
} test_size_s;
typedef struct {
+ unsigned char r;
+ unsigned char g;
+ unsigned char b;
+ unsigned char a;
+} test_color_s;
+
+typedef struct {
/* for input path or dir */
char *path;
gboolean use_buffer;
} test_encode_agif_params_s;
+/* for encode animation parameters */
+typedef struct {
+ image_util_anim_type_e type;
+ int delay;
+ unsigned int loop_count;
+ bool lossless;
+ test_color_s bg_color; // rgba
+ gboolean use_buffer;
+} test_encode_anim_params_s;
+
/* for transform parameters */
typedef struct {
gboolean has_convert_color;
/* encode a-gif */
static test_encode_agif_params_s g_encode_agif_params;
static test_complex_data_s g_encode_agif_result;
+/* encode anim */
+static test_encode_anim_params_s g_encode_anim_params;
+static test_complex_data_s g_encode_anim_result;
/* transform */
static test_transform_params_s g_transform_params;
static test_complex_data_s g_transform_result;
/* for menu queue */
static GQueue *g_queue_menu = NULL;
-/* for images queue to encode a-gif */
-static GQueue *g_queue_agif_images = NULL;
+/* for images queue to encode a-gif and animation */
+static GQueue *g_queue_anim_images = NULL;
/* for input data queue */
static GQueue *g_queue_data = NULL;
}
typedef enum {
+ ENCODE_ANIM_SET_DIR = 0,
+ ENCODE_ANIM_SET_TYPE,
+ ENCODE_ANIM_SET_DELAY,
+ ENCODE_ANIM_SET_BG_COLOR,
+ ENCODE_ANIM_SET_LOSSLESS,
+ ENCODE_ANIM_SAVE_TO_FILE,
+ ENCODE_ANIM_SAVE_TO_BUFFER,
+ ENCODE_ANIM_MENU_MAX,
+} test_encode_anim_menu_e;
+
+typedef struct {
+ test_encode_anim_menu_e e;
+ const char *t;
+} test_encode_anim_menu_s;
+
+static const test_encode_anim_menu_s g_disp_encode_anim_menu[ENCODE_ANIM_MENU_MAX] = {
+ { ENCODE_ANIM_SET_DIR, "set directory" },
+ { ENCODE_ANIM_SET_TYPE, "set animation type (mand. default = webp)" },
+ { ENCODE_ANIM_SET_DELAY, "set delay time (mand. default = 100)" },
+ { ENCODE_ANIM_SET_BG_COLOR, "set background color (opt.)" },
+ { ENCODE_ANIM_SET_LOSSLESS, "set lossless (opt. default = 0(false=lossy))" },
+ { ENCODE_ANIM_SAVE_TO_FILE, "add frame by frame and save to file" },
+ { ENCODE_ANIM_SAVE_TO_BUFFER, "add frame by frame and save to buffer" },
+};
+
+static void __display_encode_anim_menu(void)
+{
+ unsigned int idx = 0;
+ g_print("\n");
+ g_print("====================================================\n");
+ g_print(" image-util Core-API test: Encode ANIMATION menu v%s\n", VERSION);
+ g_print("----------------------------------------------------\n");
+ for (idx = 0; idx < ENCODE_ANIM_MENU_MAX; idx++)
+ g_print("%u. %s\n", g_disp_encode_anim_menu[idx].e, g_disp_encode_anim_menu[idx].t);
+ g_print("b. back\n");
+ g_print("q. quit\n");
+ g_print("----------------------------------------------------\n");
+ g_print("====================================================\n");
+}
+
+typedef enum {
TRANSFORM_SET_CONVERT = 0,
TRANSFORM_SET_CROP,
TRANSFORM_SET_RESIZE,
TEST_DECODE,
TEST_ENCODE,
TEST_ENCODE_AGIF,
+ TEST_ENCODE_ANIM,
TEST_TRANSFORM,
SET_PATH,
MAIN_MENU_MAX,
{ TEST_DECODE, "test decode" },
{ TEST_ENCODE, "test encode" },
{ TEST_ENCODE_AGIF, "test encode a-gif" },
+ { TEST_ENCODE_ANIM, "test encode animation" },
{ TEST_TRANSFORM, "test transform" },
{ SET_PATH, "set path" },
};
case ENCODE_AGIF_MENU:
__display_encode_agif_menu();
break;
+ case ENCODE_ANIM_MENU:
+ __display_encode_anim_menu();
+ break;
case TRANSFORM_MENU:
__display_transform_menu();
break;
case SET_DELAY_MENU:
__display_set("delay", "20~");
break;
+ case SET_BG_COLOR_MENU:
+ __display_set("background color", "(r),(g),(b),(a) 255,0,0,0");
+ break;
case SET_DOWNSCALE_MENU:
__display_set("downscale", "0(1/1), 1(1/2), 2(1/4), 3(1/8)");
break;
case SET_TYPE_MENU:
__display_set("image_type", "0:jpeg, 1:png, 2:gif, 3:bmp, 4:webp");
break;
+ case SET_ANIM_TYPE_MENU:
+ __display_set("image_anim_type", "0:gif, 1:webp");
+ break;
/* set menus */
case MAIN_MENU:
return FALSE;
}
- g_queue_foreach(g_queue_agif_images, __decode_func, decoder);
+ g_queue_foreach(g_queue_anim_images, __decode_func, decoder);
if (g_input_data.image_cnt == 0) {
g_print("No valid image\n");
return FALSE;
}
- if (g_queue_agif_images)
- g_queue_free_full(g_queue_agif_images, g_free);
+ if (g_queue_anim_images)
+ g_queue_free_full(g_queue_anim_images, g_free);
- g_queue_agif_images = g_queue_new();
+ g_queue_anim_images = g_queue_new();
/* push files of dir into queue */
while (1) {
if (!filename)
break;
- g_queue_insert_sorted(g_queue_agif_images, g_strdup_printf("%s/%s", path, filename), __sort_compare, NULL);
+ g_queue_insert_sorted(g_queue_anim_images, g_strdup_printf("%s/%s", path, filename), __sort_compare, NULL);
}
g_dir_close(dir);
- if (g_queue_agif_images->length == 0) {
+ if (g_queue_anim_images->length == 0) {
g_print("No test file in directory(%s)!\n", path);
return FALSE;
}
return ret;
}
+static gboolean __set_input_color(const char *data, test_color_s *color)
+{
+ gchar **params = NULL;
+ gboolean ret = FALSE;
+ unsigned int color_level = 0;
+
+ if (data == NULL || strlen(data) == 0)
+ return FALSE;
+
+ params = g_strsplit(data, ",", 0);
+
+ if (params == NULL || params[0] == NULL || params[1] == NULL || params[2] == NULL || params[3] == NULL)
+ return FALSE;
+
+ if (!__safe_atoui(params[0], &color_level) || color_level > 255) {
+ g_print("wrong red! %s\n", params[0]);
+ goto ERROR;
+ }
+ color->r = (unsigned char)color_level;
+ if (!__safe_atoui(params[1], &color_level) || color_level > 255) {
+ g_print("wrong green! %s\n", params[1]);
+ goto ERROR;
+ }
+ color->g = (unsigned char)color_level;
+ if (!__safe_atoui(params[2], &color_level) || color_level > 255) {
+ g_print("wrong blue! %s\n", params[0]);
+ goto ERROR;
+ }
+ color->b = (unsigned char)color_level;
+ if (!__safe_atoui(params[3], &color_level) || color_level > 255) {
+ g_print("wrong alpha! %s\n", params[1]);
+ goto ERROR;
+ }
+ color->a = (unsigned char)color_level;
+
+ ret = TRUE;
+
+ERROR:
+ g_strfreev(params);
+
+ return ret;
+}
+
static int __get_raw_data(test_complex_data_s *test_data)
{
int ret = IMAGE_UTIL_ERROR_NONE;
g_print("\t__get_encode_path: %s!\n", *path);
}
+
+static const char *g_anim_image_exts[] = {
+ "gif",
+ "webp",
+};
+static void __get_encode_anim_path(image_util_anim_type_e anim_type, const char *base, char **path)
+{
+ char *_path = NULL;
+
+ switch (anim_type) {
+ case IMAGE_UTIL_ANIM_GIF:
+ /* fall through */
+ case IMAGE_UTIL_ANIM_WEBP:
+ // do noting...
+ break;
+ default:
+ g_print("Not supported encode animation format!\n");
+ return;
+ }
+
+ _path = g_strdup_printf("%s.%s", base, g_anim_image_exts[anim_type]);
+
+ g_free(*path);
+ *path = _path;
+
+ g_print("\t__get_encode_path: %s!\n", *path);
+}
/* internal functions for testsuite */
return ret;
}
+/* encode animated WEBP or GIF frame by frame
+ * input : use image_cnt & images
+ * output : use path or buffer(buffer_size)
+ */
+static int __run_encode_anim(test_encode_menu_e menu, test_complex_data_s *input,
+ test_encode_anim_params_s *params, test_complex_data_s *result)
+{
+ int ret = IMAGE_UTIL_ERROR_NONE;
+ image_util_agif_encode_h handle = NULL;
+ unsigned int i = 0;
+
+ if (!input || !params || !result) {
+ g_print("invalid parameter!!! input: %p, params: %p, result: %p\n", input, params, result);
+ return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
+ }
+
+ ret = image_util_anim_encode_create(params->type, &handle);
+ if (ret != IMAGE_UTIL_ERROR_NONE) {
+ g_print("image_util_anim_encode_create failed %d\n", ret);
+ return ret;
+ }
+
+ ret = image_util_anim_encode_set_lossless(handle, params->lossless);
+ if (ret != IMAGE_UTIL_ERROR_NONE) {
+ g_print("image_util_anim_encode_set_lossless failed %d\n", ret);
+ return ret;
+ }
+
+ ret = image_util_anim_encode_set_background_color(handle, params->bg_color.r, params->bg_color.g,
+ params->bg_color.b, params->bg_color.a);
+ if (ret != IMAGE_UTIL_ERROR_NONE) {
+ g_print("image_util_anim_encode_set_background_color failed %d\n", ret);
+ return ret;
+ }
+
+ for (i = 0; i < input->image_cnt; i++) {
+ ret = image_util_anim_encode_add_frame(handle, input->images[i], params->delay);
+ if (ret != IMAGE_UTIL_ERROR_NONE) {
+ g_print("image_util_anim_encode_add_frame failed %d\n", ret);
+ goto ERROR;
+ }
+ }
+
+ switch(menu) {
+ case ENCODE_AGIF_SAVE_TO_FILE:
+ ret = image_util_anim_encode_save_to_file(handle, result->path);
+ if (ret != IMAGE_UTIL_ERROR_NONE) {
+ g_print("image_util_anim_encode_save_to_file failed %d\n", ret);
+ break;
+ }
+ break;
+
+ case ENCODE_AGIF_SAVE_TO_BUFFER:
+ ret = image_util_anim_encode_save_to_buffer(handle, &result->buffer, &result->buffer_size);
+ if (ret != IMAGE_UTIL_ERROR_NONE) {
+ g_print("image_util_anim_encode_save_to_buffer failed %d\n", ret);
+ break;
+ }
+ __write_file(result->path, result->buffer, result->buffer_size);
+ SAFE_FREE(result->buffer);
+ break;
+ default:
+ g_print("wrong encode animation menu %u", menu);
+ break;
+ }
+
+ERROR:
+ image_util_anim_encode_destroy(handle);
+
+ return ret;
+}
+
/* run transform with parameters
* input/output : use only image_h
*/
}
}
+static void __interpret_encode_anim(const char *cmd, unsigned int index)
+{
+ int ret = 0;
+ test_complex_data_s *input_data = NULL;
+
+ switch(index) {
+ case ENCODE_ANIM_SET_DIR:
+ __menu_move(SET_DIR_MENU);
+ break;
+ case ENCODE_ANIM_SET_TYPE:
+ __menu_move(SET_ANIM_TYPE_MENU);
+ break;
+ case ENCODE_ANIM_SET_DELAY:
+ __menu_move(SET_DELAY_MENU);
+ break;
+ case ENCODE_ANIM_SET_BG_COLOR:
+ __menu_move(SET_BG_COLOR_MENU);
+ break;
+ case ENCODE_ANIM_SET_LOSSLESS:
+ __menu_move(SET_LOSSLESS_MENU);
+ break;
+ case ENCODE_ANIM_SAVE_TO_FILE:
+ case ENCODE_ANIM_SAVE_TO_BUFFER:
+ if (!__data_pop(&input_data)) {
+ g_print("There is no test data for decode.\n");
+ break;
+ }
+ __get_encode_anim_path(g_encode_anim_params.type, FILE_FOR_ENCODE_ANIM, &g_encode_anim_result.path);
+ ret = __run_encode_anim(index, input_data, &g_encode_anim_params, &g_encode_anim_result);
+ if (ret == IMAGE_UTIL_ERROR_NONE) {
+ g_print("Success to encode image!!!\n");
+ __data_push(&g_encode_anim_result);
+ } else {
+ g_print("Fail to encode image!!!\n");
+ __data_push(input_data);
+ }
+ break;
+ default:
+ g_print("wrong command! %s\n\n", cmd);
+ break;
+ }
+}
+
static void __interpret_transform(const char *cmd, unsigned int index)
{
int ret = 0;
g_print("Success to set compression (%u)\n", g_encode_params.compression);
break;
case SET_LOSSLESS_MENU:
- g_encode_params.lossless = (index == 0) ? false : true;
- g_print("Success to set lossless (%u)\n", g_encode_params.lossless);
+ if (g_previous_menu == ENCODE_MENU) {
+ g_encode_params.lossless = (index == 0) ? false : true;
+ g_print("Success to set lossless (%u)\n", g_encode_params.lossless);
+ } else if (g_previous_menu == ENCODE_ANIM_MENU) {
+ g_encode_anim_params.lossless = (index == 0) ? false : true;
+ g_print("Success to set animation lossless (%u)\n", g_encode_anim_params.lossless);
+ }
break;
case SET_CONVERT_MENU:
g_transform_params.convert_color = index;
g_transform_params.crop_area.y, g_transform_params.crop_area.w, g_transform_params.crop_area.h);
break;
case SET_DELAY_MENU:
- g_encode_agif_params.delay = index;
- g_print("Success to set agif delay (%u)\n", g_encode_agif_params.delay);
+ if (g_previous_menu == ENCODE_AGIF_MENU) {
+ g_encode_agif_params.delay = index;
+ g_print("Success to set agif delay (%u)\n", g_encode_agif_params.delay);
+ } else if (g_previous_menu == ENCODE_ANIM_MENU) {
+ g_encode_anim_params.delay = index;
+ g_print("Success to set animation delay (%u)\n", g_encode_anim_params.delay);
+ }
+ break;
+ case SET_BG_COLOR_MENU:
+ if (!__set_input_color(cmd, &g_encode_anim_params.bg_color)) {
+ g_print("wrong size! %s\n\n", cmd);
+ return FALSE;
+ }
+ g_print("Success to set animation bg_color(%u,%u,%u,%u)\n", g_encode_anim_params.bg_color.r,
+ g_encode_anim_params.bg_color.g, g_encode_anim_params.bg_color.b, g_encode_anim_params.bg_color.a);
break;
case SET_DOWNSCALE_MENU:
g_decode_params.downscale = index;
__get_encode_path(g_encode_params.type, FILE_FOR_ENCODE, &g_encode_result.path);
g_print("Success to set image_type (%u)\n", g_encode_params.type);
break;
+ case SET_ANIM_TYPE_MENU:
+ g_encode_anim_params.type = index;
+ __get_encode_anim_path(g_encode_anim_params.type, FILE_FOR_ENCODE_ANIM, &g_encode_anim_result.path);
+ g_print("Success to set anim_type (%u)\n", g_encode_anim_params.type);
+ break;
default:
g_print("wrong command! %s\n\n", cmd);
return FALSE;
case TEST_ENCODE_AGIF:
__menu_move(ENCODE_AGIF_MENU);
break;
+ case TEST_ENCODE_ANIM:
+ __menu_move(ENCODE_ANIM_MENU);
+ break;
case TEST_TRANSFORM:
__menu_move(TRANSFORM_MENU);
break;
__interpret_encode_agif(cmd, index);
break;
+ /* Encode ANIMATION menu */
+ case ENCODE_ANIM_MENU:
+ __interpret_encode_anim(cmd, index);
+ break;
+
/* Transform menu */
case TRANSFORM_MENU:
__interpret_transform(cmd, index);
memset(&g_decode_params, 0, sizeof(test_decode_params_s));
memset(&g_encode_params, 0, sizeof(test_encode_params_s));
memset(&g_encode_agif_params, 0, sizeof(test_encode_agif_params_s));
+ memset(&g_encode_anim_params, 0, sizeof(test_encode_anim_params_s));
memset(&g_transform_params, 0, sizeof(test_transform_params_s));
/* If you want to change default value, change the value here!!! */
g_encode_params.compression = IMAGE_UTIL_PNG_COMPRESSION_6;
/* encode_agif */
- g_encode_agif_params.delay = 10;
+ g_encode_agif_params.delay = 100;
+
+ /* encode_anim */
+ g_encode_anim_params.type = IMAGE_UTIL_ANIM_WEBP;
+ g_encode_anim_params.lossless = false;
+ g_encode_anim_params.delay = 100;
/* transform, not used yet */
g_transform_params.convert_color = IMAGE_UTIL_COLORSPACE_RGB888;
unsigned int i = 0;
g_queue_free_full(g_queue_menu, g_free);
- g_queue_free_full(g_queue_agif_images, g_free);
+ g_queue_free_full(g_queue_anim_images, g_free);
g_free(g_input_data.path);
g_free(g_input_data.buffer);