aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/evas/src/modules/loaders/psd/evas_image_load_psd.c
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/evas/src/modules/loaders/psd/evas_image_load_psd.c')
-rw-r--r--libraries/evas/src/modules/loaders/psd/evas_image_load_psd.c264
1 files changed, 150 insertions, 114 deletions
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
63static Eina_Bool get_compressed_channels_length(PSD_Header *Head, 63static 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
68static int 68static int
69read_ushort(FILE *file, unsigned short *ret) 69read_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
78static int 78static int
79read_uint(FILE *file, unsigned int *ret) 79read_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
88static int
89read_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.
89Eina_Bool 98Eina_Bool
90psd_get_header(PSD_Header *header, FILE * file) 99psd_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
144evas_image_load_file_head_psd(Image_Entry *ie, const char *FileName, 153evas_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
176static unsigned int 200static unsigned int
177read_compressed_channel(FILE* file, 201read_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,
226Eina_Bool 249Eina_Bool
227psd_get_data(Image_Entry *ie __UNUSED__, 250psd_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__,
482Eina_Bool 504Eina_Bool
483get_single_channel(Image_Entry *ie __UNUSED__, 505get_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
545Eina_Bool 567Eina_Bool
546read_psd_grey(Image_Entry *ie, PSD_Header *head, FILE * f, int *error) 568read_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
614Eina_Bool 635Eina_Bool
615read_psd_indexed(Image_Entry *ie, PSD_Header *head, FILE * f, int *error) 636read_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
674Eina_Bool 695Eina_Bool
675read_psd_rgb(Image_Entry *ie, PSD_Header *head, FILE *f, int *error) 696read_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
737Eina_Bool 758Eina_Bool
738read_psd_cmyk(Image_Entry *ie, PSD_Header *head, FILE *f, int *error) 759read_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
910static Eina_Bool 947static Eina_Bool
911get_compressed_channels_length(PSD_Header *head, 948get_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
947static int 983static int