1 #include "evas_common.h"
2 #include "evas_private.h"
8 static int evas_image_save_file_jpeg(RGBA_Image *im, const char *file, const char *key, int quality, int compress);
10 static Evas_Image_Save_Func evas_image_save_jpeg_func =
12 evas_image_save_file_jpeg
15 struct _JPEG_error_mgr
17 struct jpeg_error_mgr pub;
18 jmp_buf setjmp_buffer;
20 typedef struct _JPEG_error_mgr *emptr;
22 static void _JPEGFatalErrorHandler(j_common_ptr cinfo);
24 _JPEGFatalErrorHandler(j_common_ptr cinfo)
28 errmgr = (emptr) cinfo->err;
29 longjmp(errmgr->setjmp_buffer, 1);
34 _JPEGErrorHandler(j_common_ptr cinfo __UNUSED__)
38 /* errmgr = (emptr) cinfo->err; */
43 _JPEGErrorHandler2(j_common_ptr cinfo __UNUSED__, int msg_level __UNUSED__)
47 /* errmgr = (emptr) cinfo->err; */
52 save_image_jpeg(RGBA_Image *im, const char *file, int quality)
54 struct jpeg_compress_struct cinfo;
55 struct _JPEG_error_mgr jerr;
62 if (!im || !im->image.data || !file)
65 buf = alloca(im->cache_entry.w * 3 * sizeof(DATA8));
66 f = fopen(file, "wb");
71 memset(&cinfo, 0, sizeof(cinfo));
72 cinfo.err = jpeg_std_error(&(jerr.pub));
73 jerr.pub.error_exit = _JPEGFatalErrorHandler;
74 jerr.pub.emit_message = _JPEGErrorHandler2;
75 jerr.pub.output_message = _JPEGErrorHandler;
76 if (sigsetjmp(jerr.setjmp_buffer, 1))
78 jpeg_destroy_compress(&cinfo);
82 jpeg_create_compress(&cinfo);
83 jpeg_stdio_dest(&cinfo, f);
84 cinfo.image_width = im->cache_entry.w;
85 cinfo.image_height = im->cache_entry.h;
86 cinfo.input_components = 3;
87 cinfo.in_color_space = JCS_RGB;
88 cinfo.optimize_coding = FALSE;
89 cinfo.dct_method = JDCT_ISLOW; // JDCT_FLOAT JDCT_IFAST(quality loss)
90 if (quality < 60) cinfo.dct_method = JDCT_IFAST;
91 jpeg_set_defaults(&cinfo);
92 jpeg_set_quality(&cinfo, quality, TRUE);
95 cinfo.comp_info[0].h_samp_factor = 1;
96 cinfo.comp_info[0].v_samp_factor = 1;
97 cinfo.comp_info[1].h_samp_factor = 1;
98 cinfo.comp_info[1].v_samp_factor = 1;
99 cinfo.comp_info[2].h_samp_factor = 1;
100 cinfo.comp_info[2].v_samp_factor = 1;
102 jpeg_start_compress(&cinfo, TRUE);
103 ptr = im->image.data;
104 while (cinfo.next_scanline < cinfo.image_height)
107 for (j = 0, i = 0; i < im->cache_entry.w; i++)
109 buf[j++] = ((*ptr) >> 16) & 0xff;
110 buf[j++] = ((*ptr) >> 8) & 0xff;
111 buf[j++] = ((*ptr)) & 0xff;
114 jbuf = (JSAMPROW *) (&buf);
115 jpeg_write_scanlines(&cinfo, jbuf, 1);
118 jpeg_finish_compress(&cinfo);
119 jpeg_destroy_compress(&cinfo);
124 static int evas_image_save_file_jpeg(RGBA_Image *im, const char *file, const char *key __UNUSED__, int quality, int compress __UNUSED__)
126 return save_image_jpeg(im, file, quality);
130 module_open(Evas_Module *em)
133 em->functions = (void *)(&evas_image_save_jpeg_func);
138 module_close(Evas_Module *em __UNUSED__)
142 static Evas_Module_Api evas_modapi =
144 EVAS_MODULE_API_VERSION,
153 EVAS_MODULE_DEFINE(EVAS_MODULE_TYPE_IMAGE_SAVER, image_saver, jpeg);
155 #ifndef EVAS_STATIC_BUILD_JPEG
156 EVAS_EINA_MODULE_DEFINE(image_saver, jpeg);