summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile_Evas.am27
-rw-r--r--src/lib/evas/common/evas_image_load.c4
-rw-r--r--src/lib/evas/file/evas_module.c4
-rw-r--r--src/modules/evas/loaders/jp2k/evas_image_load_jp2k.c409
4 files changed, 444 insertions, 0 deletions
diff --git a/src/Makefile_Evas.am b/src/Makefile_Evas.am
index 924e0e159b..29bea4b603 100644
--- a/src/Makefile_Evas.am
+++ b/src/Makefile_Evas.am
@@ -1275,6 +1275,33 @@ endif
1275endif 1275endif
1276endif 1276endif
1277 1277
1278if BUILD_LOADER_JP2K
1279if EVAS_STATIC_BUILD_JP2K
1280lib_evas_libevas_la_SOURCES += modules/evas/loaders/jp2k/evas_image_load_jp2k.c
1281lib_evas_libevas_la_CPPFLAGS += @evas_image_loader_jp2k_cflags@
1282lib_evas_libevas_la_LIBADD += @evas_image_loader_jp2k_libs@
1283if EVAS_CSERVE2
1284bin_evas_evas_cserve2_slave_SOURCES += modules/evas/loaders/jp2k/evas_image_load_jp2k.c
1285bin_evas_evas_cserve2_slave_CPPFLAGS += @evas_image_loader_jp2k_cflags@
1286bin_evas_evas_cserve2_slave_LDADD += @evas_image_loader_jp2k_libs@
1287endif
1288else
1289loaderjp2kpkgdir = $(libdir)/evas/modules/loaders/jp2k/$(MODULE_ARCH)
1290loaderjp2kpkg_LTLIBRARIES = modules/evas/loaders/jp2k/module.la
1291modules_evas_loaders_jp2k_module_la_SOURCES = modules/evas/loaders/jp2k/evas_image_load_jp2k.c
1292modules_evas_loaders_jp2k_module_la_CPPFLAGS = -I$(top_builddir)/src/lib/efl \
1293-I$(top_srcdir)/src/lib/evas/include \
1294@EVAS_CFLAGS@ \
1295@evas_image_loader_jp2k_cflags@
1296modules_evas_loaders_jp2k_module_la_LIBADD = \
1297@USE_EVAS_LIBS@ \
1298@evas_image_loader_jp2k_libs@
1299modules_evas_loaders_jp2k_module_la_DEPENDENCIES = @USE_EVAS_INTERNAL_LIBS@
1300modules_evas_loaders_jp2k_module_la_LDFLAGS = -module @EFL_LTMODULE_FLAGS@
1301modules_evas_loaders_jp2k_module_la_LIBTOOLFLAGS = --tag=disable-static
1302endif
1303endif
1304
1278if BUILD_LOADER_PMAPS 1305if BUILD_LOADER_PMAPS
1279if EVAS_STATIC_BUILD_PMAPS 1306if EVAS_STATIC_BUILD_PMAPS
1280lib_evas_libevas_la_SOURCES += modules/evas/loaders/pmaps/evas_image_load_pmaps.c 1307lib_evas_libevas_la_SOURCES += modules/evas/loaders/pmaps/evas_image_load_pmaps.c
diff --git a/src/lib/evas/common/evas_image_load.c b/src/lib/evas/common/evas_image_load.c
index afca101deb..c945442be5 100644
--- a/src/lib/evas/common/evas_image_load.c
+++ b/src/lib/evas/common/evas_image_load.c
@@ -29,6 +29,10 @@ static const struct ext_loader_s loaders[] =
29 MATCHING(".jpg", "jpeg"), 29 MATCHING(".jpg", "jpeg"),
30 MATCHING(".jpeg", "jpeg"), 30 MATCHING(".jpeg", "jpeg"),
31 MATCHING(".jfif", "jpeg"), 31 MATCHING(".jfif", "jpeg"),
32 MATCHING(".j2k", "jp2k"),
33 MATCHING(".jp2", "jp2k"),
34 MATCHING(".jpx", "jp2k"),
35 MATCHING(".jpf", "jp2k"),
32 MATCHING(".eet", "eet"), 36 MATCHING(".eet", "eet"),
33 MATCHING(".edj", "eet"), 37 MATCHING(".edj", "eet"),
34 MATCHING(".eap", "eet"), 38 MATCHING(".eap", "eet"),
diff --git a/src/lib/evas/file/evas_module.c b/src/lib/evas/file/evas_module.c
index 9f70e60369..b3d0a87c92 100644
--- a/src/lib/evas/file/evas_module.c
+++ b/src/lib/evas/file/evas_module.c
@@ -136,6 +136,7 @@ EVAS_EINA_STATIC_MODULE_DEFINE(image_loader, generic);
136EVAS_EINA_STATIC_MODULE_DEFINE(image_loader, gif); 136EVAS_EINA_STATIC_MODULE_DEFINE(image_loader, gif);
137EVAS_EINA_STATIC_MODULE_DEFINE(image_loader, ico); 137EVAS_EINA_STATIC_MODULE_DEFINE(image_loader, ico);
138EVAS_EINA_STATIC_MODULE_DEFINE(image_loader, jpeg); 138EVAS_EINA_STATIC_MODULE_DEFINE(image_loader, jpeg);
139EVAS_EINA_STATIC_MODULE_DEFINE(image_loader, jp2k);
139EVAS_EINA_STATIC_MODULE_DEFINE(image_loader, pmaps); 140EVAS_EINA_STATIC_MODULE_DEFINE(image_loader, pmaps);
140EVAS_EINA_STATIC_MODULE_DEFINE(image_loader, png); 141EVAS_EINA_STATIC_MODULE_DEFINE(image_loader, png);
141EVAS_EINA_STATIC_MODULE_DEFINE(image_loader, psd); 142EVAS_EINA_STATIC_MODULE_DEFINE(image_loader, psd);
@@ -207,6 +208,9 @@ static const struct {
207#ifdef EVAS_STATIC_BUILD_JPEG 208#ifdef EVAS_STATIC_BUILD_JPEG
208 EVAS_EINA_STATIC_MODULE_USE(image_loader, jpeg), 209 EVAS_EINA_STATIC_MODULE_USE(image_loader, jpeg),
209#endif 210#endif
211#ifdef EVAS_STATIC_BUILD_JP2K
212 EVAS_EINA_STATIC_MODULE_USE(image_loader, jp2k),
213#endif
210#ifdef EVAS_STATIC_BUILD_PMAPS 214#ifdef EVAS_STATIC_BUILD_PMAPS
211 EVAS_EINA_STATIC_MODULE_USE(image_loader, pmaps), 215 EVAS_EINA_STATIC_MODULE_USE(image_loader, pmaps),
212#endif 216#endif
diff --git a/src/modules/evas/loaders/jp2k/evas_image_load_jp2k.c b/src/modules/evas/loaders/jp2k/evas_image_load_jp2k.c
new file mode 100644
index 0000000000..28200cee0a
--- /dev/null
+++ b/src/modules/evas/loaders/jp2k/evas_image_load_jp2k.c
@@ -0,0 +1,409 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif
4
5#include <stdio.h>
6
7#ifdef HAVE_EVIL
8# include <Evil.h>
9#endif
10
11#include <openjpeg.h>
12
13#include "Evas_Loader.h"
14
15static int _evas_loader_jp2k_log_dom = -1;
16
17#ifdef ERR
18# undef ERR
19#endif
20#define ERR(...) EINA_LOG_DOM_ERR(_evas_loader_jp2k_log_dom, __VA_ARGS__)
21
22#ifdef WRN
23# undef WRN
24#endif
25#define WRN(...) EINA_LOG_DOM_WARN(_evas_loader_jp2k_log_dom, __VA_ARGS__)
26
27#ifdef INF
28# undef INF
29#endif
30#define INF(...) EINA_LOG_DOM_INFO(_evas_loader_jp2k_log_dom, __VA_ARGS__)
31
32typedef struct _Evas_Loader_Internal Evas_Loader_Internal;
33struct _Evas_Loader_Internal
34{
35 Eina_File *f;
36 Evas_Image_Load_Opts *opts;
37};
38
39static void
40_jp2k_error_cb(const char *msg, void *data EINA_UNUSED)
41{
42 ERR("OpenJPEG internal error: '%s'.", msg);
43}
44
45static void
46_jp2k_warning_cb(const char *msg, void *data EINA_UNUSED)
47{
48 WRN("OpenJPEG internal warning: '%s'.", msg);
49}
50
51static void
52_jp2k_info_cb(const char *msg, void *data EINA_UNUSED)
53{
54 INF("OpenJPEG internal information: '%s'.", msg);
55}
56
57static Eina_Bool
58evas_image_load_file_head_jp2k_internal(unsigned int *w, unsigned int *h,
59 unsigned char *alpha,
60 Evas_Image_Load_Opts *opts EINA_UNUSED,
61 void *map, size_t length,
62 int *error)
63{
64 opj_event_mgr_t event_mgr;
65 opj_dparameters_t params;
66 opj_dinfo_t *info;
67 opj_cio_t *cio;
68 opj_image_t *image;
69 int format;
70 int k;
71
72 if (length < 2)
73 {
74 *error = EVAS_LOAD_ERROR_GENERIC;
75 return EINA_FALSE;
76 }
77
78 if (((unsigned char *)map)[0] == 0xFF && ((unsigned char *)map)[1] == 0x4F)
79 format = CODEC_J2K;
80 else
81 format = CODEC_JP2;
82
83 memset(&event_mgr, 0, sizeof(event_mgr));
84 event_mgr.error_handler = _jp2k_error_cb;
85 event_mgr.warning_handler = _jp2k_warning_cb;
86 event_mgr.info_handler = _jp2k_info_cb;
87
88 opj_set_default_decoder_parameters(&params);
89 info = opj_create_decompress(format);
90 if (!info)
91 {
92 *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
93 return EINA_FALSE;
94 }
95 opj_set_event_mgr((opj_common_ptr)info, &event_mgr, NULL);
96 opj_setup_decoder(info, &params);
97
98 cio = opj_cio_open((opj_common_ptr)info, map, length);
99 if (!cio)
100 {
101 *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
102 return EINA_FALSE;
103 }
104
105 image = opj_decode(info, cio);
106 if (!image)
107 {
108 *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
109 return EINA_FALSE;
110 }
111
112 for (k = 1; k < image->numcomps; k++)
113 {
114 if (image->comps[k].w != image->comps[0].w)
115 goto free_image;
116 if (image->comps[k].h != image->comps[0].h)
117 goto free_image;
118 if (image->comps[k].prec > 8)
119 goto free_image;
120 }
121
122 *w = image->comps[0].w;
123 *h = image->comps[0].h;
124 *alpha = ((image->numcomps == 4) || (image->numcomps == 2)) ? 1 : 0;
125 *error = EVAS_LOAD_ERROR_NONE;
126
127 opj_image_destroy(image);
128 opj_cio_close(cio);
129 opj_destroy_decompress(info);
130
131 return EINA_TRUE;
132
133 free_image:
134 *error = EVAS_LOAD_ERROR_GENERIC;
135 opj_image_destroy(image);
136 opj_cio_close(cio);
137 opj_destroy_decompress(info);
138
139 return EINA_FALSE;
140}
141
142static Eina_Bool
143evas_image_load_file_data_jp2k_internal(Evas_Image_Load_Opts *opts EINA_UNUSED,
144 Evas_Image_Property *prop EINA_UNUSED,
145 void *pixels,
146 void *map, size_t length,
147 int *error)
148{
149 opj_dparameters_t params;
150 opj_dinfo_t *info;
151 opj_cio_t *cio;
152 opj_image_t *image;
153 unsigned int *iter;
154 int format;
155 int idx;
156
157 if (((unsigned char *)map)[0] == 0xFF && ((unsigned char *)map)[1] == 0x4F)
158 format = CODEC_J2K;
159 else
160 format = CODEC_JP2;
161
162 opj_set_default_decoder_parameters(&params);
163 info = opj_create_decompress(format);
164 opj_set_event_mgr((opj_common_ptr)info, NULL, NULL);
165 opj_setup_decoder(info, &params);
166 cio = opj_cio_open((opj_common_ptr)info, map, length);
167 image = opj_decode(info, cio);
168
169 iter = pixels;
170 idx = 0;
171
172 /*
173 * FIXME:
174 * image->numcomps == 4, image->color_space == CLRSPC_SYCC : YUV
175 */
176 /* BGR(A) */
177 if ((image->numcomps >= 3) &&
178 (image->comps[0].dx == image->comps[1].dx) &&
179 (image->comps[1].dx == image->comps[2].dx) &&
180 (image->comps[0].dy == image->comps[1].dy) &&
181 (image->comps[1].dy == image->comps[2].dy))
182 {
183 int a;
184 int r;
185 int g;
186 int b;
187 int i;
188 int j;
189
190 for (j = 0; j < image->comps[0].h; j++)
191 {
192 for (i = 0; i < image->comps[0].w; i++, idx++, iter++)
193 {
194 r = image->comps[0].data[idx];
195 r+= (image->comps[0].sgnd ? 1 << (image->comps[0].prec - 1) : 0);
196 if (r > 255) r = 255;
197 if (r < 0) r = 0;
198
199 g = image->comps[1].data[idx];
200 g+= (image->comps[1].sgnd ? 1 << (image->comps[1].prec - 1) : 0);
201 if (g > 255) g = 255;
202 if (g < 0) g = 0;
203
204 b = image->comps[2].data[idx];
205 b+= (image->comps[2].sgnd ? 1 << (image->comps[2].prec - 1) : 0);
206 if (b > 255) b = 255;
207 if (b < 0) b = 0;
208
209 if (image->numcomps == 4)
210 {
211 a = image->comps[3].data[idx];
212 a+= (image->comps[3].sgnd ? 1 << (image->comps[3].prec - 1) : 0);
213 if (a > 255) a = 255;
214 if (a < 0) a = 0;
215 }
216 else
217 a = 255;
218
219 *iter = a << 24 | r << 16 | g << 8 | b;
220 }
221 }
222 }
223 /* *GRAY(A) */
224 else if (((image->numcomps == 1) || (image->numcomps == 2)) &&
225 (image->comps[0].dx == image->comps[1].dx) &&
226 (image->comps[1].dx == image->comps[2].dx) &&
227 (image->comps[0].dy == image->comps[1].dy) &&
228 (image->comps[1].dy == image->comps[2].dy))
229 {
230 int a;
231 int g;
232 int i;
233 int j;
234
235 for (j = 0; j < image->comps[0].h; j++)
236 {
237 for (i = 0; i < image->comps[0].w; i++, idx++, iter++)
238 {
239 g = image->comps[0].data[idx];
240 g+= (image->comps[0].sgnd ? 1 << (image->comps[0].prec - 1) : 0);
241 if (g > 255) g = 255;
242 if (g < 0) g = 0;
243
244 if (image->numcomps == 2)
245 {
246 a = image->comps[1].data[idx];
247 a+= (image->comps[1].sgnd ? 1 << (image->comps[1].prec - 1) : 0);
248 if (a > 255) a = 255;
249 if (a < 0) a = 0;
250 }
251 else
252 a = 255;
253
254 *iter = a << 24 | g << 16 | g << 8 | g;
255 }
256 }
257 }
258
259 opj_image_destroy(image);
260 opj_cio_close(cio);
261 opj_destroy_decompress(info);
262
263 *error = EVAS_LOAD_ERROR_NONE;
264 return EINA_TRUE;
265}
266
267static void *
268evas_image_load_file_open_jp2k(Eina_File *f, Eina_Stringshare *key EINA_UNUSED,
269 Evas_Image_Load_Opts *opts,
270 Evas_Image_Animated *animated EINA_UNUSED,
271 int *error)
272{
273 Evas_Loader_Internal *loader;
274
275 loader = calloc(1, sizeof (Evas_Loader_Internal));
276 if (!loader)
277 {
278 *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
279 return NULL;
280 }
281
282 loader->f = f;
283 loader->opts = opts;
284
285 return loader;
286}
287
288static void
289evas_image_load_file_close_jp2k(void *loader_data)
290{
291 free(loader_data);
292}
293
294static Eina_Bool
295evas_image_load_file_head_jp2k(void *loader_data,
296 Evas_Image_Property *prop,
297 int *error)
298{
299 Evas_Loader_Internal *loader = loader_data;
300 Evas_Image_Load_Opts *opts;
301 Eina_File *f;
302 void *map;
303 Eina_Bool val;
304
305 opts = loader->opts;
306 f = loader->f;
307
308 map = eina_file_map_all(f, EINA_FILE_RANDOM);
309 if (!map)
310 {
311 *error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
312 return EINA_FALSE;
313 }
314
315 val = evas_image_load_file_head_jp2k_internal(&prop->w, &prop->h,
316 &prop->alpha,
317 opts,
318 map, eina_file_size_get(f),
319 error);
320
321 eina_file_map_free(f, map);
322
323 return val;
324}
325
326static Eina_Bool
327evas_image_load_file_data_jp2k(void *loader_data,
328 Evas_Image_Property *prop,
329 void *pixels,
330 int *error)
331{
332 Evas_Loader_Internal *loader = loader_data;
333 Evas_Image_Load_Opts *opts;
334 Eina_File *f;
335 void *map;
336 Eina_Bool val = EINA_FALSE;
337
338 f = loader->f;
339 opts = loader->opts;
340
341 map = eina_file_map_all(f, EINA_FILE_WILLNEED);
342 if (!map)
343 {
344 *error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
345 goto on_error;
346 }
347
348 val = evas_image_load_file_data_jp2k_internal(opts, prop, pixels,
349 map, eina_file_size_get(f),
350 error);
351
352 eina_file_map_free(f, map);
353
354 on_error:
355 return val;
356}
357
358static Evas_Image_Load_Func evas_image_load_jp2k_func =
359{
360 evas_image_load_file_open_jp2k,
361 evas_image_load_file_close_jp2k,
362 evas_image_load_file_head_jp2k,
363 evas_image_load_file_data_jp2k,
364 NULL,
365 EINA_TRUE,
366 EINA_TRUE
367};
368
369static int
370module_open(Evas_Module *em)
371{
372 if (!em) return 0;
373
374 _evas_loader_jp2k_log_dom = eina_log_domain_register("evas-jp2k", EINA_COLOR_BLUE);
375 if (_evas_loader_jp2k_log_dom < 0)
376 {
377 EINA_LOG_ERR("Can not create a module log domain.");
378 return 0;
379 }
380
381 em->functions = (void *)(&evas_image_load_jp2k_func);
382
383 return 1;
384}
385
386static void
387module_close(Evas_Module *em EINA_UNUSED)
388{
389 eina_log_domain_unregister(_evas_loader_jp2k_log_dom);
390 _evas_loader_jp2k_log_dom = -1;
391}
392
393static Evas_Module_Api evas_modapi =
394{
395 EVAS_MODULE_API_VERSION,
396 "jp2k",
397 "none",
398 {
399 module_open,
400 module_close
401 }
402};
403
404EVAS_MODULE_DEFINE(EVAS_MODULE_TYPE_IMAGE_LOADER, image_loader, jp2k);
405
406#ifndef EVAS_STATIC_BUILD_JP2K
407EVAS_EINA_MODULE_DEFINE(image_loader, jp2k);
408#endif
409