aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/evas/src/modules/savers/jpeg/evas_image_save_jpeg.c
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/evas/src/modules/savers/jpeg/evas_image_save_jpeg.c')
-rw-r--r--libraries/evas/src/modules/savers/jpeg/evas_image_save_jpeg.c156
1 files changed, 156 insertions, 0 deletions
diff --git a/libraries/evas/src/modules/savers/jpeg/evas_image_save_jpeg.c b/libraries/evas/src/modules/savers/jpeg/evas_image_save_jpeg.c
new file mode 100644
index 0000000..247f0af
--- /dev/null
+++ b/libraries/evas/src/modules/savers/jpeg/evas_image_save_jpeg.c
@@ -0,0 +1,156 @@
1#include "evas_common.h"
2#include "evas_private.h"
3
4#include <stdio.h>
5#include <jpeglib.h>
6#include <setjmp.h>
7
8static int evas_image_save_file_jpeg(RGBA_Image *im, const char *file, const char *key, int quality, int compress);
9
10static Evas_Image_Save_Func evas_image_save_jpeg_func =
11{
12 evas_image_save_file_jpeg
13};
14
15struct _JPEG_error_mgr
16{
17 struct jpeg_error_mgr pub;
18 jmp_buf setjmp_buffer;
19};
20typedef struct _JPEG_error_mgr *emptr;
21
22static void _JPEGFatalErrorHandler(j_common_ptr cinfo);
23static 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
33static void
34_JPEGErrorHandler(j_common_ptr cinfo __UNUSED__)
35{
36/* emptr errmgr; */
37
38/* errmgr = (emptr) cinfo->err; */
39 return;
40}
41
42static void
43_JPEGErrorHandler2(j_common_ptr cinfo __UNUSED__, int msg_level __UNUSED__)
44{
45/* emptr errmgr; */
46
47/* errmgr = (emptr) cinfo->err; */
48 return;
49}
50
51static int
52save_image_jpeg(RGBA_Image *im, const char *file, int quality)
53{
54 struct _JPEG_error_mgr jerr;
55 struct jpeg_compress_struct cinfo;
56 FILE *f;
57 DATA8 *buf;
58 DATA32 *ptr;
59 JSAMPROW *jbuf;
60 int y = 0;
61
62 if (!im || !im->image.data || !file)
63 return 0;
64
65 buf = alloca(im->cache_entry.w * 3 * sizeof(DATA8));
66 f = fopen(file, "wb");
67 if (!f)
68 {
69 return 0;
70 }
71 jerr.pub.error_exit = _JPEGFatalErrorHandler;
72 jerr.pub.emit_message = _JPEGErrorHandler2;
73 jerr.pub.output_message = _JPEGErrorHandler;
74 cinfo.err = jpeg_std_error(&(jerr.pub));
75 if (sigsetjmp(jerr.setjmp_buffer, 1))
76 {
77 jpeg_destroy_compress(&cinfo);
78 fclose(f);
79 return 0;
80 }
81 jpeg_create_compress(&cinfo);
82 jpeg_stdio_dest(&cinfo, f);
83 cinfo.image_width = im->cache_entry.w;
84 cinfo.image_height = im->cache_entry.h;
85 cinfo.input_components = 3;
86 cinfo.in_color_space = JCS_RGB;
87 cinfo.optimize_coding = FALSE;
88 cinfo.dct_method = JDCT_ISLOW; // JDCT_FLOAT JDCT_IFAST(quality loss)
89 if (quality < 60) cinfo.dct_method = JDCT_IFAST;
90 jpeg_set_defaults(&cinfo);
91 jpeg_set_quality(&cinfo, quality, TRUE);
92 if (quality >= 90)
93 {
94 cinfo.comp_info[0].h_samp_factor = 1;
95 cinfo.comp_info[0].v_samp_factor = 1;
96 cinfo.comp_info[1].h_samp_factor = 1;
97 cinfo.comp_info[1].v_samp_factor = 1;
98 cinfo.comp_info[2].h_samp_factor = 1;
99 cinfo.comp_info[2].v_samp_factor = 1;
100 }
101 jpeg_start_compress(&cinfo, TRUE);
102 ptr = im->image.data;
103 while (cinfo.next_scanline < cinfo.image_height)
104 {
105 unsigned int i, j;
106 for (j = 0, i = 0; i < im->cache_entry.w; i++)
107 {
108 buf[j++] = ((*ptr) >> 16) & 0xff;
109 buf[j++] = ((*ptr) >> 8) & 0xff;
110 buf[j++] = ((*ptr)) & 0xff;
111 ptr++;
112 }
113 jbuf = (JSAMPROW *) (&buf);
114 jpeg_write_scanlines(&cinfo, jbuf, 1);
115 y++;
116 }
117 jpeg_finish_compress(&cinfo);
118 jpeg_destroy_compress(&cinfo);
119 fclose(f);
120 return 1;
121}
122
123static int evas_image_save_file_jpeg(RGBA_Image *im, const char *file, const char *key __UNUSED__, int quality, int compress __UNUSED__)
124{
125 return save_image_jpeg(im, file, quality);
126}
127
128static int
129module_open(Evas_Module *em)
130{
131 if (!em) return 0;
132 em->functions = (void *)(&evas_image_save_jpeg_func);
133 return 1;
134}
135
136static void
137module_close(Evas_Module *em __UNUSED__)
138{
139}
140
141static Evas_Module_Api evas_modapi =
142{
143 EVAS_MODULE_API_VERSION,
144 "jpeg",
145 "none",
146 {
147 module_open,
148 module_close
149 }
150};
151
152EVAS_MODULE_DEFINE(EVAS_MODULE_TYPE_IMAGE_SAVER, image_saver, jpeg);
153
154#ifndef EVAS_STATIC_BUILD_JPEG
155EVAS_EINA_MODULE_DEFINE(image_saver, jpeg);
156#endif