move around - flatter.
[profile/ivi/evas.git] / src / modules / savers / jpeg / evas_image_save_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 int evas_image_save_file_jpeg(RGBA_Image *im, const char *file, const char *key, int quality, int compress);
9
10 Evas_Image_Save_Func evas_image_save_jpeg_func =
11 {
12    evas_image_save_file_jpeg
13 };
14
15 struct _JPEG_error_mgr
16 {
17    struct     jpeg_error_mgr pub;
18    jmp_buf    setjmp_buffer;
19 };
20 typedef struct _JPEG_error_mgr *emptr;
21
22 static void _JPEGFatalErrorHandler(j_common_ptr cinfo);
23 static void
24 _JPEGFatalErrorHandler(j_common_ptr cinfo)
25 {
26    emptr errmgr;
27    
28    errmgr = (emptr) cinfo->err;
29    longjmp(errmgr->setjmp_buffer, 1);
30    return;
31 }
32
33 static void _JPEGErrorHandler(j_common_ptr cinfo);
34 static void
35 _JPEGErrorHandler(j_common_ptr cinfo)
36 {
37    emptr errmgr;
38    
39    errmgr = (emptr) cinfo->err;
40    return;
41 }
42
43 static void _JPEGErrorHandler2(j_common_ptr cinfo, int msg_level);
44 static void
45 _JPEGErrorHandler2(j_common_ptr cinfo, int msg_level)
46 {
47    emptr errmgr;
48    
49    errmgr = (emptr) cinfo->err;
50    return;
51    msg_level = 0;
52 }
53
54 static int
55 save_image_jpeg(RGBA_Image *im, const char *file, int quality)
56 {
57    struct _JPEG_error_mgr jerr;
58    struct jpeg_compress_struct cinfo;
59    FILE               *f;
60    DATA8              *buf;
61    DATA32             *ptr;
62    JSAMPROW           *jbuf;
63    int                 y = 0;
64    int                 i, j;
65
66    if (!im || !im->image.data || !file)
67       return 0;
68    
69    buf = alloca(im->cache_entry.w * 3 * sizeof(DATA8));
70    f = fopen(file, "wb");
71    if (!f)
72      {
73         return 0;
74      }
75    jerr.pub.error_exit = _JPEGFatalErrorHandler;
76    jerr.pub.emit_message = _JPEGErrorHandler2;
77    jerr.pub.output_message = _JPEGErrorHandler;
78    cinfo.err = jpeg_std_error(&(jerr.pub));
79    if (sigsetjmp(jerr.setjmp_buffer, 1))
80      {
81         jpeg_destroy_compress(&cinfo);
82         fclose(f);
83         return 0;
84      }
85    jpeg_create_compress(&cinfo);
86    jpeg_stdio_dest(&cinfo, f);
87    cinfo.image_width = im->cache_entry.w;
88    cinfo.image_height = im->cache_entry.h;
89    cinfo.input_components = 3;
90    cinfo.in_color_space = JCS_RGB;
91    jpeg_set_defaults(&cinfo);
92    jpeg_set_quality(&cinfo, quality, TRUE);
93    jpeg_start_compress(&cinfo, TRUE);
94    ptr = im->image.data;
95    while (cinfo.next_scanline < cinfo.image_height)
96      {
97         for (j = 0, i = 0; i < im->cache_entry.w; i++)
98           {
99              buf[j++] = ((*ptr) >> 16) & 0xff;
100              buf[j++] = ((*ptr) >> 8) & 0xff;
101              buf[j++] = ((*ptr)) & 0xff;
102              ptr++;
103           }
104         jbuf = (JSAMPROW *) (&buf);
105         jpeg_write_scanlines(&cinfo, jbuf, 1);
106         y++;
107      }
108    jpeg_finish_compress(&cinfo);
109    jpeg_destroy_compress(&cinfo);
110    fclose(f);
111    return 1;
112 }
113
114 int evas_image_save_file_jpeg(RGBA_Image *im, const char *file, const char *key, int quality, int compress)
115 {
116    return save_image_jpeg(im, file, quality);
117 }
118
119 EAPI int
120 module_open(Evas_Module *em)
121 {
122    if (!em) return 0;
123    em->functions = (void *)(&evas_image_save_jpeg_func);
124    return 1;
125 }
126
127 EAPI void
128 module_close(void)
129 {
130    
131 }
132
133 EAPI Evas_Module_Api evas_modapi =
134 {
135    EVAS_MODULE_API_VERSION,
136      EVAS_MODULE_TYPE_IMAGE_SAVER,
137      "jpeg",
138      "none"
139 };