aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/evas/src/modules/loaders/png/evas_image_load_png.c
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/evas/src/modules/loaders/png/evas_image_load_png.c')
-rw-r--r--libraries/evas/src/modules/loaders/png/evas_image_load_png.c329
1 files changed, 0 insertions, 329 deletions
diff --git a/libraries/evas/src/modules/loaders/png/evas_image_load_png.c b/libraries/evas/src/modules/loaders/png/evas_image_load_png.c
deleted file mode 100644
index 3007a57..0000000
--- a/libraries/evas/src/modules/loaders/png/evas_image_load_png.c
+++ /dev/null
@@ -1,329 +0,0 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif
4
5#include <stdio.h>
6#include <png.h>
7#include <setjmp.h>
8
9#ifdef HAVE_EVIL
10# include <Evil.h>
11#endif
12
13#ifdef _WIN32_WCE
14# define E_FOPEN(file, mode) evil_fopen_native((file), (mode))
15# define E_FREAD(buffer, size, count, stream) evil_fread_native(buffer, size, count, stream)
16# define E_FCLOSE(stream) evil_fclose_native(stream)
17#else
18# define E_FOPEN(file, mode) fopen((file), (mode))
19# define E_FREAD(buffer, size, count, stream) fread(buffer, size, count, stream)
20# define E_FCLOSE(stream) fclose(stream)
21#endif
22
23#include "evas_common.h"
24#include "evas_private.h"
25
26
27#define PNG_BYTES_TO_CHECK 4
28
29
30static Eina_Bool evas_image_load_file_head_png(Image_Entry *ie, const char *file, const char *key, int *error) EINA_ARG_NONNULL(1, 2, 4);
31static Eina_Bool evas_image_load_file_data_png(Image_Entry *ie, const char *file, const char *key, int *error) EINA_ARG_NONNULL(1, 2, 4);
32
33static Evas_Image_Load_Func evas_image_load_png_func =
34{
35 EINA_TRUE,
36 evas_image_load_file_head_png,
37 evas_image_load_file_data_png,
38 NULL,
39 EINA_FALSE
40};
41
42static Eina_Bool
43evas_image_load_file_head_png(Image_Entry *ie, const char *file, const char *key __UNUSED__, int *error)
44{
45 png_uint_32 w32, h32;
46 FILE *f;
47 png_structp png_ptr = NULL;
48 png_infop info_ptr = NULL;
49 int bit_depth, color_type, interlace_type;
50 unsigned char buf[PNG_BYTES_TO_CHECK];
51 char hasa;
52
53 hasa = 0;
54 f = E_FOPEN(file, "rb");
55 if (!f)
56 {
57 ERR("File: '%s' does not exist\n", file);
58 *error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
59 return EINA_FALSE;
60 }
61
62 /* if we havent read the header before, set the header data */
63 if (E_FREAD(buf, PNG_BYTES_TO_CHECK, 1, f) != 1)
64 {
65 *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
66 goto close_file;
67 }
68
69 if (png_sig_cmp(buf, 0, PNG_BYTES_TO_CHECK))
70 {
71 *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
72 goto close_file;
73 }
74
75 png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
76 if (!png_ptr)
77 {
78 *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
79 goto close_file;
80 }
81
82 info_ptr = png_create_info_struct(png_ptr);
83 if (!info_ptr)
84 {
85 png_destroy_read_struct(&png_ptr, NULL, NULL);
86 *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
87 goto close_file;
88 }
89 if (setjmp(png_jmpbuf(png_ptr)))
90 {
91 png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
92 *error = EVAS_LOAD_ERROR_CORRUPT_FILE;
93 goto close_file;
94 }
95 png_init_io(png_ptr, f);
96 png_set_sig_bytes(png_ptr, PNG_BYTES_TO_CHECK);
97 png_read_info(png_ptr, info_ptr);
98 png_get_IHDR(png_ptr, info_ptr, (png_uint_32 *) (&w32),
99 (png_uint_32 *) (&h32), &bit_depth, &color_type,
100 &interlace_type, NULL, NULL);
101 if ((w32 < 1) || (h32 < 1) || (w32 > IMG_MAX_SIZE) || (h32 > IMG_MAX_SIZE) ||
102 IMG_TOO_BIG(w32, h32))
103 {
104 png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
105 if (IMG_TOO_BIG(w32, h32))
106 *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
107 else
108 *error = EVAS_LOAD_ERROR_GENERIC;
109 goto close_file;
110 }
111 if (ie->load_opts.scale_down_by > 1)
112 {
113 ie->w = (int) w32 / ie->load_opts.scale_down_by;
114 ie->h = (int) h32 / ie->load_opts.scale_down_by;
115 if ((ie->w < 1) || (ie->h < 1))
116 {
117 *error = EVAS_LOAD_ERROR_GENERIC;
118 goto close_file;
119 }
120 }
121 else
122 {
123 ie->w = (int) w32;
124 ie->h = (int) h32;
125 }
126 if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) hasa = 1;
127 if (color_type == PNG_COLOR_TYPE_RGB_ALPHA) hasa = 1;
128 if (color_type == PNG_COLOR_TYPE_GRAY_ALPHA) hasa = 1;
129 if (hasa) ie->flags.alpha = 1;
130 png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
131 E_FCLOSE(f);
132
133 *error = EVAS_LOAD_ERROR_NONE;
134 return EINA_TRUE;
135
136 close_file:
137 E_FCLOSE(f);
138 return EINA_FALSE;
139}
140
141static Eina_Bool
142evas_image_load_file_data_png(Image_Entry *ie, const char *file, const char *key __UNUSED__, int *error)
143{
144 unsigned char *surface;
145 png_uint_32 w32, h32;
146 int w, h;
147 FILE *f;
148 png_structp png_ptr = NULL;
149 png_infop info_ptr = NULL;
150 int bit_depth, color_type, interlace_type;
151 unsigned char buf[PNG_BYTES_TO_CHECK];
152 unsigned char **lines;
153 char hasa;
154 int i, j;
155 int scale_ratio = 1, image_w = 0;
156 unsigned char *tmp_line;
157 DATA32 *src_ptr, *dst_ptr;
158
159 hasa = 0;
160 f = E_FOPEN(file, "rb");
161 if (!f)
162 {
163 *error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
164 return EINA_FALSE;
165 }
166
167 /* if we havent read the header before, set the header data */
168 if (E_FREAD(buf, PNG_BYTES_TO_CHECK, 1, f) != 1)
169 {
170 *error = EVAS_LOAD_ERROR_CORRUPT_FILE;
171 goto close_file;
172 }
173 if (png_sig_cmp(buf, 0, PNG_BYTES_TO_CHECK))
174 {
175 *error = EVAS_LOAD_ERROR_CORRUPT_FILE;
176 goto close_file;
177 }
178 png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
179 if (!png_ptr)
180 {
181 *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
182 goto close_file;
183 }
184
185 info_ptr = png_create_info_struct(png_ptr);
186 if (!info_ptr)
187 {
188 png_destroy_read_struct(&png_ptr, NULL, NULL);
189 *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
190 goto close_file;
191 }
192 if (setjmp(png_jmpbuf(png_ptr)))
193 {
194 png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
195 *error = EVAS_LOAD_ERROR_CORRUPT_FILE;
196 goto close_file;
197 }
198 png_init_io(png_ptr, f);
199 png_set_sig_bytes(png_ptr, PNG_BYTES_TO_CHECK);
200 png_read_info(png_ptr, info_ptr);
201 png_get_IHDR(png_ptr, info_ptr, (png_uint_32 *) (&w32),
202 (png_uint_32 *) (&h32), &bit_depth, &color_type,
203 &interlace_type, NULL, NULL);
204 image_w = w32;
205 if (ie->load_opts.scale_down_by > 1)
206 {
207 scale_ratio = ie->load_opts.scale_down_by;
208 w32 /= scale_ratio;
209 h32 /= scale_ratio;
210 }
211 evas_cache_image_surface_alloc(ie, w32, h32);
212 surface = (unsigned char *) evas_cache_image_pixels(ie);
213 if (!surface)
214 {
215 png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
216 *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
217 goto close_file;
218 }
219 if ((w32 != ie->w) || (h32 != ie->h))
220 {
221 png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
222 *error = EVAS_LOAD_ERROR_GENERIC;
223 goto close_file;
224 }
225 if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) hasa = 1;
226 if (color_type == PNG_COLOR_TYPE_RGB_ALPHA) hasa = 1;
227 if (color_type == PNG_COLOR_TYPE_GRAY_ALPHA) hasa = 1;
228 if (hasa) ie->flags.alpha = 1;
229
230 /* Prep for transformations... ultimately we want ARGB */
231 /* expand palette -> RGB if necessary */
232 if (color_type == PNG_COLOR_TYPE_PALETTE) png_set_palette_to_rgb(png_ptr);
233 /* expand gray (w/reduced bits) -> 8-bit RGB if necessary */
234 if ((color_type == PNG_COLOR_TYPE_GRAY) ||
235 (color_type == PNG_COLOR_TYPE_GRAY_ALPHA))
236 {
237 png_set_gray_to_rgb(png_ptr);
238 if (bit_depth < 8) png_set_expand_gray_1_2_4_to_8(png_ptr);
239 }
240 /* expand transparency entry -> alpha channel if present */
241 if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
242 png_set_tRNS_to_alpha(png_ptr);
243 /* reduce 16bit color -> 8bit color if necessary */
244 if (bit_depth > 8) png_set_strip_16(png_ptr);
245 /* pack all pixels to byte boundaries */
246 png_set_packing(png_ptr);
247
248 w = ie->w;
249 h = ie->h;
250 /* we want ARGB */
251#ifdef WORDS_BIGENDIAN
252 png_set_swap_alpha(png_ptr);
253 if (!hasa) png_set_filler(png_ptr, 0xff, PNG_FILLER_BEFORE);
254#else
255 png_set_bgr(png_ptr);
256 if (!hasa) png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER);
257#endif
258
259 /* we read image line by line if scale down was set */
260 if (scale_ratio == 1)
261 {
262 lines = (unsigned char **) alloca(h * sizeof(unsigned char *));
263 for (i = 0; i < h; i++)
264 lines[i] = surface + (i * w * sizeof(DATA32));
265 png_read_image(png_ptr, lines);
266 png_read_end(png_ptr, info_ptr);
267 }
268 else
269 {
270 tmp_line = (unsigned char *) alloca(image_w * sizeof(DATA32));
271 dst_ptr = (DATA32 *)surface;
272 for (i = 0; i < h; i++)
273 {
274 png_read_row(png_ptr, tmp_line, NULL);
275 src_ptr = (DATA32 *)tmp_line;
276 for (j = 0; j < w; j++)
277 {
278 *dst_ptr = *src_ptr;
279 dst_ptr++;
280 src_ptr += scale_ratio;
281 }
282 for (j = 0; j < (scale_ratio - 1); j++)
283 {
284 png_read_row(png_ptr, tmp_line, NULL);
285 }
286 }
287 }
288
289 png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
290 E_FCLOSE(f);
291 evas_common_image_premul(ie);
292
293 *error = EVAS_LOAD_ERROR_NONE;
294 return EINA_TRUE;
295
296 close_file:
297 E_FCLOSE(f);
298 return EINA_FALSE;
299}
300
301static int
302module_open(Evas_Module *em)
303{
304 if (!em) return 0;
305 em->functions = (void *)(&evas_image_load_png_func);
306 return 1;
307}
308
309static void
310module_close(Evas_Module *em __UNUSED__)
311{
312}
313
314static Evas_Module_Api evas_modapi =
315{
316 EVAS_MODULE_API_VERSION,
317 "png",
318 "none",
319 {
320 module_open,
321 module_close
322 }
323};
324
325EVAS_MODULE_DEFINE(EVAS_MODULE_TYPE_IMAGE_LOADER, image_loader, png);
326
327#ifndef EVAS_STATIC_BUILD_PNG
328EVAS_EINA_MODULE_DEFINE(image_loader, png);
329#endif