fix resource leak
[platform/core/multimedia/libheif.git] / test / heif_testsuite.c
1 /*
2  * libheif
3  *
4  * Copyright (c) 2021 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Jiyong Min <jiyong.min@samsung.com>
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  */
21
22 #include <stdio.h>
23 #include <glib.h>
24
25 #include <magick/api.h>
26
27 #include <heif.h>
28
29 typedef enum {
30         TEST_AUTO,
31         TEST_GETINFO_FILE,
32         TEST_GETINFO_MEMORY,
33         TEST_DECODE_FILE,
34         TEST_DECODE_MEMORY,
35         TEST_THUMB_FILE,
36         TEST_THUMB_MEMORY,
37         TEST_NUM,
38 } heif_test_mode_e;
39
40 static const char *g_test_decode_file_jpeg[] = {
41         [HEIF_COLOR_FORMAT_NONE] = NULL,
42         [HEIF_COLOR_FORMAT_YUV420P] = NULL,
43         [HEIF_COLOR_FORMAT_RGB24] = "/opt/usr/home/owner/media/test_heif_file_rgb24.jpg",
44         [HEIF_COLOR_FORMAT_ARGB] = "/opt/usr/home/owner/media/test_heif_file_argb.jpg",
45         [HEIF_COLOR_FORMAT_BGRA] = "/opt/usr/home/owner/media/test_heif_file_bgra.jpg",
46         [HEIF_COLOR_FORMAT_RGBA] = "/opt/usr/home/owner/media/test_heif_file_rgba.jpg",
47 };
48 static const char *g_test_decode_file_png[] = {
49         [HEIF_COLOR_FORMAT_NONE] = NULL,
50         [HEIF_COLOR_FORMAT_YUV420P] = NULL,     // not supported yuv420p in png
51         [HEIF_COLOR_FORMAT_RGB24] = "/opt/usr/home/owner/media/test_heif_file_rgb24.png",
52         [HEIF_COLOR_FORMAT_ARGB] = "/opt/usr/home/owner/media/test_heif_file_argb.png",
53         [HEIF_COLOR_FORMAT_BGRA] = "/opt/usr/home/owner/media/test_heif_file_bgra.png",
54         [HEIF_COLOR_FORMAT_RGBA] = "/opt/usr/home/owner/media/test_heif_file_rgba.png",
55 };
56 static const char *g_test_decode_buff_jpeg[] = {
57         [HEIF_COLOR_FORMAT_NONE] = NULL,
58         [HEIF_COLOR_FORMAT_YUV420P] = NULL,
59         [HEIF_COLOR_FORMAT_RGB24] = "/opt/usr/home/owner/media/test_heif_buff_rgb24.jpg",
60         [HEIF_COLOR_FORMAT_ARGB] = "/opt/usr/home/owner/media/test_heif_buff_argb.jpg",
61         [HEIF_COLOR_FORMAT_BGRA] = "/opt/usr/home/owner/media/test_heif_buff_bgra.jpg",
62         [HEIF_COLOR_FORMAT_RGBA] = "/opt/usr/home/owner/media/test_heif_buff_rgba.jpg",
63 };
64 static const char *g_test_decode_buff_png[] = {
65         [HEIF_COLOR_FORMAT_NONE] = NULL,
66         [HEIF_COLOR_FORMAT_YUV420P] = NULL,
67         [HEIF_COLOR_FORMAT_RGB24] = "/opt/usr/home/owner/media/test_heif_buff_rgb24.png",
68         [HEIF_COLOR_FORMAT_ARGB] = "/opt/usr/home/owner/media/test_heif_buff_argb.png",
69         [HEIF_COLOR_FORMAT_BGRA] = "/opt/usr/home/owner/media/test_heif_buff_bgra.png",
70         [HEIF_COLOR_FORMAT_RGBA] = "/opt/usr/home/owner/media/test_heif_buff_rgba.png",
71 };
72 static const char *g_test_thumb_file_jpeg[] = {
73         [HEIF_COLOR_FORMAT_NONE] = NULL,
74         [HEIF_COLOR_FORMAT_YUV420P] = NULL,
75         [HEIF_COLOR_FORMAT_RGB24] = "/opt/usr/home/owner/media/test_heif_thumb_file_rgb24.jpg",
76         [HEIF_COLOR_FORMAT_ARGB] = "/opt/usr/home/owner/media/test_heif_thumb_file_argb.jpg",
77         [HEIF_COLOR_FORMAT_BGRA] = "/opt/usr/home/owner/media/test_heif_thumb_file_bgra.jpg",
78         [HEIF_COLOR_FORMAT_RGBA] = "/opt/usr/home/owner/media/test_heif_thumb_file_rgba.jpg",
79 };
80 static const char *g_test_thumb_file_png[] = {
81         [HEIF_COLOR_FORMAT_NONE] = NULL,
82         [HEIF_COLOR_FORMAT_YUV420P] = NULL,
83         [HEIF_COLOR_FORMAT_RGB24] = "/opt/usr/home/owner/media/test_heif_thumb_file_rgb24.png",
84         [HEIF_COLOR_FORMAT_ARGB] = "/opt/usr/home/owner/media/test_heif_thumb_file_argb.png",
85         [HEIF_COLOR_FORMAT_BGRA] = "/opt/usr/home/owner/media/test_heif_thumb_file_bgra.png",
86         "/opt/usr/home/owner/media/test_heif_thumb_file_rgba.png",
87 };
88 static const char *g_test_thumb_buff_jpeg[] = {
89         [HEIF_COLOR_FORMAT_NONE] = NULL,
90         [HEIF_COLOR_FORMAT_YUV420P] = NULL,
91         [HEIF_COLOR_FORMAT_RGB24] = "/opt/usr/home/owner/media/test_heif_thumb_buff_rgb24.jpg",
92         [HEIF_COLOR_FORMAT_ARGB] = "/opt/usr/home/owner/media/test_heif_thumb_buff_argb.jpg",
93         [HEIF_COLOR_FORMAT_BGRA] = "/opt/usr/home/owner/media/test_heif_thumb_buff_bgra.jpg",
94         [HEIF_COLOR_FORMAT_RGBA] = "/opt/usr/home/owner/media/test_heif_thumb_buff_rgba.jpg",
95 };
96 static const char *g_test_thumb_buff_png[] = {
97         [HEIF_COLOR_FORMAT_NONE] = NULL,
98         [HEIF_COLOR_FORMAT_YUV420P] = NULL,
99         [HEIF_COLOR_FORMAT_RGB24] = "/opt/usr/home/owner/media/test_heif_thumb_buff_rgb24.png",
100         [HEIF_COLOR_FORMAT_ARGB] = "/opt/usr/home/owner/media/test_heif_thumb_buff_argb.png",
101         [HEIF_COLOR_FORMAT_BGRA] = "/opt/usr/home/owner/media/test_heif_thumb_buff_bgra.png",
102         [HEIF_COLOR_FORMAT_RGBA] = "/opt/usr/home/owner/media/test_heif_thumb_buff_rgba.png",
103 };
104
105 static int g_test_mode = TEST_AUTO;
106 static char *g_path = NULL;
107 static int g_color = HEIF_COLOR_FORMAT_RGB24;
108
109 // for only test
110 static void __print_help(const char *argv0);
111 static bool __get_input_data(const char *argv, const long min, const long max, int *data);
112 static bool __get_arguments(int argc, char *argv[]);
113 // library tests
114 static bool __test_auto(void);
115 static bool __test_get_info(int mode);
116 static bool __test_decode(int mode);
117 static bool __test_thumb(int mode);
118 static int __get_image_attrs(heif_image_info_h image_info);
119 // encode image using GraphicsMagick
120 static int __save_image_to_file(heif_image_h source, const char *path);
121
122
123 int main(int argc, char *argv[])
124 {
125         if (argc < 2) {
126                 __print_help(argv[0]);
127                 return 0;
128         }
129
130         if (false == __get_arguments(argc, argv)) {
131                 g_print("\t[HEIF_testsuite] _get_arguments failed\n");
132                 goto END;
133         }
134
135         /* test all functions automatically */
136         if (g_test_mode == TEST_AUTO) {
137                 if (false == __test_auto())
138                         g_print("\t[HEIF_testsuite] _test_auto failed\n");
139                 goto END;
140         }
141
142         /* test of getting image information from file or memory */
143         if (g_test_mode == TEST_GETINFO_FILE || g_test_mode == TEST_GETINFO_MEMORY) {
144                 if (false == __test_get_info(g_test_mode))
145                         g_print("\t[HEIF_testsuite] __test_decode failed\n");
146                 goto END;
147         }
148
149         /* test of decoding image from file or memory */
150         if (g_test_mode == TEST_DECODE_FILE || g_test_mode == TEST_DECODE_MEMORY) {
151                 if (false == __test_decode(g_test_mode))
152                         g_print("\t[HEIF_testsuite] __test_decode failed\n");
153                 goto END;
154         }
155
156         /* test of getting thumbnail from file or memory */
157         if (g_test_mode == TEST_THUMB_FILE || g_test_mode == TEST_THUMB_MEMORY) {
158                 if (false == __test_thumb(g_test_mode))
159                         g_print("\t[HEIF_testsuite] __test_thumb failed\n");
160                 goto END;
161         }
162
163 END:
164         g_free(g_path);
165
166         return 0;
167 }
168
169 static void __print_help(const char *argv0)
170 {
171         g_print("\t[usage]\n");
172         g_print("\t\t1. decode & encode : %s {mode} {path} {color_format(opt)}\n", argv0);
173         g_print("\t\t2. decode : %s 0 /home/owner/media/test.heif\n", argv0);
174         g_print("\t\t3. encode : %s 1 /home/owner/media/test.heif\n", argv0);
175         g_print("\t\t4. encode : %s 3 /home/owner/media/test.heif 2(HEIF_COLOR_FORMAT_RGB24)\n", argv0);
176         g_print("\t\t5. [mode]\n");
177         g_print("\t\t  0 - auto\n");
178         g_print("\t\t  1 - get information from file\n");
179         g_print("\t\t  2 - get information from memory\n");
180         g_print("\t\t  3 - decode from file\n");
181         g_print("\t\t  4 - decode from memory\n");
182         g_print("\t\t  5 - get thumbnail from file\n");
183         g_print("\t\t  6 - get thumbnail from memory\n");
184 }
185
186 static bool __get_input_data(const char *argv, const long min, const long max, int *data)
187 {
188         if (argv == NULL || strlen(argv) == 0)
189                 return false;
190
191         long temp = g_ascii_strtoll(argv, NULL, 10);
192         if (temp < min || temp > max)
193                 return false;
194
195         *data  = (int)temp;
196
197         return true;
198 }
199
200 static bool __get_arguments(int argc, char *argv[])
201 {
202         if (false == __get_input_data(argv[1], TEST_AUTO, TEST_NUM - 1, &g_test_mode)) {
203                 g_print("\t[HEIF_testsuite] invalid mode(%s)\n", argv[1]);
204                 __print_help(argv[0]);
205                 return false;
206         }
207
208         g_path = g_strdup(argv[2]);
209         if (!g_path) {
210                 g_print("\t[HEIF_testsuite] invalid path(%s)\n", argv[2]);
211                 __print_help(argv[0]);
212                 return false;
213         }
214
215         if (g_test_mode == TEST_AUTO ||
216                 g_test_mode == TEST_GETINFO_FILE ||
217                 g_test_mode == TEST_GETINFO_MEMORY) {
218                 /* do nothing... */
219         } else if (g_test_mode == TEST_DECODE_FILE ||
220                         g_test_mode == TEST_DECODE_MEMORY ||
221                         g_test_mode == TEST_THUMB_FILE ||
222                         g_test_mode == TEST_THUMB_MEMORY) {
223                 if (false == __get_input_data(argv[3], HEIF_COLOR_FORMAT_YUV420P, HEIF_COLOR_FORMAT_MAX - 1, &g_color))
224                         g_print("\t[HEIF_testsuite] used default color(%d)\n", g_color);
225         } else {
226                 g_print("\t[HEIF_testsuite] invalid mode for test %s\n", argv[1]);
227                 return false;
228         }
229
230         return true;
231 }
232
233 static bool __test_auto(void)
234 {
235         bool result = true;
236
237         if (!__test_get_info(TEST_GETINFO_FILE)) {
238                 g_print("\t[HEIF_testsuite] __test_get_info(%d) failed\n", TEST_GETINFO_FILE);
239                 result = false;
240         }
241
242         if (!__test_get_info(TEST_GETINFO_MEMORY)) {
243                 g_print("\t[HEIF_testsuite] __test_get_info(%d) failed\n", TEST_GETINFO_MEMORY);
244                 result = false;
245         }
246
247         for (g_color = HEIF_COLOR_FORMAT_YUV420P; g_color < HEIF_COLOR_FORMAT_MAX; g_color++) {
248                 if (!__test_decode(TEST_DECODE_FILE)) {
249                         g_print("\t[HEIF_TEST] __test_decode(%d/format:%u) fail\n", TEST_DECODE_FILE, g_color);
250                         result = false;
251                 }
252         }
253
254         for (g_color = HEIF_COLOR_FORMAT_YUV420P; g_color < HEIF_COLOR_FORMAT_MAX; g_color++) {
255                 if (!__test_decode(TEST_DECODE_MEMORY)) {
256                         g_print("\t[HEIF_TEST] __test_decode(%d/format:%u) fail\n", TEST_DECODE_MEMORY, g_color);
257                         result = false;
258                 }
259         }
260
261         for (g_color = HEIF_COLOR_FORMAT_YUV420P; g_color < HEIF_COLOR_FORMAT_MAX; g_color++) {
262                 if (!__test_thumb(TEST_THUMB_FILE)) {
263                         g_print("\t[HEIF_TEST] __test_thumb(%d/format:%u) fail\n", TEST_THUMB_FILE, g_color);
264                         result = false;
265                 }
266         }
267
268         for (g_color = HEIF_COLOR_FORMAT_YUV420P; g_color < HEIF_COLOR_FORMAT_MAX; g_color++) {
269                 if (!__test_thumb(TEST_THUMB_MEMORY)) {
270                         g_print("\t[HEIF_TEST] __test_thumb(%d/format:%u) fail\n", TEST_THUMB_MEMORY, g_color);
271                         result = false;
272                 }
273         }
274
275         return result;
276 }
277
278 static bool __test_get_info(int mode)
279 {
280         bool result = true;
281         int ret = 0;
282         heif_image_info_h image_info = NULL;
283         gchar *buffer = NULL;
284         gsize size = 0;
285         GError *error = NULL;
286
287         switch (mode) {
288         case TEST_GETINFO_FILE:
289                 ret = heif_get_image_info_from_file(g_path, &image_info);
290                 if (ret != LIBHEIF_ERROR_NONE) {
291                         g_print("\t[HEIF_TEST] heif_get_image_info_from_file fail %d\n", ret);
292                         return false;
293                 }
294
295                 g_print("[HEIF_TEST] heif_get_image_info_from_file succeed !!!\n");
296
297                 ret = __get_image_attrs(image_info);
298                 if (ret != LIBHEIF_ERROR_NONE) {
299                         g_print("\t[HEIF_TEST] __get_image_attrs fail %d\n", ret);
300                         result = false;
301                 }
302                 break;
303
304         case TEST_GETINFO_MEMORY:
305                 if (!g_file_get_contents(g_path, &buffer, &size, &error)) {
306                         g_print("\t[HEIF_TEST] g_file_get_contents fail [%s: %s]\n", g_path, (error ? error->message : "none"));
307                         if (error)
308                                 g_error_free(error);
309                         return false;
310                 }
311
312                 ret = heif_get_image_info_from_buffer((unsigned char *)((void *)buffer), (size_t)size, &image_info);
313                 g_free(buffer);
314                 if (ret != LIBHEIF_ERROR_NONE) {
315                         g_print("\t[HEIF_TEST] heif_get_image_info_from_buffer fail %d\n", ret);
316                         return false;
317                 }
318
319                 g_print("[HEIF_TEST] heif_get_image_info_from_buffer succeed !!!\n");
320
321                 ret = __get_image_attrs(image_info);
322                 if (ret != LIBHEIF_ERROR_NONE) {
323                         g_print("\t[HEIF_TEST] __get_image_attrs fail %d\n", ret);
324                         result = false;
325                 }
326
327                 break;
328
329         default:
330                 g_print("\t[HEIF_TEST] invalid mode %d\n", mode);
331                 return false;
332         }
333
334         heif_image_info_free(image_info);
335         return result;
336 }
337
338 static bool __test_decode(int mode)
339 {
340         int ret = 0;
341         heif_image_h image = NULL;
342         gchar *buffer = NULL;
343         gsize size = 0;
344         GError *error = NULL;
345
346         switch (mode) {
347         case TEST_DECODE_FILE:
348                 ret = heif_decode_image_from_file(g_path, g_color, &image);
349                 if (ret != LIBHEIF_ERROR_NONE) {
350                         g_print("\t[HEIF_TEST] heif_decode_image_from_file(format:%u) fail %d\n", g_color, ret);
351                         return false;
352                 }
353
354                 g_print("[HEIF_TEST] heif_decode_image_from_file succeed !!!\n");
355
356                 ret = __save_image_to_file(image, g_test_decode_file_jpeg[g_color]);
357                 if (ret != LIBHEIF_ERROR_NONE)
358                         g_print("\t[HEIF_TEST] __save_to_image fail %d\n", ret);
359
360                 ret = __save_image_to_file(image, g_test_decode_file_png[g_color]);
361                 if (ret != LIBHEIF_ERROR_NONE)
362                         g_print("\t[HEIF_TEST] __save_to_image fail %d\n", ret);
363
364                 break;
365
366         case TEST_DECODE_MEMORY:
367                 if (!g_file_get_contents(g_path, &buffer, &size, &error)) {
368                         g_print("\t[HEIF_TEST] g_file_get_contents fail [%s: %s]\n", g_path, (error ? error->message : "none"));
369                         if (error)
370                                 g_error_free(error);
371                         return false;
372                 }
373
374                 ret = heif_decode_image_from_buffer((unsigned char *)((void *)buffer), (size_t)size, g_color, &image);
375                 g_free(buffer);
376                 if (ret != LIBHEIF_ERROR_NONE) {
377                         g_print("\t[HEIF_TEST] heif_decode_image_from_buffer fail %d\n", ret);
378                         return false;
379                 }
380
381                 g_print("[HEIF_TEST] heif_decode_image_from_buffer succeed !!!\n");
382
383                 ret = __save_image_to_file(image, g_test_decode_buff_jpeg[g_color]);
384                 if (ret != LIBHEIF_ERROR_NONE)
385                         g_print("\t[HEIF_TEST] __save_to_image fail %d\n", ret);
386
387                 ret = __save_image_to_file(image, g_test_decode_buff_png[g_color]);
388                 if (ret != LIBHEIF_ERROR_NONE)
389                         g_print("\t[HEIF_TEST] __save_to_image fail %d\n", ret);
390
391                 break;
392
393         default:
394                 g_print("\t[HEIF_TEST] invalid mode %d\n", mode);
395                 return false;
396         }
397
398         heif_image_free(image);
399         return true;
400 }
401
402 static bool __test_thumb(int mode)
403 {
404         int ret = 0;
405         heif_image_h thumbnail = NULL;
406         gchar *buffer = NULL;
407         gsize size = 0;
408         GError *error = NULL;
409
410         switch (mode) {
411         case TEST_THUMB_FILE:
412                 ret = heif_decode_thumb_from_file(g_path, g_color, &thumbnail);
413                 if (ret != LIBHEIF_ERROR_NONE) {
414                         g_print("\t[HEIF_TEST] heif_decode_thumb_from_file(format:%u) fail %d\n", g_color, ret);
415                         return false;
416                 }
417
418                 g_print("[HEIF_TEST] heif_decode_thumb_from_file succeed !!!\n");
419
420                 ret = __save_image_to_file(thumbnail, g_test_thumb_file_jpeg[g_color]);
421                 if (ret != LIBHEIF_ERROR_NONE)
422                         g_print("\t[HEIF_TEST] __save_to_image fail %d\n", ret);
423
424                 ret = __save_image_to_file(thumbnail, g_test_thumb_file_png[g_color]);
425                 if (ret != LIBHEIF_ERROR_NONE)
426                         g_print("\t[HEIF_TEST] __save_to_image fail %d\n", ret);
427
428                 break;
429
430         case TEST_THUMB_MEMORY:
431                 if (!g_file_get_contents(g_path, &buffer, &size, &error)) {
432                         g_print("\t[HEIF_TEST] g_file_get_contents fail [%s: %s]\n", g_path, (error ? error->message : "none"));
433                         if (error)
434                                 g_error_free(error);
435                         return false;
436                 }
437
438                 ret = heif_decode_thumb_from_buffer((unsigned char *)((void *)buffer), (size_t)size, g_color, &thumbnail);
439                 g_free(buffer);
440                 if (ret != LIBHEIF_ERROR_NONE) {
441                         g_print("\t[HEIF_TEST] heif_decode_thumb_from_buffer fail %d\n", ret);
442                         return false;
443                 }
444
445                 g_print("[HEIF_TEST] heif_decode_thumb_from_buffer succeed !!!\n");
446
447                 ret = __save_image_to_file(thumbnail, g_test_thumb_buff_jpeg[g_color]);
448                 if (ret != LIBHEIF_ERROR_NONE)
449                         g_print("\t[HEIF_TEST] __save_to_image fail %d\n", ret);
450
451                 ret = __save_image_to_file(thumbnail, g_test_thumb_buff_png[g_color]);
452                 if (ret != LIBHEIF_ERROR_NONE)
453                         g_print("\t[HEIF_TEST] __save_to_image fail %d\n", ret);
454
455                 break;
456
457         default:
458                 g_print("\t[HEIF_TEST] invalid mode %d\n", mode);
459                 return false;
460         }
461
462         heif_image_free(thumbnail);
463         return true;
464 }
465
466 static int __get_image_attrs(heif_image_info_h image_info)
467 {
468         int ret = 0;
469         int width = 0, height = 0, orientation = 0, mirror = 0;
470         char *mimetype = NULL;
471         void *exif = NULL, *icc_profile = NULL;
472         int mimetype_len = 0, exif_len = 0, icc_profile_len = 0;
473
474         /* get basic information */
475         ret = heif_image_info_get_attrs(image_info,
476                                                                 HEIF_IMAGE_MIMETYPE, &mimetype, &mimetype_len,
477                                                                 HEIF_IMAGE_WIDTH, &width,
478                                                                 HEIF_IMAGE_HEIGHT, &height,
479                                                                 HEIF_IMAGE_ORIENTATION, &orientation,
480                                                                 HEIF_IMAGE_MIRROR, &mirror,
481                                                                 NULL);
482         if (ret != LIBHEIF_ERROR_NONE)
483                 g_print("\t[HEIF_TEST] heif_image_info_get_attrs fail %d\n", ret);
484
485         g_print("[HEIF_TEST] Mimetype\t: %s\n", mimetype);
486         g_print("[HEIF_TEST] Width\t: %d\n", width);
487         g_print("[HEIF_TEST] Height\t: %d\n", height);
488         g_print("[HEIF_TEST] Orientation\t: %d\n", orientation);
489         g_print("[HEIF_TEST] Mirror\t: %d\n", mirror);
490
491         /* get extra information */
492         ret = heif_image_info_get_attrs(image_info,
493                                                                 HEIF_IMAGE_EXIF, &exif, &exif_len,
494                                                                 HEIF_IMAGE_ICC_PROFILE, &icc_profile, &icc_profile_len,
495                                                                 NULL);
496         if (ret != LIBHEIF_ERROR_NONE)
497                 g_print("\t[HEIF_TEST] heif_image_info_get_attrs fail %d\n", ret);
498
499         g_print("[HEIF_TEST] Exif\t: %p/%d\n", exif, exif_len);
500         g_print("[HEIF_TEST] ICC profile\t: %p/%d\n", icc_profile, icc_profile_len);
501
502         return ret;
503 }
504
505 static void __magick_log_method(const ExceptionType excep, const char *message)
506 {
507         /* To exclude time, user time and pid */
508         unsigned int start_idx = 31;
509
510         if (!message || (strlen(message) < start_idx))
511                 start_idx = 0;
512
513         g_print("\t\t[GM][Ex:%3u] %s", excep, message + start_idx);
514 }
515
516 static const char * __magick_get_map(heif_color_format_e format)
517 {
518         switch (format) {
519         case HEIF_COLOR_FORMAT_RGB24:
520                 return "RGB";
521         case HEIF_COLOR_FORMAT_ARGB:
522                 return "ARGB";
523         case HEIF_COLOR_FORMAT_BGRA:
524                 return "BGRA";
525         case HEIF_COLOR_FORMAT_RGBA:
526                 return "RGBA";
527         default:
528                 g_print("\t[HEIF_TEST] not supported format. [%d]", format);
529                 return NULL;
530         }
531 }
532
533 static Image *__magick_get_image(heif_image_h source, ExceptionInfo *exception)
534 {
535         unsigned int width = 0, height = 0;
536         heif_color_format_e format = HEIF_COLOR_FORMAT_NONE;
537         unsigned char *data = NULL;
538         size_t size = 0;
539         const char *map = NULL;
540         Image *image = NULL;
541
542         if (!exception) {
543                 g_print("\t[HEIF_TEST] invalid exception\n");
544                 return NULL;
545         }
546
547         if (heif_image_get_image(source, &width, &height, &format, &data, &size) != LIBHEIF_ERROR_NONE) {
548                 g_print("\t[HEIF_TEST] heif_image_get_image fail\n");
549                 return NULL;
550         }
551
552         map = __magick_get_map(format);
553         if (!map) {
554                 g_print("\t[HEIF_TEST] __magick_get_map fail\n");
555                 return NULL;
556         }
557
558         g_print("[HEIF_TEST][SOURCE] width: %u, height: %u format: %u data: %p, size: %zu\n", width, height, format, data, size);
559
560         image = ConstituteImage(width, height, map, CharPixel, data, exception);
561         if (!image) {
562                 g_print("\t[HEIF_TEST] ConstituteImage fail\n");
563                 if (exception->severity != UndefinedException)
564                         CatchException(exception);
565         }
566
567         return image;
568 }
569
570 static int __magick_write_image_to_file(Image *image, const char *path, ExceptionInfo *exception)
571 {
572         int ret = LIBHEIF_ERROR_NONE;
573         ImageInfo *_image_info = NULL;
574
575         if (!image || !path || !exception) {
576                 g_print("\t[HEIF_TEST] invalid %s\n",
577                         (!image) ? "image" : ((!path) ? "path" : "exception"));
578                 return LIBHEIF_ERROR_INVALID_PARAMETER;
579         }
580
581         _image_info = CloneImageInfo(0);
582         if (!_image_info) {
583                 g_print("\t[HEIF_TEST] CloneImageInfo fail\n");
584                 return LIBHEIF_ERROR_INVALID_OPERATION;
585         }
586
587         g_strlcpy(image->filename, path, sizeof(image->filename));
588         image->filename[MaxTextExtent-1] = '\0';
589
590         DeleteImageProfile(image, "EXIF");
591         DeleteImageProfile(image, "8BIM");
592         DeleteImageProfile(image, "ICM");
593         DeleteImageProfile(image, "IPTC");
594         DeleteImageProfile(image, "XMP");
595
596         AddDefinition(_image_info, "jpeg", "dct-method", "FASTEST", exception);
597         AddDefinition(_image_info, "jpeg", "optimize-coding", "FALSE", exception);
598         AddDefinition(_image_info, "webp", "lossless", "TRUE", exception);
599
600         if (WriteImage (_image_info, image) == MagickFalse) {
601                 g_print("\t[HEIF_TEST] WriteImage fail\n");
602                 if (exception->severity != UndefinedException)
603                         CatchException(exception);
604
605                 ret = LIBHEIF_ERROR_INVALID_OPERATION;
606         }
607
608         DestroyImageInfo(_image_info);
609
610         return ret;
611 }
612
613
614 static int __save_image_to_file(heif_image_h source, const char *path)
615 {
616         int ret = 0;
617         ExceptionInfo exception;
618         Image *image = NULL;
619
620         if (!path) {
621                 g_print("\t[HEIF_TEST] save function not supported\n");
622                 return LIBHEIF_ERROR_NONE;
623         }
624
625         g_print("[HEIF_TEST] path [%s]", path);
626
627         InitializeMagick(NULL);
628         GetExceptionInfo(&exception);
629
630         SetLogEventMask("warning, error, fatalerror, exception");
631         SetLogMethod(__magick_log_method);
632
633         image = __magick_get_image(source, &exception);
634         ret = __magick_write_image_to_file(image, path, &exception);
635         DestroyImageList(image);
636
637         DestroyExceptionInfo(&exception);
638         DestroyMagick();
639
640         return ret;
641 }