diff options
Diffstat (limited to '')
-rw-r--r-- | libraries/evas/src/modules/loaders/psd/Makefile.in | 8 | ||||
-rw-r--r-- | libraries/evas/src/modules/loaders/psd/evas_image_load_psd.c | 264 |
2 files changed, 156 insertions, 116 deletions
diff --git a/libraries/evas/src/modules/loaders/psd/Makefile.in b/libraries/evas/src/modules/loaders/psd/Makefile.in index 98d340a..3dc9c38 100644 --- a/libraries/evas/src/modules/loaders/psd/Makefile.in +++ b/libraries/evas/src/modules/loaders/psd/Makefile.in | |||
@@ -231,8 +231,6 @@ PATH_SEPARATOR = @PATH_SEPARATOR@ | |||
231 | PIXMAN_CFLAGS = @PIXMAN_CFLAGS@ | 231 | PIXMAN_CFLAGS = @PIXMAN_CFLAGS@ |
232 | PIXMAN_LIBS = @PIXMAN_LIBS@ | 232 | PIXMAN_LIBS = @PIXMAN_LIBS@ |
233 | PKG_CONFIG = @PKG_CONFIG@ | 233 | PKG_CONFIG = @PKG_CONFIG@ |
234 | PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ | ||
235 | PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ | ||
236 | PNG_CFLAGS = @PNG_CFLAGS@ | 234 | PNG_CFLAGS = @PNG_CFLAGS@ |
237 | PNG_LIBS = @PNG_LIBS@ | 235 | PNG_LIBS = @PNG_LIBS@ |
238 | RANLIB = @RANLIB@ | 236 | RANLIB = @RANLIB@ |
@@ -249,6 +247,8 @@ VALGRIND_CFLAGS = @VALGRIND_CFLAGS@ | |||
249 | VALGRIND_LIBS = @VALGRIND_LIBS@ | 247 | VALGRIND_LIBS = @VALGRIND_LIBS@ |
250 | VERSION = @VERSION@ | 248 | VERSION = @VERSION@ |
251 | VMAJ = @VMAJ@ | 249 | VMAJ = @VMAJ@ |
250 | WAYLAND_EGL_CFLAGS = @WAYLAND_EGL_CFLAGS@ | ||
251 | WAYLAND_EGL_LIBS = @WAYLAND_EGL_LIBS@ | ||
252 | WIN32_CFLAGS = @WIN32_CFLAGS@ | 252 | WIN32_CFLAGS = @WIN32_CFLAGS@ |
253 | WIN32_CPPFLAGS = @WIN32_CPPFLAGS@ | 253 | WIN32_CPPFLAGS = @WIN32_CPPFLAGS@ |
254 | XCB_CFLAGS = @XCB_CFLAGS@ | 254 | XCB_CFLAGS = @XCB_CFLAGS@ |
@@ -330,6 +330,10 @@ evas_engine_software_xcb_cflags = @evas_engine_software_xcb_cflags@ | |||
330 | evas_engine_software_xcb_libs = @evas_engine_software_xcb_libs@ | 330 | evas_engine_software_xcb_libs = @evas_engine_software_xcb_libs@ |
331 | evas_engine_software_xlib_cflags = @evas_engine_software_xlib_cflags@ | 331 | evas_engine_software_xlib_cflags = @evas_engine_software_xlib_cflags@ |
332 | evas_engine_software_xlib_libs = @evas_engine_software_xlib_libs@ | 332 | evas_engine_software_xlib_libs = @evas_engine_software_xlib_libs@ |
333 | evas_engine_wayland_egl_cflags = @evas_engine_wayland_egl_cflags@ | ||
334 | evas_engine_wayland_egl_libs = @evas_engine_wayland_egl_libs@ | ||
335 | evas_engine_wayland_shm_cflags = @evas_engine_wayland_shm_cflags@ | ||
336 | evas_engine_wayland_shm_libs = @evas_engine_wayland_shm_libs@ | ||
333 | evas_image_loader_bmp_cflags = @evas_image_loader_bmp_cflags@ | 337 | evas_image_loader_bmp_cflags = @evas_image_loader_bmp_cflags@ |
334 | evas_image_loader_bmp_libs = @evas_image_loader_bmp_libs@ | 338 | evas_image_loader_bmp_libs = @evas_image_loader_bmp_libs@ |
335 | evas_image_loader_edb_cflags = @evas_image_loader_edb_cflags@ | 339 | evas_image_loader_edb_cflags = @evas_image_loader_edb_cflags@ |
diff --git a/libraries/evas/src/modules/loaders/psd/evas_image_load_psd.c b/libraries/evas/src/modules/loaders/psd/evas_image_load_psd.c index 5a85e17..27f5f24 100644 --- a/libraries/evas/src/modules/loaders/psd/evas_image_load_psd.c +++ b/libraries/evas/src/modules/loaders/psd/evas_image_load_psd.c | |||
@@ -61,48 +61,57 @@ enum { | |||
61 | }; | 61 | }; |
62 | 62 | ||
63 | static Eina_Bool get_compressed_channels_length(PSD_Header *Head, | 63 | static Eina_Bool get_compressed_channels_length(PSD_Header *Head, |
64 | FILE *file, | 64 | const unsigned char *map, size_t length, size_t *position, |
65 | unsigned short *rle_table, | 65 | unsigned short *rle_table, |
66 | unsigned int *chanlen); | 66 | unsigned int *chanlen); |
67 | 67 | ||
68 | static int | 68 | static int |
69 | read_ushort(FILE *file, unsigned short *ret) | 69 | read_ushort(const unsigned char *map, size_t length, size_t *position, unsigned short *ret) |
70 | { | 70 | { |
71 | unsigned char b[2]; | 71 | if (*position + 2 > length) return 0; |
72 | if (fread(b, sizeof(unsigned char), 2, file) != 2) return 0; | ||
73 | // FIXME: need to check order | 72 | // FIXME: need to check order |
74 | *ret = (b[0] << 8) | b[1]; | 73 | *ret = (map[(*position) + 0] << 8) | map[(*position) + 1]; |
74 | *position += 2; | ||
75 | return 1; | 75 | return 1; |
76 | } | 76 | } |
77 | 77 | ||
78 | static int | 78 | static int |
79 | read_uint(FILE *file, unsigned int *ret) | 79 | read_uint(const unsigned char *map, size_t length, size_t *position, unsigned int *ret) |
80 | { | 80 | { |
81 | unsigned char b[4]; | 81 | if (*position + 4 > length) return 0; |
82 | if (fread(b, sizeof(unsigned char), 4, file) != 4) return 0; | ||
83 | // FIXME: need to check order | 82 | // FIXME: need to check order |
84 | *ret = ARGB_JOIN(b[0], b[1], b[2], b[3]); | 83 | *ret = ARGB_JOIN(map[(*position) + 0], map[(*position) + 1], map[(*position) + 2], map[(*position) + 3]); |
84 | *position += 4; | ||
85 | return 1; | ||
86 | } | ||
87 | |||
88 | static int | ||
89 | read_block(const unsigned char *map, size_t length, size_t *position, void *target, size_t size) | ||
90 | { | ||
91 | if (*position + size > length) return 0; | ||
92 | memcpy(target, map + *position, size); | ||
93 | *position += size; | ||
85 | return 1; | 94 | return 1; |
86 | } | 95 | } |
87 | 96 | ||
88 | // Internal function used to get the Psd header from the current file. | 97 | // Internal function used to get the Psd header from the current file. |
89 | Eina_Bool | 98 | Eina_Bool |
90 | psd_get_header(PSD_Header *header, FILE * file) | 99 | psd_get_header(PSD_Header *header, const unsigned char *map, size_t length, size_t *position) |
91 | { | 100 | { |
92 | unsigned short tmp; | 101 | unsigned short tmp; |
93 | 102 | ||
94 | #define CHECK_RET(Call, Value) \ | 103 | #define CHECK_RET(Call) \ |
95 | if (Call != Value) return EINA_FALSE; | 104 | if (!Call) return EINA_FALSE; |
96 | 105 | ||
97 | CHECK_RET(fread(header->signature, sizeof (unsigned char), 4, file), 4); | 106 | CHECK_RET(read_block(map, length, position, header->signature, 4)); |
98 | CHECK_RET(read_ushort(file, &header->version), 1); | 107 | CHECK_RET(read_ushort(map, length, position, &header->version)); |
99 | CHECK_RET(fread(header->reserved, sizeof (unsigned char), 6, file), 6); | 108 | CHECK_RET(read_block(map, length, position, header->reserved, 6)); |
100 | CHECK_RET(read_ushort(file, &header->channels), 1); | 109 | CHECK_RET(read_ushort(map, length, position, &header->channels)); |
101 | CHECK_RET(read_uint(file, &header->height), 1); | 110 | CHECK_RET(read_uint(map, length, position, &header->height)); |
102 | CHECK_RET(read_uint(file, &header->width), 1); | 111 | CHECK_RET(read_uint(map, length, position, &header->width)); |
103 | CHECK_RET(read_ushort(file, &header->depth), 1); | 112 | CHECK_RET(read_ushort(map, length, position, &header->depth)); |
104 | 113 | ||
105 | CHECK_RET(read_ushort(file, &tmp), 1); | 114 | CHECK_RET(read_ushort(map, length, position, &tmp)); |
106 | header->mode = tmp; | 115 | header->mode = tmp; |
107 | 116 | ||
108 | #undef CHECK_RET | 117 | #undef CHECK_RET |
@@ -144,20 +153,35 @@ static Eina_Bool | |||
144 | evas_image_load_file_head_psd(Image_Entry *ie, const char *FileName, | 153 | evas_image_load_file_head_psd(Image_Entry *ie, const char *FileName, |
145 | const char *key __UNUSED__, int *error) | 154 | const char *key __UNUSED__, int *error) |
146 | { | 155 | { |
147 | FILE *f; | 156 | Eina_File *f; |
157 | void *map; | ||
158 | size_t length; | ||
159 | size_t position; | ||
148 | PSD_Header header; | 160 | PSD_Header header; |
149 | Eina_Bool correct; | 161 | Eina_Bool correct; |
150 | 162 | ||
151 | *error = EVAS_LOAD_ERROR_NONE; | 163 | *error = EVAS_LOAD_ERROR_NONE; |
152 | 164 | ||
153 | f = fopen(FileName, "rb"); | 165 | f = eina_file_open(FileName, 0); |
154 | if (f == NULL) | 166 | if (f == NULL) |
155 | { | 167 | { |
156 | *error = EVAS_LOAD_ERROR_DOES_NOT_EXIST; | 168 | *error = EVAS_LOAD_ERROR_DOES_NOT_EXIST; |
157 | return EINA_FALSE; | 169 | return EINA_FALSE; |
158 | } | 170 | } |
159 | correct = psd_get_header(&header, f); | 171 | |
160 | fclose(f); | 172 | map = eina_file_map_all(f, EINA_FILE_SEQUENTIAL); |
173 | length = eina_file_size_get(f); | ||
174 | position = 0; | ||
175 | if (!map || length < 1) | ||
176 | { | ||
177 | eina_file_close(f); | ||
178 | *error = EVAS_LOAD_ERROR_CORRUPT_FILE; | ||
179 | return EINA_FALSE; | ||
180 | } | ||
181 | correct = psd_get_header(&header, map, length, &position); | ||
182 | |||
183 | eina_file_map_free(f, map); | ||
184 | eina_file_close(f); | ||
161 | 185 | ||
162 | if (!correct || !is_psd(&header)) | 186 | if (!correct || !is_psd(&header)) |
163 | { | 187 | { |
@@ -174,7 +198,7 @@ evas_image_load_file_head_psd(Image_Entry *ie, const char *FileName, | |||
174 | } | 198 | } |
175 | 199 | ||
176 | static unsigned int | 200 | static unsigned int |
177 | read_compressed_channel(FILE* file, | 201 | read_compressed_channel(const unsigned char *map, size_t length, size_t *position, |
178 | const unsigned int channel_length __UNUSED__, | 202 | const unsigned int channel_length __UNUSED__, |
179 | unsigned int size, | 203 | unsigned int size, |
180 | unsigned char* channel) | 204 | unsigned char* channel) |
@@ -183,19 +207,18 @@ read_compressed_channel(FILE* file, | |||
183 | unsigned int i; | 207 | unsigned int i; |
184 | char headbyte, c; | 208 | char headbyte, c; |
185 | 209 | ||
186 | #define CHECK_RET(Call, Value) \ | 210 | #define CHECK_RET(Call) \ |
187 | if (Call != Value) return READ_COMPRESSED_ERROR_FILE_READ_ERROR; | 211 | if (!Call) return READ_COMPRESSED_ERROR_FILE_READ_ERROR; \ |
188 | 212 | ||
189 | for (i = 0; i < size; ) | 213 | for (i = 0; i < size; ) |
190 | { | 214 | { |
191 | CHECK_RET(fread(&headbyte, 1, 1, file), 1); | 215 | CHECK_RET(read_block(map, length, position, &headbyte, 1)); |
192 | 216 | ||
193 | if (headbyte >= 0) | 217 | if (headbyte >= 0) |
194 | { | 218 | { |
195 | if (i + headbyte > size) | 219 | if (i + headbyte > size) |
196 | return READ_COMPRESSED_ERROR_FILE_CORRUPT; | 220 | return READ_COMPRESSED_ERROR_FILE_CORRUPT; |
197 | 221 | CHECK_RET(read_block(map, length, position, channel + i, headbyte + 1)); | |
198 | CHECK_RET(fread(channel + i, headbyte + 1, 1, file), 1); | ||
199 | 222 | ||
200 | i += headbyte + 1; | 223 | i += headbyte + 1; |
201 | } | 224 | } |
@@ -203,14 +226,14 @@ read_compressed_channel(FILE* file, | |||
203 | { | 226 | { |
204 | int run; | 227 | int run; |
205 | 228 | ||
206 | CHECK_RET(fread(&c, 1, 1, file), 1); | 229 | CHECK_RET(read_block(map, length, position, &c, 1)); |
207 | 230 | ||
208 | run = c; | 231 | run = c; |
209 | /* if (run == -1) */ | 232 | /* if (run == -1) */ |
210 | /* return READ_COMPRESSED_ERROR_FILE_READ_ERROR; */ | 233 | /* return READ_COMPRESSED_ERROR_FILE_READ_ERROR; */ |
211 | 234 | ||
212 | if (i + (-headbyte + 1) > size) | 235 | if (i + (-headbyte + 1) > size) |
213 | return READ_COMPRESSED_ERROR_FILE_CORRUPT; | 236 | return READ_COMPRESSED_ERROR_FILE_CORRUPT; |
214 | 237 | ||
215 | memset(channel + i, run, -headbyte + 1); | 238 | memset(channel + i, run, -headbyte + 1); |
216 | i += -headbyte + 1; | 239 | i += -headbyte + 1; |
@@ -226,7 +249,7 @@ read_compressed_channel(FILE* file, | |||
226 | Eina_Bool | 249 | Eina_Bool |
227 | psd_get_data(Image_Entry *ie __UNUSED__, | 250 | psd_get_data(Image_Entry *ie __UNUSED__, |
228 | PSD_Header *head, | 251 | PSD_Header *head, |
229 | FILE *f, | 252 | const unsigned char *map, size_t length, size_t *position, |
230 | unsigned char *buffer, Eina_Bool compressed, | 253 | unsigned char *buffer, Eina_Bool compressed, |
231 | int *error) | 254 | int *error) |
232 | { | 255 | { |
@@ -268,13 +291,12 @@ psd_get_data(Image_Entry *ie __UNUSED__, | |||
268 | { | 291 | { |
269 | free(data); | 292 | free(data); |
270 | free(channel); | 293 | free(channel); |
271 | fprintf(stderr, "unsupported file format.\n"); | ||
272 | *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT; | 294 | *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT; |
273 | return EINA_FALSE; | 295 | return EINA_FALSE; |
274 | } | 296 | } |
275 | 297 | ||
276 | #define CHECK_RET(Call, Value) \ | 298 | #define CHECK_RET(Call) \ |
277 | if (Call != Value) \ | 299 | if (!Call) \ |
278 | { \ | 300 | { \ |
279 | free(data); \ | 301 | free(data); \ |
280 | free(channel); \ | 302 | free(channel); \ |
@@ -289,7 +311,7 @@ psd_get_data(Image_Entry *ie __UNUSED__, | |||
289 | { | 311 | { |
290 | unsigned char *tmp = channel; | 312 | unsigned char *tmp = channel; |
291 | 313 | ||
292 | CHECK_RET(fread(tmp, pixels_count, 1, f), 1); | 314 | CHECK_RET(read_block(map, length, position, tmp, pixels_count)); |
293 | 315 | ||
294 | for (y = 0; y < head->height * bps; y += bps) | 316 | for (y = 0; y < head->height * bps; y += bps) |
295 | { | 317 | { |
@@ -306,7 +328,7 @@ psd_get_data(Image_Entry *ie __UNUSED__, | |||
306 | { | 328 | { |
307 | unsigned char *tmp = channel; | 329 | unsigned char *tmp = channel; |
308 | 330 | ||
309 | CHECK_RET(fread(channel, pixels_count, 1, f), 1); | 331 | CHECK_RET(read_block(map, length, position, channel, pixels_count)); |
310 | 332 | ||
311 | for (y = 0; y < head->height * bps; y += bps) | 333 | for (y = 0; y < head->height * bps; y += bps) |
312 | { | 334 | { |
@@ -333,7 +355,7 @@ psd_get_data(Image_Entry *ie __UNUSED__, | |||
333 | { | 355 | { |
334 | unsigned short *shortptr = (unsigned short*) channel; | 356 | unsigned short *shortptr = (unsigned short*) channel; |
335 | 357 | ||
336 | CHECK_RET(fread(channel, pixels_count * 2, 1, f), 1); | 358 | CHECK_RET(read_block(map, length, position, channel, pixels_count * 2)); |
337 | 359 | ||
338 | for (y = 0; y < head->height * bps2; y += bps2) | 360 | for (y = 0; y < head->height * bps2; y += bps2) |
339 | { | 361 | { |
@@ -350,7 +372,7 @@ psd_get_data(Image_Entry *ie __UNUSED__, | |||
350 | { | 372 | { |
351 | unsigned short *shortptr = (unsigned short*) channel; | 373 | unsigned short *shortptr = (unsigned short*) channel; |
352 | 374 | ||
353 | CHECK_RET(fread(channel, pixels_count * 2, 1, f), 1); | 375 | CHECK_RET(read_block(map, length, position, channel, pixels_count * 2)); |
354 | 376 | ||
355 | for (y = 0; y < head->height * bps2; y += bps2) | 377 | for (y = 0; y < head->height * bps2; y += bps2) |
356 | { | 378 | { |
@@ -373,7 +395,7 @@ psd_get_data(Image_Entry *ie __UNUSED__, | |||
373 | 395 | ||
374 | rle_table = alloca(head->height * head->channel_num * sizeof (unsigned short)); | 396 | rle_table = alloca(head->height * head->channel_num * sizeof (unsigned short)); |
375 | chanlen = alloca(head->channel_num * sizeof (unsigned int)); | 397 | chanlen = alloca(head->channel_num * sizeof (unsigned int)); |
376 | if (!get_compressed_channels_length(head, f, rle_table, chanlen)) | 398 | if (!get_compressed_channels_length(head, map, length, position, rle_table, chanlen)) |
377 | goto file_read_error; | 399 | goto file_read_error; |
378 | 400 | ||
379 | for (c = 0; c < numchan; c++) | 401 | for (c = 0; c < numchan; c++) |
@@ -381,7 +403,7 @@ psd_get_data(Image_Entry *ie __UNUSED__, | |||
381 | unsigned char *tmp = channel; | 403 | unsigned char *tmp = channel; |
382 | int err; | 404 | int err; |
383 | 405 | ||
384 | err = read_compressed_channel(f, | 406 | err = read_compressed_channel(map, length, position, |
385 | chanlen[c], | 407 | chanlen[c], |
386 | pixels_count, | 408 | pixels_count, |
387 | channel); | 409 | channel); |
@@ -416,7 +438,7 @@ psd_get_data(Image_Entry *ie __UNUSED__, | |||
416 | unsigned char *tmp = channel; | 438 | unsigned char *tmp = channel; |
417 | int err; | 439 | int err; |
418 | 440 | ||
419 | err = read_compressed_channel(f, | 441 | err = read_compressed_channel(map, length, position, |
420 | chanlen[c], | 442 | chanlen[c], |
421 | pixels_count, | 443 | pixels_count, |
422 | channel); | 444 | channel); |
@@ -482,7 +504,7 @@ psd_get_data(Image_Entry *ie __UNUSED__, | |||
482 | Eina_Bool | 504 | Eina_Bool |
483 | get_single_channel(Image_Entry *ie __UNUSED__, | 505 | get_single_channel(Image_Entry *ie __UNUSED__, |
484 | PSD_Header *head, | 506 | PSD_Header *head, |
485 | FILE *f, | 507 | const unsigned char *map, size_t length, size_t *position, |
486 | unsigned char *buffer, | 508 | unsigned char *buffer, |
487 | Eina_Bool compressed) | 509 | Eina_Bool compressed) |
488 | { | 510 | { |
@@ -496,29 +518,29 @@ get_single_channel(Image_Entry *ie __UNUSED__, | |||
496 | bpc = (head->depth / 8); | 518 | bpc = (head->depth / 8); |
497 | pixels_count = head->width * head->height; | 519 | pixels_count = head->width * head->height; |
498 | 520 | ||
499 | #define CHECK_RET(Call, Value) \ | 521 | #define CHECK_RET(Call) \ |
500 | if (Call != Value) return EINA_FALSE; | 522 | if (!Call) return EINA_FALSE; |
501 | 523 | ||
502 | if (!compressed) | 524 | if (!compressed) |
503 | { | 525 | { |
504 | if (bpc == 1) | 526 | if (bpc == 1) |
505 | { | 527 | { |
506 | CHECK_RET(fread(buffer, pixels_count, 1, f), 1); | 528 | CHECK_RET(read_block(map, length, position, buffer, pixels_count)); |
507 | } | 529 | } |
508 | else | 530 | else |
509 | { // Bpc == 2 | 531 | { // Bpc == 2 |
510 | CHECK_RET(fread(buffer, pixels_count * 2, 1, f), 1); | 532 | CHECK_RET(read_block(map, length, position, buffer, pixels_count * 2)); |
511 | } | 533 | } |
512 | } | 534 | } |
513 | else | 535 | else |
514 | { | 536 | { |
515 | for (i = 0; i < (unsigned int)pixels_count; ) | 537 | for (i = 0; i < (unsigned int)pixels_count; ) |
516 | { | 538 | { |
517 | CHECK_RET(fread(&headbyte, 1, 1, f), 1); | 539 | CHECK_RET(read_block(map, length, position, &headbyte, 1)); |
518 | 540 | ||
519 | if (headbyte >= 0) | 541 | if (headbyte >= 0) |
520 | { // && HeadByte <= 127 | 542 | { // && HeadByte <= 127 |
521 | CHECK_RET(fread(buffer + i, headbyte + 1, 1, f), 1); | 543 | CHECK_RET(read_block(map, length, position, buffer + i, headbyte + 1)); |
522 | 544 | ||
523 | i += headbyte + 1; | 545 | i += headbyte + 1; |
524 | } | 546 | } |
@@ -526,7 +548,7 @@ get_single_channel(Image_Entry *ie __UNUSED__, | |||
526 | { | 548 | { |
527 | int run; | 549 | int run; |
528 | 550 | ||
529 | CHECK_RET(fread(&c, 1, 1, f), 1); | 551 | CHECK_RET(read_block(map, length, position, &c, 1)); |
530 | 552 | ||
531 | run = c; | 553 | run = c; |
532 | if (run == -1) return EINA_FALSE; | 554 | if (run == -1) return EINA_FALSE; |
@@ -543,7 +565,7 @@ get_single_channel(Image_Entry *ie __UNUSED__, | |||
543 | } | 565 | } |
544 | 566 | ||
545 | Eina_Bool | 567 | Eina_Bool |
546 | read_psd_grey(Image_Entry *ie, PSD_Header *head, FILE * f, int *error) | 568 | read_psd_grey(Image_Entry *ie, PSD_Header *head, const unsigned char *map, size_t length, size_t *position, int *error) |
547 | { | 569 | { |
548 | unsigned int color_mode, resource_size, misc_info; | 570 | unsigned int color_mode, resource_size, misc_info; |
549 | unsigned short compressed; | 571 | unsigned short compressed; |
@@ -552,22 +574,21 @@ read_psd_grey(Image_Entry *ie, PSD_Header *head, FILE * f, int *error) | |||
552 | 574 | ||
553 | *error = EVAS_LOAD_ERROR_CORRUPT_FILE; | 575 | *error = EVAS_LOAD_ERROR_CORRUPT_FILE; |
554 | 576 | ||
555 | #define CHECK_RET(Call, Value) \ | 577 | #define CHECK_RET(Call) \ |
556 | if (Call != Value) return EINA_FALSE; | 578 | if (!Call) return EINA_FALSE; |
557 | 579 | ||
558 | CHECK_RET(read_uint(f, &color_mode), 1); | 580 | CHECK_RET(read_uint(map, length, position, &color_mode)); |
559 | // Skip over the 'color mode data section' | 581 | // Skip over the 'color mode data section' |
560 | CHECK_RET(fseek(f, color_mode, SEEK_CUR), 0); | 582 | *position += color_mode; |
561 | 583 | ||
562 | CHECK_RET(read_uint(f, &resource_size), 1); | 584 | CHECK_RET(read_uint(map, length, position, &resource_size)); |
563 | // Read the 'image resources section' | 585 | // Read the 'image resources section' |
586 | *position += resource_size; | ||
564 | 587 | ||
565 | CHECK_RET(fseek(f, resource_size, SEEK_CUR), 0); | 588 | CHECK_RET(read_uint(map, length, position, &misc_info)); |
589 | *position += misc_info; | ||
566 | 590 | ||
567 | CHECK_RET(read_uint(f, &misc_info), 1); | 591 | CHECK_RET(read_ushort(map, length, position, &compressed)); |
568 | CHECK_RET(fseek(f, misc_info, SEEK_CUR), 0); | ||
569 | |||
570 | CHECK_RET(read_ushort(f, &compressed), 1); | ||
571 | 592 | ||
572 | ie->w = head->width; | 593 | ie->w = head->width; |
573 | ie->h = head->height; | 594 | ie->h = head->height; |
@@ -599,7 +620,7 @@ read_psd_grey(Image_Entry *ie, PSD_Header *head, FILE * f, int *error) | |||
599 | goto cleanup_error; | 620 | goto cleanup_error; |
600 | } | 621 | } |
601 | 622 | ||
602 | if (!psd_get_data(ie, head, f, surface, compressed, error)) | 623 | if (!psd_get_data(ie, head, map, length, position, surface, compressed, error)) |
603 | goto cleanup_error; | 624 | goto cleanup_error; |
604 | 625 | ||
605 | return EINA_TRUE; | 626 | return EINA_TRUE; |
@@ -612,7 +633,7 @@ read_psd_grey(Image_Entry *ie, PSD_Header *head, FILE * f, int *error) | |||
612 | 633 | ||
613 | 634 | ||
614 | Eina_Bool | 635 | Eina_Bool |
615 | read_psd_indexed(Image_Entry *ie, PSD_Header *head, FILE * f, int *error) | 636 | read_psd_indexed(Image_Entry *ie, PSD_Header *head, const unsigned char *map, size_t length, size_t *position, int *error) |
616 | { | 637 | { |
617 | unsigned int color_mode, resource_size, misc_info; | 638 | unsigned int color_mode, resource_size, misc_info; |
618 | unsigned short compressed; | 639 | unsigned short compressed; |
@@ -620,11 +641,11 @@ read_psd_indexed(Image_Entry *ie, PSD_Header *head, FILE * f, int *error) | |||
620 | 641 | ||
621 | *error = EVAS_LOAD_ERROR_CORRUPT_FILE; | 642 | *error = EVAS_LOAD_ERROR_CORRUPT_FILE; |
622 | 643 | ||
623 | #define CHECK_RET(Call, Value) \ | 644 | #define CHECK_RET(Call) \ |
624 | if (Call != Value) return EINA_FALSE; | 645 | if (!(Call)) return EINA_FALSE; |
625 | 646 | ||
626 | CHECK_RET(read_uint(f, &color_mode), 1); | 647 | CHECK_RET(read_uint(map, length, position, &color_mode)); |
627 | CHECK_RET((color_mode % 3), 0); | 648 | CHECK_RET(!(color_mode % 3)); |
628 | /* | 649 | /* |
629 | Palette = (unsigned char*)malloc(Colormode); | 650 | Palette = (unsigned char*)malloc(Colormode); |
630 | if (Palette == NULL) | 651 | if (Palette == NULL) |
@@ -633,16 +654,16 @@ read_psd_indexed(Image_Entry *ie, PSD_Header *head, FILE * f, int *error) | |||
633 | goto cleanup_error; | 654 | goto cleanup_error; |
634 | */ | 655 | */ |
635 | // Skip over the 'color mode data section' | 656 | // Skip over the 'color mode data section' |
636 | CHECK_RET(fseek(f, color_mode, SEEK_CUR), 0); | 657 | *position += color_mode; |
637 | 658 | ||
638 | // Read the 'image resources section' | 659 | // Read the 'image resources section' |
639 | CHECK_RET(read_uint(f, &resource_size), 1); | 660 | CHECK_RET(read_uint(map, length, position, &resource_size)); |
640 | CHECK_RET(fseek(f, resource_size, SEEK_CUR), 0); | 661 | *position += resource_size; |
641 | 662 | ||
642 | CHECK_RET(read_uint(f, &misc_info), 1); | 663 | CHECK_RET(read_uint(map, length, position, &misc_info)); |
643 | CHECK_RET(fseek(f, misc_info, SEEK_CUR), 0); | 664 | *position += misc_info; |
644 | 665 | ||
645 | CHECK_RET(read_ushort(f, &compressed), 1); | 666 | CHECK_RET(read_ushort(map, length, position, &compressed)); |
646 | 667 | ||
647 | if (head->channels != 1 || head->depth != 8) | 668 | if (head->channels != 1 || head->depth != 8) |
648 | { | 669 | { |
@@ -664,7 +685,7 @@ read_psd_indexed(Image_Entry *ie, PSD_Header *head, FILE * f, int *error) | |||
664 | return EINA_FALSE; | 685 | return EINA_FALSE; |
665 | } | 686 | } |
666 | 687 | ||
667 | if (!psd_get_data(ie, head, f, surface, compressed, error)) | 688 | if (!psd_get_data(ie, head, map, length, position, surface, compressed, error)) |
668 | return EINA_FALSE; | 689 | return EINA_FALSE; |
669 | return EINA_TRUE; | 690 | return EINA_TRUE; |
670 | 691 | ||
@@ -672,28 +693,28 @@ read_psd_indexed(Image_Entry *ie, PSD_Header *head, FILE * f, int *error) | |||
672 | } | 693 | } |
673 | 694 | ||
674 | Eina_Bool | 695 | Eina_Bool |
675 | read_psd_rgb(Image_Entry *ie, PSD_Header *head, FILE *f, int *error) | 696 | read_psd_rgb(Image_Entry *ie, PSD_Header *head, const unsigned char *map, size_t length, size_t *position, int *error) |
676 | { | 697 | { |
677 | unsigned int color_mode, resource_size, misc_info; | 698 | unsigned int color_mode, resource_size, misc_info; |
678 | unsigned short compressed; | 699 | unsigned short compressed; |
679 | unsigned int type; | 700 | unsigned int type; |
680 | void *surface; | 701 | void *surface; |
681 | 702 | ||
682 | #define CHECK_RET(Call, Value) \ | 703 | #define CHECK_RET(Call) \ |
683 | if (Call != Value) return EINA_FALSE; | 704 | if (!Call) return EINA_FALSE; |
684 | 705 | ||
685 | CHECK_RET(read_uint(f, &color_mode), 1); | 706 | CHECK_RET(read_uint(map, length, position, &color_mode)); |
686 | // Skip over the 'color mode data section' | 707 | // Skip over the 'color mode data section' |
687 | CHECK_RET(fseek(f, color_mode, SEEK_CUR), 0); | 708 | *position += color_mode; |
688 | 709 | ||
689 | // Read the 'image resources section' | 710 | // Read the 'image resources section' |
690 | CHECK_RET(read_uint(f, &resource_size), 1); | 711 | CHECK_RET(read_uint(map, length, position, &resource_size)); |
691 | CHECK_RET(fseek(f, resource_size, SEEK_CUR), 0); | 712 | *position += resource_size; |
692 | 713 | ||
693 | CHECK_RET(read_uint(f, &misc_info), 1); | 714 | CHECK_RET(read_uint(map, length, position, &misc_info)); |
694 | CHECK_RET(fseek(f, misc_info, SEEK_CUR), 0); | 715 | *position += misc_info; |
695 | 716 | ||
696 | CHECK_RET(read_ushort(f, &compressed), 1); | 717 | CHECK_RET(read_ushort(map, length, position, &compressed)); |
697 | 718 | ||
698 | head->channel_num = head->channels; | 719 | head->channel_num = head->channels; |
699 | 720 | ||
@@ -722,7 +743,7 @@ read_psd_rgb(Image_Entry *ie, PSD_Header *head, FILE *f, int *error) | |||
722 | goto cleanup_error; | 743 | goto cleanup_error; |
723 | } | 744 | } |
724 | 745 | ||
725 | if (!psd_get_data(ie, head, f, surface, compressed, error)) | 746 | if (!psd_get_data(ie, head, map, length, position, surface, compressed, error)) |
726 | goto cleanup_error; | 747 | goto cleanup_error; |
727 | 748 | ||
728 | evas_common_image_premul(ie); | 749 | evas_common_image_premul(ie); |
@@ -735,7 +756,7 @@ read_psd_rgb(Image_Entry *ie, PSD_Header *head, FILE *f, int *error) | |||
735 | } | 756 | } |
736 | 757 | ||
737 | Eina_Bool | 758 | Eina_Bool |
738 | read_psd_cmyk(Image_Entry *ie, PSD_Header *head, FILE *f, int *error) | 759 | read_psd_cmyk(Image_Entry *ie, PSD_Header *head, const unsigned char *map, size_t length, size_t *position, int *error) |
739 | { | 760 | { |
740 | unsigned int color_mode, resource_size, misc_info, size, i, j, data_size; | 761 | unsigned int color_mode, resource_size, misc_info, size, i, j, data_size; |
741 | unsigned short compressed; | 762 | unsigned short compressed; |
@@ -745,21 +766,21 @@ read_psd_cmyk(Image_Entry *ie, PSD_Header *head, FILE *f, int *error) | |||
745 | 766 | ||
746 | *error = EVAS_LOAD_ERROR_CORRUPT_FILE; | 767 | *error = EVAS_LOAD_ERROR_CORRUPT_FILE; |
747 | 768 | ||
748 | #define CHECK_RET(Call, Value) \ | 769 | #define CHECK_RET(Call) \ |
749 | if (Call != Value) return EINA_FALSE; | 770 | if (!Call) return EINA_FALSE; |
750 | 771 | ||
751 | CHECK_RET(read_uint(f, &color_mode), 1); | 772 | CHECK_RET(read_uint(map, length, position, &color_mode)); |
752 | // Skip over the 'color mode data section' | 773 | // Skip over the 'color mode data section' |
753 | CHECK_RET(fseek(f, color_mode, SEEK_CUR), 0); | 774 | *position += color_mode; |
754 | 775 | ||
755 | CHECK_RET(read_uint(f, &resource_size), 1); | 776 | CHECK_RET(read_uint(map, length, position, &resource_size)); |
756 | // Read the 'image resources section' | 777 | // Read the 'image resources section' |
757 | CHECK_RET(fseek(f, resource_size, SEEK_CUR), 0); | 778 | *position += resource_size; |
758 | 779 | ||
759 | CHECK_RET(read_uint(f, &misc_info), 1); | 780 | CHECK_RET(read_uint(map, length, position, &misc_info)); |
760 | CHECK_RET(fseek(f, misc_info, SEEK_CUR), 0); | 781 | *position += misc_info; |
761 | 782 | ||
762 | CHECK_RET(read_ushort(f, &compressed), 1); | 783 | CHECK_RET(read_ushort(map, length, position, &compressed)); |
763 | 784 | ||
764 | switch (head->channels) | 785 | switch (head->channels) |
765 | { | 786 | { |
@@ -804,14 +825,14 @@ read_psd_cmyk(Image_Entry *ie, PSD_Header *head, FILE *f, int *error) | |||
804 | goto cleanup_error; | 825 | goto cleanup_error; |
805 | } | 826 | } |
806 | 827 | ||
807 | if (!psd_get_data(ie, head, f, surface, compressed, error)) | 828 | if (!psd_get_data(ie, head, map, length, position, surface, compressed, error)) |
808 | goto cleanup_error; | 829 | goto cleanup_error; |
809 | 830 | ||
810 | size = type * ie->w * ie->h; | 831 | size = type * ie->w * ie->h; |
811 | kchannel = malloc(size); | 832 | kchannel = malloc(size); |
812 | if (kchannel == NULL) | 833 | if (kchannel == NULL) |
813 | goto cleanup_error; | 834 | goto cleanup_error; |
814 | if (!get_single_channel(ie, head, f, kchannel, compressed)) | 835 | if (!get_single_channel(ie, head, map, length, position, kchannel, compressed)) |
815 | goto cleanup_error; | 836 | goto cleanup_error; |
816 | 837 | ||
817 | data_size = head->channels * type * ie->w * ie->h; | 838 | data_size = head->channels * type * ie->w * ie->h; |
@@ -861,20 +882,34 @@ evas_image_load_file_data_psd(Image_Entry *ie, | |||
861 | const char *key __UNUSED__, | 882 | const char *key __UNUSED__, |
862 | int *error) | 883 | int *error) |
863 | { | 884 | { |
864 | FILE *f; | 885 | Eina_File *f; |
886 | void *map; | ||
887 | size_t length; | ||
888 | size_t position; | ||
865 | PSD_Header header; | 889 | PSD_Header header; |
866 | Eina_Bool bpsd = EINA_FALSE; | 890 | Eina_Bool bpsd = EINA_FALSE; |
867 | 891 | ||
868 | f = fopen(file, "rb"); | 892 | f = eina_file_open(file, 0); |
869 | if (f == NULL) | 893 | if (f == NULL) |
870 | { | 894 | { |
871 | *error = EVAS_LOAD_ERROR_DOES_NOT_EXIST; | 895 | *error = EVAS_LOAD_ERROR_DOES_NOT_EXIST; |
872 | return bpsd; | 896 | return bpsd; |
873 | } | 897 | } |
874 | 898 | ||
875 | if (!psd_get_header(&header, f) || !is_psd(&header)) | 899 | map = eina_file_map_all(f, EINA_FILE_SEQUENTIAL); |
900 | length = eina_file_size_get(f); | ||
901 | position = 0; | ||
902 | if (!map || length < 1) | ||
903 | { | ||
904 | eina_file_close(f); | ||
905 | *error = EVAS_LOAD_ERROR_CORRUPT_FILE; | ||
906 | return EINA_FALSE; | ||
907 | } | ||
908 | |||
909 | if (!psd_get_header(&header, map, length, &position) || !is_psd(&header)) | ||
876 | { | 910 | { |
877 | fclose(f); | 911 | eina_file_map_free(f, map); |
912 | eina_file_close(f); | ||
878 | *error = EVAS_LOAD_ERROR_GENERIC; | 913 | *error = EVAS_LOAD_ERROR_GENERIC; |
879 | return EINA_FALSE; | 914 | return EINA_FALSE; |
880 | } | 915 | } |
@@ -887,39 +922,39 @@ evas_image_load_file_data_psd(Image_Entry *ie, | |||
887 | switch (header.mode) | 922 | switch (header.mode) |
888 | { | 923 | { |
889 | case PSD_GREYSCALE: // Greyscale | 924 | case PSD_GREYSCALE: // Greyscale |
890 | bpsd = read_psd_grey(ie, &header, f, error); | 925 | bpsd = read_psd_grey(ie, &header, map, length, &position, error); |
891 | break; | 926 | break; |
892 | case PSD_INDEXED: // Indexed | 927 | case PSD_INDEXED: // Indexed |
893 | bpsd = read_psd_indexed(ie, &header, f, error); | 928 | bpsd = read_psd_indexed(ie, &header, map, length, &position, error); |
894 | break; | 929 | break; |
895 | case PSD_RGB: // RGB | 930 | case PSD_RGB: // RGB |
896 | bpsd = read_psd_rgb(ie, &header, f, error); | 931 | bpsd = read_psd_rgb(ie, &header, map, length, &position, error); |
897 | break; | 932 | break; |
898 | case PSD_CMYK: // CMYK | 933 | case PSD_CMYK: // CMYK |
899 | bpsd = read_psd_cmyk(ie, &header, f, error); | 934 | bpsd = read_psd_cmyk(ie, &header, map, length, &position, error); |
900 | break; | 935 | break; |
901 | default : | 936 | default : |
902 | *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT; | 937 | *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT; |
903 | bpsd = EINA_FALSE; | 938 | bpsd = EINA_FALSE; |
904 | } | 939 | } |
905 | fclose(f); | 940 | |
941 | eina_file_map_free(f, map); | ||
942 | eina_file_close(f); | ||
906 | 943 | ||
907 | return bpsd; | 944 | return bpsd; |
908 | } | 945 | } |
909 | 946 | ||
910 | static Eina_Bool | 947 | static Eina_Bool |
911 | get_compressed_channels_length(PSD_Header *head, | 948 | get_compressed_channels_length(PSD_Header *head, |
912 | FILE * file, | 949 | const unsigned char *map, size_t length, size_t *position, |
913 | unsigned short *rle_table, | 950 | unsigned short *rle_table, |
914 | unsigned int *chanlen) | 951 | unsigned int *chanlen) |
915 | { | 952 | { |
916 | unsigned int j; | 953 | unsigned int j; |
917 | unsigned int c; | 954 | unsigned int c; |
918 | 955 | ||
919 | if (fread(rle_table, | 956 | if (!read_block(map, length, position, rle_table, |
920 | sizeof(unsigned short), | 957 | sizeof (unsigned short) * head->height * head->channel_num)) |
921 | head->height * head->channel_num, | ||
922 | file) != head->height * head->channel_num) | ||
923 | return EINA_FALSE; | 958 | return EINA_FALSE; |
924 | 959 | ||
925 | memset(chanlen, 0, head->channel_num * sizeof(unsigned int)); | 960 | memset(chanlen, 0, head->channel_num * sizeof(unsigned int)); |
@@ -941,7 +976,8 @@ static const Evas_Image_Load_Func evas_image_load_psd_func = { | |||
941 | EINA_TRUE, | 976 | EINA_TRUE, |
942 | evas_image_load_file_head_psd, | 977 | evas_image_load_file_head_psd, |
943 | evas_image_load_file_data_psd, | 978 | evas_image_load_file_data_psd, |
944 | NULL | 979 | NULL, |
980 | EINA_FALSE | ||
945 | }; | 981 | }; |
946 | 982 | ||
947 | static int | 983 | static int |