move around - flatter.
[profile/ivi/evas.git] / src / modules / loaders / jpeg / evas_image_load_jpeg.c
1 #include "evas_common.h"
2 #include "evas_private.h"
3
4 #include <stdio.h>
5 #include <jpeglib.h>
6 #include <setjmp.h>
7
8
9 typedef struct _JPEG_error_mgr *emptr;
10 struct _JPEG_error_mgr
11 {
12    struct     jpeg_error_mgr pub;
13    jmp_buf    setjmp_buffer;
14 };
15
16 static void _JPEGFatalErrorHandler(j_common_ptr cinfo);
17 static void _JPEGErrorHandler(j_common_ptr cinfo);
18 static void _JPEGErrorHandler2(j_common_ptr cinfo, int msg_level);
19
20 static int evas_image_load_file_head_jpeg_internal(Image_Entry *ie, FILE *f);
21 static int evas_image_load_file_data_jpeg_internal(Image_Entry *ie, FILE *f);
22 #if 0 /* not used at the moment */
23 static int evas_image_load_file_data_jpeg_alpha_internal(Image_Entry *ie, FILE *f);
24 #endif
25
26 int evas_image_load_file_head_jpeg(Image_Entry *ie, const char *file, const char *key);
27 int evas_image_load_file_data_jpeg(Image_Entry *ie, const char *file, const char *key);
28
29 Evas_Image_Load_Func evas_image_load_jpeg_func =
30 {
31   evas_image_load_file_head_jpeg,
32   evas_image_load_file_data_jpeg
33 };
34
35
36 static void
37 _JPEGFatalErrorHandler(j_common_ptr cinfo)
38 {
39    emptr errmgr;
40
41    errmgr = (emptr) cinfo->err;
42    /*   cinfo->err->output_message(cinfo);*/
43    longjmp(errmgr->setjmp_buffer, 1);
44    return;
45 }
46
47 static void
48 _JPEGErrorHandler(j_common_ptr cinfo)
49 {
50    emptr errmgr;
51
52    errmgr = (emptr) cinfo->err;
53    /*   cinfo->err->output_message(cinfo);*/
54    /*   longjmp(errmgr->setjmp_buffer, 1);*/
55    return;
56 }
57
58 static void
59 _JPEGErrorHandler2(j_common_ptr cinfo, int msg_level)
60 {
61    emptr errmgr;
62
63    errmgr = (emptr) cinfo->err;
64    /*   cinfo->err->output_message(cinfo);*/
65    /*   longjmp(errmgr->setjmp_buffer, 1);*/
66    return;
67    msg_level = 0;
68 }
69
70 static int
71 evas_image_load_file_head_jpeg_internal(Image_Entry *ie, FILE *f)
72 {
73    int w, h, scalew, scaleh;
74    struct jpeg_decompress_struct cinfo;
75    struct _JPEG_error_mgr jerr;
76
77    if (!f) return 0;
78    cinfo.err = jpeg_std_error(&(jerr.pub));
79    jerr.pub.error_exit = _JPEGFatalErrorHandler;
80    jerr.pub.emit_message = _JPEGErrorHandler2;
81    jerr.pub.output_message = _JPEGErrorHandler;
82    if (setjmp(jerr.setjmp_buffer))
83      {
84         jpeg_destroy_decompress(&cinfo);
85         return 0;
86      }
87    jpeg_create_decompress(&cinfo);
88    jpeg_stdio_src(&cinfo, f);
89    jpeg_read_header(&cinfo, TRUE);
90    cinfo.do_fancy_upsampling = FALSE;
91    cinfo.do_block_smoothing = FALSE;
92    cinfo.dct_method = JDCT_IFAST;
93    cinfo.dither_mode = JDITHER_ORDERED;
94    jpeg_start_decompress(&cinfo);
95
96 /* head decoding */
97    w = cinfo.output_width;
98    h = cinfo.output_height;
99    if ((w < 1) || (h < 1) || (w > 8192) || (h > 8192))
100      {  
101         jpeg_destroy_decompress(&cinfo);
102         return 0;
103      }
104    if (ie->load_opts.scale_down_by > 1)
105      {
106         w /= ie->load_opts.scale_down_by;
107         h /= ie->load_opts.scale_down_by;
108      }
109    else if (ie->load_opts.dpi > 0.0)
110      {
111         w = (w * ie->load_opts.dpi) / 90.0;
112         h = (h * ie->load_opts.dpi) / 90.0;
113      }
114    else if ((ie->load_opts.w > 0) &&
115             (ie->load_opts.h > 0))
116      {
117         int w2, h2;
118         
119         w2 = ie->load_opts.w;
120         h2 = (ie->load_opts.w * h) / w;
121         if (h2 > ie->load_opts.h)
122           {
123              h2 = ie->load_opts.h;
124              w2 = (ie->load_opts.h * w) / h;
125           }
126         w = w2;
127         h = h2;
128      }
129    if (w < 1) w = 1;
130    if (h < 1) h = 1;
131    
132    if ((w != cinfo.output_width) || (h != cinfo.output_height))
133      {
134         scalew = cinfo.output_width / w;
135         scaleh = cinfo.output_height / h;
136         
137         ie->scale = scalew;
138         if (scaleh < scalew) ie->scale = scaleh;
139         
140         if      (ie->scale > 8) ie->scale = 8;
141         else if (ie->scale < 1) ie->scale = 1;
142         
143         if      (ie->scale == 3) ie->scale = 2;
144         else if (ie->scale == 5) ie->scale = 4;
145         else if (ie->scale == 6) ie->scale = 4;
146         else if (ie->scale == 7) ie->scale = 4;
147      }
148
149    if (ie->scale > 1)
150      {
151         jpeg_destroy_decompress(&cinfo);
152    
153         rewind(f);
154         jpeg_create_decompress(&cinfo);
155         jpeg_stdio_src(&cinfo, f);
156         jpeg_read_header(&cinfo, TRUE);
157         cinfo.do_fancy_upsampling = FALSE;
158         cinfo.do_block_smoothing = FALSE;
159         cinfo.scale_num = 1;
160         cinfo.scale_denom = ie->scale;
161         jpeg_calc_output_dimensions(&(cinfo));
162         jpeg_start_decompress(&cinfo);
163      }
164    
165    ie->w = cinfo.output_width;
166    ie->h = cinfo.output_height;
167 /* end head decoding */
168
169    jpeg_destroy_decompress(&cinfo);
170    return 1;
171 }
172
173 static int
174 evas_image_load_file_data_jpeg_internal(Image_Entry *ie, FILE *f)
175 {
176    int w, h;
177    struct jpeg_decompress_struct cinfo;
178    struct _JPEG_error_mgr jerr;
179    DATA8 *ptr, *line[16], *data;
180    DATA32 *ptr2;
181    int x, y, l, i, scans, count, prevy;
182
183    if (!f) return 0;
184    cinfo.err = jpeg_std_error(&(jerr.pub));
185    jerr.pub.error_exit = _JPEGFatalErrorHandler;
186    jerr.pub.emit_message = _JPEGErrorHandler2;
187    jerr.pub.output_message = _JPEGErrorHandler;
188    if (setjmp(jerr.setjmp_buffer))
189      {
190         jpeg_destroy_decompress(&cinfo);
191         return 0;
192      }
193    jpeg_create_decompress(&cinfo);
194    jpeg_stdio_src(&cinfo, f);
195    jpeg_read_header(&cinfo, TRUE);
196    cinfo.do_fancy_upsampling = FALSE;
197    cinfo.do_block_smoothing = FALSE;
198    cinfo.dct_method = JDCT_IFAST;
199    cinfo.dither_mode = JDITHER_ORDERED;
200
201    if (ie->scale > 1)
202      {
203         cinfo.scale_num = 1;
204         cinfo.scale_denom = ie->scale;
205      }
206    
207 /* head decoding */
208    jpeg_calc_output_dimensions(&(cinfo));
209    jpeg_start_decompress(&cinfo);
210    
211    w = cinfo.output_width;
212    h = cinfo.output_height;
213    
214    if ((w != ie->w) || (h != ie->h))
215      {
216         jpeg_destroy_decompress(&cinfo);
217         return 0;
218      }
219    
220 /* end head decoding */
221 /* data decoding */
222    if (cinfo.rec_outbuf_height > 16)
223      {
224         jpeg_destroy_decompress(&cinfo);
225         return 0;
226      }
227    data = alloca(w * 16 * 3);
228    evas_cache_image_surface_alloc(ie, w, h);
229    if (ie->flags.loaded)
230      {
231         jpeg_destroy_decompress(&cinfo);
232         return 0;
233      }
234    ptr2 = evas_cache_image_pixels(ie);
235    count = 0;
236    prevy = 0;
237    if (cinfo.output_components == 3)
238      {
239         for (i = 0; i < cinfo.rec_outbuf_height; i++)
240           line[i] = data + (i * w * 3);
241         for (l = 0; l < h; l += cinfo.rec_outbuf_height)
242           {
243              jpeg_read_scanlines(&cinfo, line, cinfo.rec_outbuf_height);
244              scans = cinfo.rec_outbuf_height;
245              if ((h - l) < scans) scans = h - l;
246              ptr = data;
247              for (y = 0; y < scans; y++)
248                {
249                   for (x = 0; x < w; x++)
250                     {
251                        *ptr2 =
252                          (0xff000000) | ((ptr[0]) << 16) | ((ptr[1]) << 8) | (ptr[2]);
253                        ptr += 3;
254                        ptr2++;
255                     }
256                }
257           }
258      }
259    else if (cinfo.output_components == 1)
260      {
261         for (i = 0; i < cinfo.rec_outbuf_height; i++)
262           line[i] = data + (i * w);
263         for (l = 0; l < h; l += cinfo.rec_outbuf_height)
264           {
265              jpeg_read_scanlines(&cinfo, line, cinfo.rec_outbuf_height);
266              scans = cinfo.rec_outbuf_height;
267              if ((h - l) < scans) scans = h - l;
268              ptr = data;
269              for (y = 0; y < scans; y++)
270                {
271                   for (x = 0; x < w; x++)
272                     {
273                        *ptr2 =
274                          (0xff000000) | ((ptr[0]) << 16) | ((ptr[0]) << 8) | (ptr[0]);
275                        ptr++;
276                        ptr2++;
277                     }
278                }
279           }
280      }
281 /* end data decoding */
282    jpeg_finish_decompress(&cinfo);
283    jpeg_destroy_decompress(&cinfo);
284    return 1;
285 }
286
287 #if 0 /* not used at the moment */
288 static int
289 evas_image_load_file_data_jpeg_alpha_internal(Image_Entry *ie, FILE *f)
290 {
291    int w, h;
292    struct jpeg_decompress_struct cinfo;
293    struct _JPEG_error_mgr jerr;
294    DATA8 *ptr, *line[16], *data;
295    DATA32 *ptr2;
296    int x, y, l, i, scans, count, prevy;
297
298    if (!f) return 0;
299    cinfo.err = jpeg_std_error(&(jerr.pub));
300    jerr.pub.error_exit = _JPEGFatalErrorHandler;
301    jerr.pub.emit_message = _JPEGErrorHandler2;
302    jerr.pub.output_message = _JPEGErrorHandler;
303    if (setjmp(jerr.setjmp_buffer))
304      {
305         jpeg_destroy_decompress(&cinfo);
306         return 0;
307      }
308    jpeg_create_decompress(&cinfo);
309    jpeg_stdio_src(&cinfo, f);
310    jpeg_read_header(&cinfo, TRUE);
311    cinfo.do_fancy_upsampling = FALSE;
312    cinfo.do_block_smoothing = FALSE;
313    jpeg_start_decompress(&cinfo);
314
315 /* head decoding */
316    ie->w = w = cinfo.output_width;
317    ie->h = h = cinfo.output_height;
318 /* end head decoding */
319 /* data decoding */
320    if (cinfo.rec_outbuf_height > 16)
321      {
322         jpeg_destroy_decompress(&cinfo);
323         return 0;
324      }
325    data = alloca(w * 16 * 3);
326    if (!ie->flags.loaded)
327      {
328         jpeg_destroy_decompress(&cinfo);
329         return 0;
330      }
331    ptr2 = evas_cache_image_pixels(ie);
332    count = 0;
333    prevy = 0;
334    if (cinfo.output_components == 3)
335      {
336         for (i = 0; i < cinfo.rec_outbuf_height; i++)
337           line[i] = data + (i * w * 3);
338         for (l = 0; l < h; l += cinfo.rec_outbuf_height)
339           {
340              jpeg_read_scanlines(&cinfo, line, cinfo.rec_outbuf_height);
341              scans = cinfo.rec_outbuf_height;
342              if ((h - l) < scans) scans = h - l;
343              ptr = data;
344              for (y = 0; y < scans; y++)
345                {
346                   for (x = 0; x < w; x++)
347                     {
348                        *ptr2 =
349                          ((*ptr2) & 0x00ffffff) |
350                          (((ptr[0] + ptr[1] + ptr[2]) / 3) << 24);
351                        ptr += 3;
352                        ptr2++;
353                     }
354                }
355           }
356      }
357    else if (cinfo.output_components == 1)
358      {
359         for (i = 0; i < cinfo.rec_outbuf_height; i++)
360           line[i] = data + (i * w);
361         for (l = 0; l < h; l += cinfo.rec_outbuf_height)
362           {
363              jpeg_read_scanlines(&cinfo, line, cinfo.rec_outbuf_height);
364              scans = cinfo.rec_outbuf_height;
365              if ((h - l) < scans) scans = h - l;
366              ptr = data;
367              for (y = 0; y < scans; y++)
368                {
369                   for (x = 0; x < w; x++)
370                     {
371                        *ptr2 =
372                          ((*ptr2) & 0x00ffffff) |
373                          ((ptr[0]) << 24);
374                        ptr++;
375                        ptr2++;
376                     }
377                }
378           }
379      }
380 /* end data decoding */
381    jpeg_finish_decompress(&cinfo);
382    jpeg_destroy_decompress(&cinfo);
383    return 1;
384 }
385 #endif
386
387 int
388 evas_image_load_file_head_jpeg(Image_Entry *ie, const char *file, const char *key)
389 {
390    int val;
391    FILE *f;
392
393    if ((!file)) return 0;
394    f = fopen(file, "rb");
395    if (!f) return 0;
396    val = evas_image_load_file_head_jpeg_internal(ie, f);
397    fclose(f);
398    return val;
399    key = 0;
400 }
401
402 int
403 evas_image_load_file_data_jpeg(Image_Entry *ie, const char *file, const char *key)
404 {
405    int val;
406    FILE *f;
407
408    if ((!file)) return 0;
409    f = fopen(file, "rb");
410    if (!f) return 0;
411    val = evas_image_load_file_data_jpeg_internal(ie, f);
412    fclose(f);
413    return val;
414    key = 0;
415 }
416
417 EAPI int
418 module_open(Evas_Module *em)
419 {
420    if (!em) return 0;
421    em->functions = (void *)(&evas_image_load_jpeg_func);
422    return 1;
423 }
424
425 EAPI void
426 module_close(void)
427 {
428    
429 }
430
431 EAPI Evas_Module_Api evas_modapi =
432 {
433    EVAS_MODULE_API_VERSION,
434      EVAS_MODULE_TYPE_IMAGE_LOADER,
435      "jpeg",
436      "none"
437 };