Evas: Fix compilation with libjpeg 8 on Windows.
[profile/ivi/evas.git] / src / modules / loaders / jpeg / evas_image_load_jpeg.c
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 <setjmp.h>
12 #include <jpeglib.h>
13
14 #include "evas_common.h"
15 #include "evas_private.h"
16
17
18 typedef struct _JPEG_error_mgr *emptr;
19 struct _JPEG_error_mgr
20 {
21    struct     jpeg_error_mgr pub;
22    jmp_buf    setjmp_buffer;
23 };
24
25 static void _JPEGFatalErrorHandler(j_common_ptr cinfo);
26 static void _JPEGErrorHandler(j_common_ptr cinfo);
27 static void _JPEGErrorHandler2(j_common_ptr cinfo, int msg_level);
28
29 static Eina_Bool evas_image_load_file_head_jpeg_internal(Image_Entry *ie, FILE *f, int *error) EINA_ARG_NONNULL(1, 2, 3);
30 static Eina_Bool evas_image_load_file_data_jpeg_internal(Image_Entry *ie, FILE *f, int *error) EINA_ARG_NONNULL(1, 2, 3);
31 #if 0 /* not used at the moment */
32 static int evas_image_load_file_data_jpeg_alpha_internal(Image_Entry *ie, FILE *f) EINA_ARG_NONNULL(1, 2);
33 #endif
34
35 static Eina_Bool evas_image_load_file_head_jpeg(Image_Entry *ie, const char *file, const char *key, int *error) EINA_ARG_NONNULL(1, 2, 4);
36 static Eina_Bool evas_image_load_file_data_jpeg(Image_Entry *ie, const char *file, const char *key, int *error) EINA_ARG_NONNULL(1, 2, 4);
37
38 static Evas_Image_Load_Func evas_image_load_jpeg_func =
39 {
40   EINA_TRUE,
41   evas_image_load_file_head_jpeg,
42   evas_image_load_file_data_jpeg
43 };
44
45
46 static void
47 _JPEGFatalErrorHandler(j_common_ptr cinfo)
48 {
49    emptr errmgr;
50
51    errmgr = (emptr) cinfo->err;
52    /*   cinfo->err->output_message(cinfo);*/
53    longjmp(errmgr->setjmp_buffer, 1);
54    return;
55 }
56
57 static void
58 _JPEGErrorHandler(j_common_ptr cinfo __UNUSED__)
59 {
60 /*    emptr errmgr; */
61
62 /*    errmgr = (emptr) cinfo->err; */
63    /*   cinfo->err->output_message(cinfo);*/
64    /*   longjmp(errmgr->setjmp_buffer, 1);*/
65    return;
66 }
67
68 static void
69 _JPEGErrorHandler2(j_common_ptr cinfo __UNUSED__, int msg_level __UNUSED__)
70 {
71 /*    emptr errmgr; */
72
73 /*    errmgr = (emptr) cinfo->err; */
74    /*   cinfo->err->output_message(cinfo);*/
75    /*   longjmp(errmgr->setjmp_buffer, 1);*/
76    return;
77 }
78
79 static Eina_Bool
80 evas_image_load_file_head_jpeg_internal(Image_Entry *ie, FILE *f, int *error)
81 {
82    unsigned int w, h, scalew, scaleh;
83    struct jpeg_decompress_struct cinfo;
84    struct _JPEG_error_mgr jerr;
85
86    cinfo.err = jpeg_std_error(&(jerr.pub));
87    jerr.pub.error_exit = _JPEGFatalErrorHandler;
88    jerr.pub.emit_message = _JPEGErrorHandler2;
89    jerr.pub.output_message = _JPEGErrorHandler;
90    if (setjmp(jerr.setjmp_buffer))
91      {
92         jpeg_destroy_decompress(&cinfo);
93         if (cinfo.saw_JFIF_marker)
94           *error = EVAS_LOAD_ERROR_CORRUPT_FILE;
95         else
96           *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
97         return EINA_FALSE;
98      }
99    jpeg_create_decompress(&cinfo);
100    jpeg_stdio_src(&cinfo, f);
101    jpeg_read_header(&cinfo, TRUE);
102    cinfo.do_fancy_upsampling = FALSE;
103    cinfo.do_block_smoothing = FALSE;
104    cinfo.dct_method = JDCT_IFAST;
105    cinfo.dither_mode = JDITHER_ORDERED;
106    jpeg_start_decompress(&cinfo);
107
108 /* head decoding */
109    w = cinfo.output_width;
110    h = cinfo.output_height;
111    if ((w < 1) || (h < 1) || (w > IMG_MAX_SIZE) || (h > IMG_MAX_SIZE) ||
112        (IMG_TOO_BIG(w, h)))
113      {
114         jpeg_destroy_decompress(&cinfo);
115         if (IMG_TOO_BIG(w, h))
116           *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
117         else
118           *error = EVAS_LOAD_ERROR_GENERIC;
119         return EINA_FALSE;
120      }
121    if (ie->load_opts.scale_down_by > 1)
122      {
123         w /= ie->load_opts.scale_down_by;
124         h /= ie->load_opts.scale_down_by;
125      }
126    else if (ie->load_opts.dpi > 0.0)
127      {
128         w = (w * ie->load_opts.dpi) / 90.0;
129         h = (h * ie->load_opts.dpi) / 90.0;
130      }
131    else if ((ie->load_opts.w > 0) && (ie->load_opts.h > 0))
132      {
133         unsigned int w2 = w, h2 = h;
134         if (ie->load_opts.w > 0)
135           {
136              w2 = ie->load_opts.w;
137              h2 = (ie->load_opts.w * h) / w;
138              if ((ie->load_opts.h > 0) && (h2 > ie->load_opts.h))
139                {
140                   unsigned int w3;
141                   h2 = ie->load_opts.h;
142                   w3 = (ie->load_opts.h * w) / h;
143                   if (w3 > w2)
144                     w2 = w3;
145                }
146           }
147         else if (ie->load_opts.h > 0)
148           {
149              h2 = ie->load_opts.h;
150              w2 = (ie->load_opts.h * w) / h;
151           }
152         w = w2;
153         h = h2;
154      }
155    if (w < 1) w = 1;
156    if (h < 1) h = 1;
157
158    if ((w != cinfo.output_width) || (h != cinfo.output_height))
159      {
160         scalew = cinfo.output_width / w;
161         scaleh = cinfo.output_height / h;
162
163         ie->scale = scalew;
164         if (scaleh < scalew) ie->scale = scaleh;
165
166         if      (ie->scale > 8) ie->scale = 8;
167         else if (ie->scale < 1) ie->scale = 1;
168
169         if      (ie->scale == 3) ie->scale = 2;
170         else if (ie->scale == 5) ie->scale = 4;
171         else if (ie->scale == 6) ie->scale = 4;
172         else if (ie->scale == 7) ie->scale = 4;
173      }
174
175    if (ie->scale > 1)
176      {
177         jpeg_destroy_decompress(&cinfo);
178         rewind(f);
179         jpeg_create_decompress(&cinfo);
180         jpeg_stdio_src(&cinfo, f);
181         jpeg_read_header(&cinfo, TRUE);
182         cinfo.do_fancy_upsampling = FALSE;
183         cinfo.do_block_smoothing = FALSE;
184         cinfo.scale_num = 1;
185         cinfo.scale_denom = ie->scale;
186         jpeg_calc_output_dimensions(&(cinfo));
187         jpeg_start_decompress(&cinfo);
188      }
189
190    ie->w = cinfo.output_width;
191    ie->h = cinfo.output_height;
192    
193    // be nice and clip region to image. if its totally outside, fail load
194    if ((ie->load_opts.region.w > 0) && (ie->load_opts.region.h > 0))
195      {
196         RECTS_CLIP_TO_RECT(ie->load_opts.region.x, ie->load_opts.region.y,
197                            ie->load_opts.region.w, ie->load_opts.region.h,
198                            0, 0, ie->w, ie->h);
199         if ((ie->load_opts.region.w <= 0) || (ie->load_opts.region.h <= 0))
200           {
201              jpeg_destroy_decompress(&cinfo);
202              *error = EVAS_LOAD_ERROR_GENERIC;
203              return EINA_FALSE;
204           }
205         ie->w = ie->load_opts.region.w;
206         ie->h = ie->load_opts.region.h;
207      }
208 /* end head decoding */
209
210    jpeg_destroy_decompress(&cinfo);
211    *error = EVAS_LOAD_ERROR_NONE;
212    return EINA_TRUE;
213 }
214
215 /*
216 static double
217 get_time(void)
218 {
219    struct timeval      timev;
220    
221    gettimeofday(&timev, NULL);
222    return (double)timev.tv_sec + (((double)timev.tv_usec) / 1000000);
223 }
224 */
225
226 static Eina_Bool
227 evas_image_load_file_data_jpeg_internal(Image_Entry *ie, FILE *f, int *error)
228 {
229    unsigned int w, h;
230    struct jpeg_decompress_struct cinfo;
231    struct _JPEG_error_mgr jerr;
232    DATA8 *ptr, *line[16], *data;
233    DATA32 *ptr2;
234    unsigned int x, y, l, i, scans;
235    int region = 0;
236
237    cinfo.err = jpeg_std_error(&(jerr.pub));
238    jerr.pub.error_exit = _JPEGFatalErrorHandler;
239    jerr.pub.emit_message = _JPEGErrorHandler2;
240    jerr.pub.output_message = _JPEGErrorHandler;
241    if (setjmp(jerr.setjmp_buffer))
242      {
243         jpeg_destroy_decompress(&cinfo);
244         *error = EVAS_LOAD_ERROR_CORRUPT_FILE;
245         return EINA_FALSE;
246      }
247    jpeg_create_decompress(&cinfo);
248    jpeg_stdio_src(&cinfo, f);
249    jpeg_read_header(&cinfo, TRUE);
250    cinfo.do_fancy_upsampling = FALSE;
251    cinfo.do_block_smoothing = FALSE;
252    cinfo.dct_method = JDCT_IFAST;
253    cinfo.dither_mode = JDITHER_ORDERED;
254
255    if (ie->scale > 1)
256      {
257         cinfo.scale_num = 1;
258         cinfo.scale_denom = ie->scale;
259      }
260
261    /* Colorspace conversion options */
262    /* libjpeg can do the following conversions: */
263    /* GRAYSCLAE => RGB YCbCr => RGB and YCCK => CMYK */
264    switch (cinfo.jpeg_color_space)
265      {
266      case JCS_UNKNOWN:
267        break;
268      case JCS_GRAYSCALE:
269      case JCS_RGB:
270      case JCS_YCbCr:
271        cinfo.out_color_space = JCS_RGB;
272        break;
273      case JCS_CMYK:
274      case JCS_YCCK:
275        cinfo.out_color_space = JCS_CMYK;
276        break;
277      }
278
279 /* head decoding */
280    jpeg_calc_output_dimensions(&(cinfo));
281    jpeg_start_decompress(&cinfo);
282
283    w = cinfo.output_width;
284    h = cinfo.output_height;
285
286    if ((ie->load_opts.region.w > 0) && (ie->load_opts.region.h > 0))
287      {
288         region = 1;
289 #ifdef BUILD_LOADER_JPEG_REGION
290         cinfo.region_x = ie->load_opts.region.x;
291         cinfo.region_y = ie->load_opts.region.y;
292         cinfo.region_w = ie->load_opts.region.w;
293         cinfo.region_h = ie->load_opts.region.h;
294 #endif
295      }
296    if ((!region) && ((w != ie->w) || (h != ie->h)))
297      {
298         // race condition, the file could have change from when we call header
299         // this test will not solve the problem with region code.
300         jpeg_destroy_decompress(&cinfo);
301         *error = EVAS_LOAD_ERROR_GENERIC;
302         return EINA_FALSE;
303      }
304    if ((region) &&
305        ((ie->w != ie->load_opts.region.w) || (ie->h != ie->load_opts.region.h)))
306      {
307         ie->w = ie->load_opts.region.w;
308         ie->h = ie->load_opts.region.h;
309      }
310
311    if (!(((cinfo.out_color_space == JCS_RGB) &&
312           ((cinfo.output_components == 3) || (cinfo.output_components == 1))) ||
313          ((cinfo.out_color_space == JCS_CMYK) && (cinfo.output_components == 4))))
314      {
315         jpeg_destroy_decompress(&cinfo);
316         *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
317         return EINA_FALSE;
318      }
319
320 /* end head decoding */
321 /* data decoding */
322    if (cinfo.rec_outbuf_height > 16)
323      {
324         jpeg_destroy_decompress(&cinfo);
325         *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
326         return EINA_FALSE;
327      }
328    data = alloca(w * 16 * cinfo.output_components);
329    evas_cache_image_surface_alloc(ie, ie->w, ie->h);
330    if (ie->flags.loaded)
331      {
332         jpeg_destroy_decompress(&cinfo);
333         *error = EVAS_LOAD_ERROR_NONE;
334         return EINA_TRUE;
335      }
336    ptr2 = evas_cache_image_pixels(ie);
337    if (!ptr2)
338      {
339         *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
340         return EINA_FALSE;
341      }
342
343    /* We handle first CMYK (4 components) */
344    if (cinfo.output_components == 4)
345      {
346         // FIXME: handle region
347         for (i = 0; (int)i < cinfo.rec_outbuf_height; i++)
348           line[i] = data + (i * w * 4);
349         for (l = 0; l < h; l += cinfo.rec_outbuf_height)
350           {
351              jpeg_read_scanlines(&cinfo, line, cinfo.rec_outbuf_height);
352              scans = cinfo.rec_outbuf_height;
353              if ((h - l) < scans) scans = h - l;
354              ptr = data;
355              if (!region)
356                {
357                   for (y = 0; y < scans; y++)
358                     {
359                        if (cinfo.saw_Adobe_marker)
360                          {
361                             for (x = 0; x < w; x++)
362                               {
363                                  /* According to libjpeg doc, Photoshop inverse the values of C, M, Y and K, */
364                                  /* that is C is replaces by 255 - C, etc...*/
365                                  /* See the comment below for the computation of RGB values from CMYK ones. */
366                                  *ptr2 =
367                                    (0xff000000) |
368                                    ((ptr[0] * ptr[3] / 255) << 16) |
369                                    ((ptr[1] * ptr[3] / 255) << 8) |
370                                    ((ptr[2] * ptr[3] / 255));
371                                  ptr += 4;
372                                  ptr2++;
373                               }
374                          }
375                        else
376                          {
377                             for (x = 0; x < w; x++)
378                               {
379                                  /* Conversion from CMYK to RGB is done in 2 steps: */
380                                  /* CMYK => CMY => RGB (see http://www.easyrgb.com/index.php?X=MATH) */
381                                  /* after computation, if C, M, Y and K are between 0 and 1, we have: */
382                                  /* R = (1 - C) * (1 - K) * 255 */
383                                  /* G = (1 - M) * (1 - K) * 255 */
384                                  /* B = (1 - Y) * (1 - K) * 255 */
385                                  /* libjpeg stores CMYK values between 0 and 255, */
386                                  /* so we replace C by C * 255 / 255, etc... and we obtain: */
387                                  /* R = (255 - C) * (255 - K) / 255 */
388                                  /* G = (255 - M) * (255 - K) / 255 */
389                                  /* B = (255 - Y) * (255 - K) / 255 */
390                                  /* with C, M, Y and K between 0 and 255. */
391                                  *ptr2 =
392                                    (0xff000000) |
393                                    (((255 - ptr[0]) * (255 - ptr[3]) / 255) << 16) |
394                                    (((255 - ptr[1]) * (255 - ptr[3]) / 255) << 8) |
395                                    (((255 - ptr[2]) * (255 - ptr[3]) / 255));
396                                  ptr += 4;
397                                  ptr2++;
398                               }
399                          }
400                     }
401                }
402              else
403                {
404                   // if line # > region last line, break
405                   if (l >= (ie->load_opts.region.y + ie->load_opts.region.h))
406                     {
407                        jpeg_destroy_decompress(&cinfo);
408                        *error = EVAS_LOAD_ERROR_NONE;
409                        return EINA_FALSE;
410                     }
411                   // els if scan block intersects region start or later
412                   else if ((l + scans) > 
413                            (ie->load_opts.region.y))
414                     {
415                        for (y = 0; y < scans; y++)
416                          {
417                             if (((y + l) >= ie->load_opts.region.y) &&
418                                 ((y + l) < (ie->load_opts.region.y + ie->load_opts.region.h)))
419                               {
420                                  ptr += ie->load_opts.region.x;
421                                  if (cinfo.saw_Adobe_marker)
422                                    {
423                                       for (x = 0; x < ie->load_opts.region.w; x++)
424                                         {
425                                            /* According to libjpeg doc, Photoshop inverse the values of C, M, Y and K, */
426                                            /* that is C is replaces by 255 - C, etc...*/
427                                            /* See the comment below for the computation of RGB values from CMYK ones. */
428                                            *ptr2 =
429                                              (0xff000000) |
430                                              ((ptr[0] * ptr[3] / 255) << 16) |
431                                              ((ptr[1] * ptr[3] / 255) << 8) |
432                                              ((ptr[2] * ptr[3] / 255));
433                                            ptr += 4;
434                                            ptr2++;
435                                         }
436                                    }
437                                  else
438                                    {
439                                       for (x = 0; x < ie->load_opts.region.w; x++)
440                                         {
441                                            /* Conversion from CMYK to RGB is done in 2 steps: */
442                                            /* CMYK => CMY => RGB (see http://www.easyrgb.com/index.php?X=MATH) */
443                                            /* after computation, if C, M, Y and K are between 0 and 1, we have: */
444                                            /* R = (1 - C) * (1 - K) * 255 */
445                                            /* G = (1 - M) * (1 - K) * 255 */
446                                            /* B = (1 - Y) * (1 - K) * 255 */
447                                            /* libjpeg stores CMYK values between 0 and 255, */
448                                            /* so we replace C by C * 255 / 255, etc... and we obtain: */
449                                            /* R = (255 - C) * (255 - K) / 255 */
450                                            /* G = (255 - M) * (255 - K) / 255 */
451                                            /* B = (255 - Y) * (255 - K) / 255 */
452                                            /* with C, M, Y and K between 0 and 255. */
453                                            *ptr2 =
454                                              (0xff000000) |
455                                              (((255 - ptr[0]) * (255 - ptr[3]) / 255) << 16) |
456                                              (((255 - ptr[1]) * (255 - ptr[3]) / 255) << 8) |
457                                              (((255 - ptr[2]) * (255 - ptr[3]) / 255));
458                                            ptr += 4;
459                                            ptr2++;
460                                         }
461                                    }
462                                  ptr += (4 * (w - (ie->load_opts.region.x + ie->load_opts.region.w)));
463                               }
464                             else
465                               ptr += (4 * w);
466                          }
467                     }
468                }
469           }
470      }
471    /* We handle then RGB with 3 components */
472    else if (cinfo.output_components == 3)
473      {
474 /*        
475         double t;
476         if (region)
477           {
478              // debug for now
479              printf("R| %p %5ix%5i %s: %5i %5i %5ix%5i - ",
480                     ie,
481                     ie->w, ie->h,
482                     ie->file,
483                     ie->load_opts.region.x,
484                     ie->load_opts.region.y,
485                     ie->load_opts.region.w,
486                     ie->load_opts.region.h);
487           }
488         t = get_time();
489  */
490         for (i = 0; (int)i < cinfo.rec_outbuf_height; i++)
491           line[i] = data + (i * w * 3);
492         for (l = 0; l < h; l += cinfo.rec_outbuf_height)
493           {
494              jpeg_read_scanlines(&cinfo, line, cinfo.rec_outbuf_height);
495              scans = cinfo.rec_outbuf_height;
496              if ((h - l) < scans) scans = h - l;
497              ptr = data;
498              if (!region)
499                {
500                   for (y = 0; y < scans; y++)
501                     {
502                        for (x = 0; x < w; x++)
503                          {
504                             *ptr2 = ARGB_JOIN(0xff, ptr[0], ptr[1], ptr[2]);
505                             ptr += 3;
506                             ptr2++;
507                          }
508                     }
509                }
510              else
511                {
512                   // if line # > region last line, break
513                   if (l >= (ie->load_opts.region.y + ie->load_opts.region.h))
514                     {
515                        jpeg_destroy_decompress(&cinfo);
516 /*                       
517                        t = get_time() - t;
518                        printf("%3.3f\n", t);
519  */ 
520                        *error = EVAS_LOAD_ERROR_NONE;
521                        return EINA_TRUE;
522                     }
523                   // else if scan block intersects region start or later
524                   else if ((l + scans) > 
525                            (ie->load_opts.region.y))
526                     {
527                        for (y = 0; y < scans; y++)
528                          {
529                             if (((y + l) >= ie->load_opts.region.y) &&
530                                 ((y + l) < (ie->load_opts.region.y + ie->load_opts.region.h)))
531                               {
532                                  ptr += (3 * ie->load_opts.region.x);
533                                  for (x = 0; x < ie->load_opts.region.w; x++)
534                                    {
535                                       *ptr2 = ARGB_JOIN(0xff, ptr[0], ptr[1], ptr[2]);
536                                       ptr += 3;
537                                       ptr2++;
538                                    }
539                                  ptr += (3 * (w - (ie->load_opts.region.x + ie->load_opts.region.w)));
540                               }
541                             else
542                               ptr += (3 * w);
543                          }
544                     }
545                }
546           }
547 /*        
548         t = get_time() - t;
549         printf("%3.3f\n", t);
550  */
551      }
552    /* We finally handle RGB with 1 component */
553    else if (cinfo.output_components == 1)
554      {
555         for (i = 0; (int)i < cinfo.rec_outbuf_height; i++)
556           line[i] = data + (i * w);
557         for (l = 0; l < h; l += cinfo.rec_outbuf_height)
558           {
559              jpeg_read_scanlines(&cinfo, line, cinfo.rec_outbuf_height);
560              scans = cinfo.rec_outbuf_height;
561              if ((h - l) < scans) scans = h - l;
562              ptr = data;
563              if (!region)
564                {
565                   for (y = 0; y < scans; y++)
566                     {
567                        for (x = 0; x < w; x++)
568                          {
569                             *ptr2 = ARGB_JOIN(0xff, ptr[0], ptr[0], ptr[0]);
570                             ptr++;
571                             ptr2++;
572                          }
573                     }
574                }
575              else
576                {
577                   // if line # > region last line, break
578                   if (l >= (ie->load_opts.region.y + ie->load_opts.region.h))
579                     {
580                        jpeg_destroy_decompress(&cinfo);
581                        *error = EVAS_LOAD_ERROR_NONE;
582                        return EINA_TRUE;
583                     }
584                   // els if scan block intersects region start or later
585                   else if ((l + scans) > 
586                            (ie->load_opts.region.y))
587                     {
588                        for (y = 0; y < scans; y++)
589                          {
590                             if (((y + l) >= ie->load_opts.region.y) &&
591                                 ((y + l) < (ie->load_opts.region.y + ie->load_opts.region.h)))
592                               {
593                                  ptr += ie->load_opts.region.x;
594                                  for (x = 0; x < ie->load_opts.region.w; x++)
595                                    {
596                                       *ptr2 = ARGB_JOIN(0xff, ptr[0], ptr[0], ptr[0]);
597                                       ptr++;
598                                       ptr2++;
599                                    }
600                                  ptr += w - (ie->load_opts.region.x + ie->load_opts.region.w);
601                               }
602                             else
603                               ptr += w;
604                          }
605                     }
606                }
607           }
608      }
609 /* end data decoding */
610    jpeg_finish_decompress(&cinfo);
611    jpeg_destroy_decompress(&cinfo);
612    *error = EVAS_LOAD_ERROR_NONE;
613    return EINA_TRUE;
614 }
615
616 #if 0 /* not used at the moment */
617 static Eina_Bool
618 evas_image_load_file_data_jpeg_alpha_internal(Image_Entry *ie, FILE *f, int *error)
619 {
620    int w, h;
621    struct jpeg_decompress_struct cinfo;
622    struct _JPEG_error_mgr jerr;
623    DATA8 *ptr, *line[16], *data;
624    DATA32 *ptr2;
625    int x, y, l, i, scans, prevy;
626
627    if (!f)
628      {
629         *error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
630         return EINA_FALSE;
631      }
632    cinfo.err = jpeg_std_error(&(jerr.pub));
633    jerr.pub.error_exit = _JPEGFatalErrorHandler;
634    jerr.pub.emit_message = _JPEGErrorHandler2;
635    jerr.pub.output_message = _JPEGErrorHandler;
636    if (setjmp(jerr.setjmp_buffer))
637      {
638         jpeg_destroy_decompress(&cinfo);
639         *error = EVAS_LOAD_ERROR_CORRUPT_FILE;
640         return EINA_FALSE;
641      }
642    jpeg_create_decompress(&cinfo);
643    jpeg_stdio_src(&cinfo, f);
644    jpeg_read_header(&cinfo, TRUE);
645    cinfo.do_fancy_upsampling = FALSE;
646    cinfo.do_block_smoothing = FALSE;
647    jpeg_start_decompress(&cinfo);
648
649 /* head decoding */
650    ie->w = w = cinfo.output_width;
651    ie->h = h = cinfo.output_height;
652 /* end head decoding */
653 /* data decoding */
654    if (cinfo.rec_outbuf_height > 16)
655      {
656         jpeg_destroy_decompress(&cinfo);
657         *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
658         return EINA_FALSE;;
659      }
660    data = alloca(w * 16 * 3);
661    if (!ie->flags.loaded)
662      {
663         jpeg_destroy_decompress(&cinfo);
664         *error = EVAS_LOAD_ERROR_NONE;
665         return EINA_TRUE;
666      }
667    ptr2 = evas_cache_image_pixels(ie);
668    prevy = 0;
669    if (cinfo.output_components == 3)
670      {
671         for (i = 0; i < cinfo.rec_outbuf_height; i++)
672           line[i] = data + (i * w * 3);
673         for (l = 0; l < h; l += cinfo.rec_outbuf_height)
674           {
675              jpeg_read_scanlines(&cinfo, line, cinfo.rec_outbuf_height);
676              scans = cinfo.rec_outbuf_height;
677              if ((h - l) < scans) scans = h - l;
678              ptr = data;
679              for (y = 0; y < scans; y++)
680                {
681                   for (x = 0; x < w; x++)
682                     {
683                        *ptr2 =
684                          ((*ptr2) & 0x00ffffff) |
685                          (((ptr[0] + ptr[1] + ptr[2]) / 3) << 24);
686                        ptr += 3;
687                        ptr2++;
688                     }
689                }
690           }
691      }
692    else if (cinfo.output_components == 1)
693      {
694         for (i = 0; i < cinfo.rec_outbuf_height; i++)
695           line[i] = data + (i * w);
696         for (l = 0; l < h; l += cinfo.rec_outbuf_height)
697           {
698              jpeg_read_scanlines(&cinfo, line, cinfo.rec_outbuf_height);
699              scans = cinfo.rec_outbuf_height;
700              if ((h - l) < scans) scans = h - l;
701              ptr = data;
702              for (y = 0; y < scans; y++)
703                {
704                   for (x = 0; x < w; x++)
705                     {
706                        *ptr2 =
707                          ((*ptr2) & 0x00ffffff) |
708                          ((ptr[0]) << 24);
709                        ptr++;
710                        ptr2++;
711                     }
712                }
713           }
714      }
715 /* end data decoding */
716    jpeg_finish_decompress(&cinfo);
717    jpeg_destroy_decompress(&cinfo);
718    *error = EVAS_LOAD_ERROR_NONE;
719    return EINA_TRUE;
720 }
721 #endif
722
723 static Eina_Bool
724 evas_image_load_file_head_jpeg(Image_Entry *ie, const char *file, const char *key, int *error)
725 {
726    int val;
727    FILE *f;
728
729    f = fopen(file, "rb");
730    if (!f)
731      {
732         *error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
733         return EINA_FALSE;
734      }
735    val = evas_image_load_file_head_jpeg_internal(ie, f, error);
736    fclose(f);
737    return val;
738    key = 0;
739 }
740
741 static Eina_Bool
742 evas_image_load_file_data_jpeg(Image_Entry *ie, const char *file, const char *key, int *error)
743 {
744    int val;
745    FILE *f;
746
747    f = fopen(file, "rb");
748    if (!f)
749      {
750         *error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
751         return EINA_FALSE;
752      }
753    val = evas_image_load_file_data_jpeg_internal(ie, f, error);
754    fclose(f);
755    return val;
756    key = 0;
757 }
758
759 static int
760 module_open(Evas_Module *em)
761 {
762    if (!em) return 0;
763    em->functions = (void *)(&evas_image_load_jpeg_func);
764    return 1;
765 }
766
767 static void
768 module_close(Evas_Module *em __UNUSED__)
769 {
770 }
771
772 static Evas_Module_Api evas_modapi =
773 {
774    EVAS_MODULE_API_VERSION,
775    "jpeg",
776    "none",
777    {
778      module_open,
779      module_close
780    }
781 };
782
783 EVAS_MODULE_DEFINE(EVAS_MODULE_TYPE_IMAGE_LOADER, image_loader, jpeg);
784
785 #ifndef EVAS_STATIC_BUILD_JPEG
786 EVAS_EINA_MODULE_DEFINE(image_loader, jpeg);
787 #endif
788