forked from enlightenment/efl
parent
08b0c50578
commit
5438cc6844
|
@ -613,3 +613,7 @@
|
||||||
* Fix unitialized value when running generic loader without any
|
* Fix unitialized value when running generic loader without any
|
||||||
application found to open the file.
|
application found to open the file.
|
||||||
* Use Eina_File when openning XPM file.
|
* Use Eina_File when openning XPM file.
|
||||||
|
|
||||||
|
2012-01-03 Cedric Bail
|
||||||
|
|
||||||
|
* Use Eina_File for PSD file to.
|
||||||
|
|
|
@ -10,7 +10,7 @@ Additions:
|
||||||
|
|
||||||
Improvements:
|
Improvements:
|
||||||
|
|
||||||
* Use Eina_File mmap infrastructure for bmp, ico, pmaps and wbmp file access.
|
* Use Eina_File mmap infrastructure for bmp, ico, pmaps, psd, wbmp and xpm file access.
|
||||||
|
|
||||||
Evas 1.1.0
|
Evas 1.1.0
|
||||||
|
|
||||||
|
|
|
@ -61,48 +61,57 @@ enum {
|
||||||
};
|
};
|
||||||
|
|
||||||
static Eina_Bool get_compressed_channels_length(PSD_Header *Head,
|
static Eina_Bool get_compressed_channels_length(PSD_Header *Head,
|
||||||
FILE *file,
|
const unsigned char *map, size_t length, size_t *position,
|
||||||
unsigned short *rle_table,
|
unsigned short *rle_table,
|
||||||
unsigned int *chanlen);
|
unsigned int *chanlen);
|
||||||
|
|
||||||
static int
|
static int
|
||||||
read_ushort(FILE *file, unsigned short *ret)
|
read_ushort(const unsigned char *map, size_t length, size_t *position, unsigned short *ret)
|
||||||
{
|
{
|
||||||
unsigned char b[2];
|
if (*position + 2 > length) return 0;
|
||||||
if (fread(b, sizeof(unsigned char), 2, file) != 2) return 0;
|
|
||||||
// FIXME: need to check order
|
// FIXME: need to check order
|
||||||
*ret = (b[0] << 8) | b[1];
|
*ret = (map[(*position) + 0] << 8) | map[(*position) + 1];
|
||||||
|
*position += 2;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
read_uint(FILE *file, unsigned int *ret)
|
read_uint(const unsigned char *map, size_t length, size_t *position, unsigned int *ret)
|
||||||
{
|
{
|
||||||
unsigned char b[4];
|
if (*position + 4 > length) return 0;
|
||||||
if (fread(b, sizeof(unsigned char), 4, file) != 4) return 0;
|
|
||||||
// FIXME: need to check order
|
// FIXME: need to check order
|
||||||
*ret = ARGB_JOIN(b[0], b[1], b[2], b[3]);
|
*ret = ARGB_JOIN(map[(*position) + 0], map[(*position) + 1], map[(*position) + 2], map[(*position) + 3]);
|
||||||
|
*position += 4;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
read_block(const unsigned char *map, size_t length, size_t *position, void *target, size_t size)
|
||||||
|
{
|
||||||
|
if (*position + size > length) return 0;
|
||||||
|
memcpy(target, map + *position, size);
|
||||||
|
*position += size;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Internal function used to get the Psd header from the current file.
|
// Internal function used to get the Psd header from the current file.
|
||||||
Eina_Bool
|
Eina_Bool
|
||||||
psd_get_header(PSD_Header *header, FILE * file)
|
psd_get_header(PSD_Header *header, const unsigned char *map, size_t length, size_t *position)
|
||||||
{
|
{
|
||||||
unsigned short tmp;
|
unsigned short tmp;
|
||||||
|
|
||||||
#define CHECK_RET(Call, Value) \
|
#define CHECK_RET(Call) \
|
||||||
if (Call != Value) return EINA_FALSE;
|
if (!Call) return EINA_FALSE;
|
||||||
|
|
||||||
CHECK_RET(fread(header->signature, sizeof (unsigned char), 4, file), 4);
|
CHECK_RET(read_block(map, length, position, header->signature, 4));
|
||||||
CHECK_RET(read_ushort(file, &header->version), 1);
|
CHECK_RET(read_ushort(map, length, position, &header->version));
|
||||||
CHECK_RET(fread(header->reserved, sizeof (unsigned char), 6, file), 6);
|
CHECK_RET(read_block(map, length, position, header->reserved, 6));
|
||||||
CHECK_RET(read_ushort(file, &header->channels), 1);
|
CHECK_RET(read_ushort(map, length, position, &header->channels));
|
||||||
CHECK_RET(read_uint(file, &header->height), 1);
|
CHECK_RET(read_uint(map, length, position, &header->height));
|
||||||
CHECK_RET(read_uint(file, &header->width), 1);
|
CHECK_RET(read_uint(map, length, position, &header->width));
|
||||||
CHECK_RET(read_ushort(file, &header->depth), 1);
|
CHECK_RET(read_ushort(map, length, position, &header->depth));
|
||||||
|
|
||||||
CHECK_RET(read_ushort(file, &tmp), 1);
|
CHECK_RET(read_ushort(map, length, position, &tmp));
|
||||||
header->mode = tmp;
|
header->mode = tmp;
|
||||||
|
|
||||||
#undef CHECK_RET
|
#undef CHECK_RET
|
||||||
|
@ -144,20 +153,35 @@ static Eina_Bool
|
||||||
evas_image_load_file_head_psd(Image_Entry *ie, const char *FileName,
|
evas_image_load_file_head_psd(Image_Entry *ie, const char *FileName,
|
||||||
const char *key __UNUSED__, int *error)
|
const char *key __UNUSED__, int *error)
|
||||||
{
|
{
|
||||||
FILE *f;
|
Eina_File *f;
|
||||||
|
void *map;
|
||||||
|
size_t length;
|
||||||
|
size_t position;
|
||||||
PSD_Header header;
|
PSD_Header header;
|
||||||
Eina_Bool correct;
|
Eina_Bool correct;
|
||||||
|
|
||||||
*error = EVAS_LOAD_ERROR_NONE;
|
*error = EVAS_LOAD_ERROR_NONE;
|
||||||
|
|
||||||
f = fopen(FileName, "rb");
|
f = eina_file_open(FileName, 0);
|
||||||
if (f == NULL)
|
if (f == NULL)
|
||||||
{
|
{
|
||||||
*error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
|
*error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
|
||||||
return EINA_FALSE;
|
return EINA_FALSE;
|
||||||
}
|
}
|
||||||
correct = psd_get_header(&header, f);
|
|
||||||
fclose(f);
|
map = eina_file_map_all(f, EINA_FILE_SEQUENTIAL);
|
||||||
|
length = eina_file_size_get(f);
|
||||||
|
position = 0;
|
||||||
|
if (!map || length < 1)
|
||||||
|
{
|
||||||
|
eina_file_close(f);
|
||||||
|
*error = EVAS_LOAD_ERROR_CORRUPT_FILE;
|
||||||
|
return EINA_FALSE;
|
||||||
|
}
|
||||||
|
correct = psd_get_header(&header, map, length, &position);
|
||||||
|
|
||||||
|
eina_file_map_free(f, map);
|
||||||
|
eina_file_close(f);
|
||||||
|
|
||||||
if (!correct || !is_psd(&header))
|
if (!correct || !is_psd(&header))
|
||||||
{
|
{
|
||||||
|
@ -174,7 +198,7 @@ evas_image_load_file_head_psd(Image_Entry *ie, const char *FileName,
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned int
|
static unsigned int
|
||||||
read_compressed_channel(FILE* file,
|
read_compressed_channel(const unsigned char *map, size_t length, size_t *position,
|
||||||
const unsigned int channel_length __UNUSED__,
|
const unsigned int channel_length __UNUSED__,
|
||||||
unsigned int size,
|
unsigned int size,
|
||||||
unsigned char* channel)
|
unsigned char* channel)
|
||||||
|
@ -183,19 +207,18 @@ read_compressed_channel(FILE* file,
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
char headbyte, c;
|
char headbyte, c;
|
||||||
|
|
||||||
#define CHECK_RET(Call, Value) \
|
#define CHECK_RET(Call) \
|
||||||
if (Call != Value) return READ_COMPRESSED_ERROR_FILE_READ_ERROR;
|
if (!Call) return READ_COMPRESSED_ERROR_FILE_READ_ERROR; \
|
||||||
|
|
||||||
for (i = 0; i < size; )
|
for (i = 0; i < size; )
|
||||||
{
|
{
|
||||||
CHECK_RET(fread(&headbyte, 1, 1, file), 1);
|
CHECK_RET(read_block(map, length, position, &headbyte, 1));
|
||||||
|
|
||||||
if (headbyte >= 0)
|
if (headbyte >= 0)
|
||||||
{
|
{
|
||||||
if (i + headbyte > size)
|
if (i + headbyte > size)
|
||||||
return READ_COMPRESSED_ERROR_FILE_CORRUPT;
|
return READ_COMPRESSED_ERROR_FILE_CORRUPT;
|
||||||
|
CHECK_RET(read_block(map, length, position, channel + i, headbyte + 1));
|
||||||
CHECK_RET(fread(channel + i, headbyte + 1, 1, file), 1);
|
|
||||||
|
|
||||||
i += headbyte + 1;
|
i += headbyte + 1;
|
||||||
}
|
}
|
||||||
|
@ -203,7 +226,7 @@ read_compressed_channel(FILE* file,
|
||||||
{
|
{
|
||||||
int run;
|
int run;
|
||||||
|
|
||||||
CHECK_RET(fread(&c, 1, 1, file), 1);
|
CHECK_RET(read_block(map, length, position, &c, 1));
|
||||||
|
|
||||||
run = c;
|
run = c;
|
||||||
/* if (run == -1) */
|
/* if (run == -1) */
|
||||||
|
@ -226,7 +249,7 @@ read_compressed_channel(FILE* file,
|
||||||
Eina_Bool
|
Eina_Bool
|
||||||
psd_get_data(Image_Entry *ie __UNUSED__,
|
psd_get_data(Image_Entry *ie __UNUSED__,
|
||||||
PSD_Header *head,
|
PSD_Header *head,
|
||||||
FILE *f,
|
const unsigned char *map, size_t length, size_t *position,
|
||||||
unsigned char *buffer, Eina_Bool compressed,
|
unsigned char *buffer, Eina_Bool compressed,
|
||||||
int *error)
|
int *error)
|
||||||
{
|
{
|
||||||
|
@ -268,13 +291,12 @@ psd_get_data(Image_Entry *ie __UNUSED__,
|
||||||
{
|
{
|
||||||
free(data);
|
free(data);
|
||||||
free(channel);
|
free(channel);
|
||||||
fprintf(stderr, "unsupported file format.\n");
|
|
||||||
*error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
|
*error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
|
||||||
return EINA_FALSE;
|
return EINA_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define CHECK_RET(Call, Value) \
|
#define CHECK_RET(Call) \
|
||||||
if (Call != Value) \
|
if (!Call) \
|
||||||
{ \
|
{ \
|
||||||
free(data); \
|
free(data); \
|
||||||
free(channel); \
|
free(channel); \
|
||||||
|
@ -289,7 +311,7 @@ psd_get_data(Image_Entry *ie __UNUSED__,
|
||||||
{
|
{
|
||||||
unsigned char *tmp = channel;
|
unsigned char *tmp = channel;
|
||||||
|
|
||||||
CHECK_RET(fread(tmp, pixels_count, 1, f), 1);
|
CHECK_RET(read_block(map, length, position, tmp, pixels_count));
|
||||||
|
|
||||||
for (y = 0; y < head->height * bps; y += bps)
|
for (y = 0; y < head->height * bps; y += bps)
|
||||||
{
|
{
|
||||||
|
@ -306,7 +328,7 @@ psd_get_data(Image_Entry *ie __UNUSED__,
|
||||||
{
|
{
|
||||||
unsigned char *tmp = channel;
|
unsigned char *tmp = channel;
|
||||||
|
|
||||||
CHECK_RET(fread(channel, pixels_count, 1, f), 1);
|
CHECK_RET(read_block(map, length, position, channel, pixels_count));
|
||||||
|
|
||||||
for (y = 0; y < head->height * bps; y += bps)
|
for (y = 0; y < head->height * bps; y += bps)
|
||||||
{
|
{
|
||||||
|
@ -333,7 +355,7 @@ psd_get_data(Image_Entry *ie __UNUSED__,
|
||||||
{
|
{
|
||||||
unsigned short *shortptr = (unsigned short*) channel;
|
unsigned short *shortptr = (unsigned short*) channel;
|
||||||
|
|
||||||
CHECK_RET(fread(channel, pixels_count * 2, 1, f), 1);
|
CHECK_RET(read_block(map, length, position, channel, pixels_count * 2));
|
||||||
|
|
||||||
for (y = 0; y < head->height * bps2; y += bps2)
|
for (y = 0; y < head->height * bps2; y += bps2)
|
||||||
{
|
{
|
||||||
|
@ -350,7 +372,7 @@ psd_get_data(Image_Entry *ie __UNUSED__,
|
||||||
{
|
{
|
||||||
unsigned short *shortptr = (unsigned short*) channel;
|
unsigned short *shortptr = (unsigned short*) channel;
|
||||||
|
|
||||||
CHECK_RET(fread(channel, pixels_count * 2, 1, f), 1);
|
CHECK_RET(read_block(map, length, position, channel, pixels_count * 2));
|
||||||
|
|
||||||
for (y = 0; y < head->height * bps2; y += bps2)
|
for (y = 0; y < head->height * bps2; y += bps2)
|
||||||
{
|
{
|
||||||
|
@ -373,7 +395,7 @@ psd_get_data(Image_Entry *ie __UNUSED__,
|
||||||
|
|
||||||
rle_table = alloca(head->height * head->channel_num * sizeof (unsigned short));
|
rle_table = alloca(head->height * head->channel_num * sizeof (unsigned short));
|
||||||
chanlen = alloca(head->channel_num * sizeof (unsigned int));
|
chanlen = alloca(head->channel_num * sizeof (unsigned int));
|
||||||
if (!get_compressed_channels_length(head, f, rle_table, chanlen))
|
if (!get_compressed_channels_length(head, map, length, position, rle_table, chanlen))
|
||||||
goto file_read_error;
|
goto file_read_error;
|
||||||
|
|
||||||
for (c = 0; c < numchan; c++)
|
for (c = 0; c < numchan; c++)
|
||||||
|
@ -381,7 +403,7 @@ psd_get_data(Image_Entry *ie __UNUSED__,
|
||||||
unsigned char *tmp = channel;
|
unsigned char *tmp = channel;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
err = read_compressed_channel(f,
|
err = read_compressed_channel(map, length, position,
|
||||||
chanlen[c],
|
chanlen[c],
|
||||||
pixels_count,
|
pixels_count,
|
||||||
channel);
|
channel);
|
||||||
|
@ -416,7 +438,7 @@ psd_get_data(Image_Entry *ie __UNUSED__,
|
||||||
unsigned char *tmp = channel;
|
unsigned char *tmp = channel;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
err = read_compressed_channel(f,
|
err = read_compressed_channel(map, length, position,
|
||||||
chanlen[c],
|
chanlen[c],
|
||||||
pixels_count,
|
pixels_count,
|
||||||
channel);
|
channel);
|
||||||
|
@ -482,7 +504,7 @@ psd_get_data(Image_Entry *ie __UNUSED__,
|
||||||
Eina_Bool
|
Eina_Bool
|
||||||
get_single_channel(Image_Entry *ie __UNUSED__,
|
get_single_channel(Image_Entry *ie __UNUSED__,
|
||||||
PSD_Header *head,
|
PSD_Header *head,
|
||||||
FILE *f,
|
const unsigned char *map, size_t length, size_t *position,
|
||||||
unsigned char *buffer,
|
unsigned char *buffer,
|
||||||
Eina_Bool compressed)
|
Eina_Bool compressed)
|
||||||
{
|
{
|
||||||
|
@ -496,29 +518,29 @@ get_single_channel(Image_Entry *ie __UNUSED__,
|
||||||
bpc = (head->depth / 8);
|
bpc = (head->depth / 8);
|
||||||
pixels_count = head->width * head->height;
|
pixels_count = head->width * head->height;
|
||||||
|
|
||||||
#define CHECK_RET(Call, Value) \
|
#define CHECK_RET(Call) \
|
||||||
if (Call != Value) return EINA_FALSE;
|
if (!Call) return EINA_FALSE;
|
||||||
|
|
||||||
if (!compressed)
|
if (!compressed)
|
||||||
{
|
{
|
||||||
if (bpc == 1)
|
if (bpc == 1)
|
||||||
{
|
{
|
||||||
CHECK_RET(fread(buffer, pixels_count, 1, f), 1);
|
CHECK_RET(read_block(map, length, position, buffer, pixels_count));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{ // Bpc == 2
|
{ // Bpc == 2
|
||||||
CHECK_RET(fread(buffer, pixels_count * 2, 1, f), 1);
|
CHECK_RET(read_block(map, length, position, buffer, pixels_count * 2));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (i = 0; i < (unsigned int)pixels_count; )
|
for (i = 0; i < (unsigned int)pixels_count; )
|
||||||
{
|
{
|
||||||
CHECK_RET(fread(&headbyte, 1, 1, f), 1);
|
CHECK_RET(read_block(map, length, position, &headbyte, 1));
|
||||||
|
|
||||||
if (headbyte >= 0)
|
if (headbyte >= 0)
|
||||||
{ // && HeadByte <= 127
|
{ // && HeadByte <= 127
|
||||||
CHECK_RET(fread(buffer + i, headbyte + 1, 1, f), 1);
|
CHECK_RET(read_block(map, length, position, buffer + i, headbyte + 1));
|
||||||
|
|
||||||
i += headbyte + 1;
|
i += headbyte + 1;
|
||||||
}
|
}
|
||||||
|
@ -526,7 +548,7 @@ get_single_channel(Image_Entry *ie __UNUSED__,
|
||||||
{
|
{
|
||||||
int run;
|
int run;
|
||||||
|
|
||||||
CHECK_RET(fread(&c, 1, 1, f), 1);
|
CHECK_RET(read_block(map, length, position, &c, 1));
|
||||||
|
|
||||||
run = c;
|
run = c;
|
||||||
if (run == -1) return EINA_FALSE;
|
if (run == -1) return EINA_FALSE;
|
||||||
|
@ -543,7 +565,7 @@ get_single_channel(Image_Entry *ie __UNUSED__,
|
||||||
}
|
}
|
||||||
|
|
||||||
Eina_Bool
|
Eina_Bool
|
||||||
read_psd_grey(Image_Entry *ie, PSD_Header *head, FILE * f, int *error)
|
read_psd_grey(Image_Entry *ie, PSD_Header *head, const unsigned char *map, size_t length, size_t *position, int *error)
|
||||||
{
|
{
|
||||||
unsigned int color_mode, resource_size, misc_info;
|
unsigned int color_mode, resource_size, misc_info;
|
||||||
unsigned short compressed;
|
unsigned short compressed;
|
||||||
|
@ -552,22 +574,21 @@ read_psd_grey(Image_Entry *ie, PSD_Header *head, FILE * f, int *error)
|
||||||
|
|
||||||
*error = EVAS_LOAD_ERROR_CORRUPT_FILE;
|
*error = EVAS_LOAD_ERROR_CORRUPT_FILE;
|
||||||
|
|
||||||
#define CHECK_RET(Call, Value) \
|
#define CHECK_RET(Call) \
|
||||||
if (Call != Value) return EINA_FALSE;
|
if (!Call) return EINA_FALSE;
|
||||||
|
|
||||||
CHECK_RET(read_uint(f, &color_mode), 1);
|
CHECK_RET(read_uint(map, length, position, &color_mode));
|
||||||
// Skip over the 'color mode data section'
|
// Skip over the 'color mode data section'
|
||||||
CHECK_RET(fseek(f, color_mode, SEEK_CUR), 0);
|
*position += color_mode;
|
||||||
|
|
||||||
CHECK_RET(read_uint(f, &resource_size), 1);
|
CHECK_RET(read_uint(map, length, position, &resource_size));
|
||||||
// Read the 'image resources section'
|
// Read the 'image resources section'
|
||||||
|
*position += resource_size;
|
||||||
|
|
||||||
CHECK_RET(fseek(f, resource_size, SEEK_CUR), 0);
|
CHECK_RET(read_uint(map, length, position, &misc_info));
|
||||||
|
*position += misc_info;
|
||||||
|
|
||||||
CHECK_RET(read_uint(f, &misc_info), 1);
|
CHECK_RET(read_ushort(map, length, position, &compressed));
|
||||||
CHECK_RET(fseek(f, misc_info, SEEK_CUR), 0);
|
|
||||||
|
|
||||||
CHECK_RET(read_ushort(f, &compressed), 1);
|
|
||||||
|
|
||||||
ie->w = head->width;
|
ie->w = head->width;
|
||||||
ie->h = head->height;
|
ie->h = head->height;
|
||||||
|
@ -599,7 +620,7 @@ read_psd_grey(Image_Entry *ie, PSD_Header *head, FILE * f, int *error)
|
||||||
goto cleanup_error;
|
goto cleanup_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!psd_get_data(ie, head, f, surface, compressed, error))
|
if (!psd_get_data(ie, head, map, length, position, surface, compressed, error))
|
||||||
goto cleanup_error;
|
goto cleanup_error;
|
||||||
|
|
||||||
return EINA_TRUE;
|
return EINA_TRUE;
|
||||||
|
@ -612,7 +633,7 @@ read_psd_grey(Image_Entry *ie, PSD_Header *head, FILE * f, int *error)
|
||||||
|
|
||||||
|
|
||||||
Eina_Bool
|
Eina_Bool
|
||||||
read_psd_indexed(Image_Entry *ie, PSD_Header *head, FILE * f, int *error)
|
read_psd_indexed(Image_Entry *ie, PSD_Header *head, const unsigned char *map, size_t length, size_t *position, int *error)
|
||||||
{
|
{
|
||||||
unsigned int color_mode, resource_size, misc_info;
|
unsigned int color_mode, resource_size, misc_info;
|
||||||
unsigned short compressed;
|
unsigned short compressed;
|
||||||
|
@ -620,11 +641,11 @@ read_psd_indexed(Image_Entry *ie, PSD_Header *head, FILE * f, int *error)
|
||||||
|
|
||||||
*error = EVAS_LOAD_ERROR_CORRUPT_FILE;
|
*error = EVAS_LOAD_ERROR_CORRUPT_FILE;
|
||||||
|
|
||||||
#define CHECK_RET(Call, Value) \
|
#define CHECK_RET(Call) \
|
||||||
if (Call != Value) return EINA_FALSE;
|
if (!(Call)) return EINA_FALSE;
|
||||||
|
|
||||||
CHECK_RET(read_uint(f, &color_mode), 1);
|
CHECK_RET(read_uint(map, length, position, &color_mode));
|
||||||
CHECK_RET((color_mode % 3), 0);
|
CHECK_RET(!(color_mode % 3));
|
||||||
/*
|
/*
|
||||||
Palette = (unsigned char*)malloc(Colormode);
|
Palette = (unsigned char*)malloc(Colormode);
|
||||||
if (Palette == NULL)
|
if (Palette == NULL)
|
||||||
|
@ -633,16 +654,16 @@ read_psd_indexed(Image_Entry *ie, PSD_Header *head, FILE * f, int *error)
|
||||||
goto cleanup_error;
|
goto cleanup_error;
|
||||||
*/
|
*/
|
||||||
// Skip over the 'color mode data section'
|
// Skip over the 'color mode data section'
|
||||||
CHECK_RET(fseek(f, color_mode, SEEK_CUR), 0);
|
*position += color_mode;
|
||||||
|
|
||||||
// Read the 'image resources section'
|
// Read the 'image resources section'
|
||||||
CHECK_RET(read_uint(f, &resource_size), 1);
|
CHECK_RET(read_uint(map, length, position, &resource_size));
|
||||||
CHECK_RET(fseek(f, resource_size, SEEK_CUR), 0);
|
*position += resource_size;
|
||||||
|
|
||||||
CHECK_RET(read_uint(f, &misc_info), 1);
|
CHECK_RET(read_uint(map, length, position, &misc_info));
|
||||||
CHECK_RET(fseek(f, misc_info, SEEK_CUR), 0);
|
*position += misc_info;
|
||||||
|
|
||||||
CHECK_RET(read_ushort(f, &compressed), 1);
|
CHECK_RET(read_ushort(map, length, position, &compressed));
|
||||||
|
|
||||||
if (head->channels != 1 || head->depth != 8)
|
if (head->channels != 1 || head->depth != 8)
|
||||||
{
|
{
|
||||||
|
@ -664,7 +685,7 @@ read_psd_indexed(Image_Entry *ie, PSD_Header *head, FILE * f, int *error)
|
||||||
return EINA_FALSE;
|
return EINA_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!psd_get_data(ie, head, f, surface, compressed, error))
|
if (!psd_get_data(ie, head, map, length, position, surface, compressed, error))
|
||||||
return EINA_FALSE;
|
return EINA_FALSE;
|
||||||
return EINA_TRUE;
|
return EINA_TRUE;
|
||||||
|
|
||||||
|
@ -672,28 +693,28 @@ read_psd_indexed(Image_Entry *ie, PSD_Header *head, FILE * f, int *error)
|
||||||
}
|
}
|
||||||
|
|
||||||
Eina_Bool
|
Eina_Bool
|
||||||
read_psd_rgb(Image_Entry *ie, PSD_Header *head, FILE *f, int *error)
|
read_psd_rgb(Image_Entry *ie, PSD_Header *head, const unsigned char *map, size_t length, size_t *position, int *error)
|
||||||
{
|
{
|
||||||
unsigned int color_mode, resource_size, misc_info;
|
unsigned int color_mode, resource_size, misc_info;
|
||||||
unsigned short compressed;
|
unsigned short compressed;
|
||||||
unsigned int type;
|
unsigned int type;
|
||||||
void *surface;
|
void *surface;
|
||||||
|
|
||||||
#define CHECK_RET(Call, Value) \
|
#define CHECK_RET(Call) \
|
||||||
if (Call != Value) return EINA_FALSE;
|
if (!Call) return EINA_FALSE;
|
||||||
|
|
||||||
CHECK_RET(read_uint(f, &color_mode), 1);
|
CHECK_RET(read_uint(map, length, position, &color_mode));
|
||||||
// Skip over the 'color mode data section'
|
// Skip over the 'color mode data section'
|
||||||
CHECK_RET(fseek(f, color_mode, SEEK_CUR), 0);
|
*position += color_mode;
|
||||||
|
|
||||||
// Read the 'image resources section'
|
// Read the 'image resources section'
|
||||||
CHECK_RET(read_uint(f, &resource_size), 1);
|
CHECK_RET(read_uint(map, length, position, &resource_size));
|
||||||
CHECK_RET(fseek(f, resource_size, SEEK_CUR), 0);
|
*position += resource_size;
|
||||||
|
|
||||||
CHECK_RET(read_uint(f, &misc_info), 1);
|
CHECK_RET(read_uint(map, length, position, &misc_info));
|
||||||
CHECK_RET(fseek(f, misc_info, SEEK_CUR), 0);
|
*position += misc_info;
|
||||||
|
|
||||||
CHECK_RET(read_ushort(f, &compressed), 1);
|
CHECK_RET(read_ushort(map, length, position, &compressed));
|
||||||
|
|
||||||
head->channel_num = head->channels;
|
head->channel_num = head->channels;
|
||||||
|
|
||||||
|
@ -722,7 +743,7 @@ read_psd_rgb(Image_Entry *ie, PSD_Header *head, FILE *f, int *error)
|
||||||
goto cleanup_error;
|
goto cleanup_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!psd_get_data(ie, head, f, surface, compressed, error))
|
if (!psd_get_data(ie, head, map, length, position, surface, compressed, error))
|
||||||
goto cleanup_error;
|
goto cleanup_error;
|
||||||
|
|
||||||
evas_common_image_premul(ie);
|
evas_common_image_premul(ie);
|
||||||
|
@ -735,7 +756,7 @@ read_psd_rgb(Image_Entry *ie, PSD_Header *head, FILE *f, int *error)
|
||||||
}
|
}
|
||||||
|
|
||||||
Eina_Bool
|
Eina_Bool
|
||||||
read_psd_cmyk(Image_Entry *ie, PSD_Header *head, FILE *f, int *error)
|
read_psd_cmyk(Image_Entry *ie, PSD_Header *head, const unsigned char *map, size_t length, size_t *position, int *error)
|
||||||
{
|
{
|
||||||
unsigned int color_mode, resource_size, misc_info, size, i, j, data_size;
|
unsigned int color_mode, resource_size, misc_info, size, i, j, data_size;
|
||||||
unsigned short compressed;
|
unsigned short compressed;
|
||||||
|
@ -745,21 +766,21 @@ read_psd_cmyk(Image_Entry *ie, PSD_Header *head, FILE *f, int *error)
|
||||||
|
|
||||||
*error = EVAS_LOAD_ERROR_CORRUPT_FILE;
|
*error = EVAS_LOAD_ERROR_CORRUPT_FILE;
|
||||||
|
|
||||||
#define CHECK_RET(Call, Value) \
|
#define CHECK_RET(Call) \
|
||||||
if (Call != Value) return EINA_FALSE;
|
if (!Call) return EINA_FALSE;
|
||||||
|
|
||||||
CHECK_RET(read_uint(f, &color_mode), 1);
|
CHECK_RET(read_uint(map, length, position, &color_mode));
|
||||||
// Skip over the 'color mode data section'
|
// Skip over the 'color mode data section'
|
||||||
CHECK_RET(fseek(f, color_mode, SEEK_CUR), 0);
|
*position += color_mode;
|
||||||
|
|
||||||
CHECK_RET(read_uint(f, &resource_size), 1);
|
CHECK_RET(read_uint(map, length, position, &resource_size));
|
||||||
// Read the 'image resources section'
|
// Read the 'image resources section'
|
||||||
CHECK_RET(fseek(f, resource_size, SEEK_CUR), 0);
|
*position += resource_size;
|
||||||
|
|
||||||
CHECK_RET(read_uint(f, &misc_info), 1);
|
CHECK_RET(read_uint(map, length, position, &misc_info));
|
||||||
CHECK_RET(fseek(f, misc_info, SEEK_CUR), 0);
|
*position += misc_info;
|
||||||
|
|
||||||
CHECK_RET(read_ushort(f, &compressed), 1);
|
CHECK_RET(read_ushort(map, length, position, &compressed));
|
||||||
|
|
||||||
switch (head->channels)
|
switch (head->channels)
|
||||||
{
|
{
|
||||||
|
@ -804,14 +825,14 @@ read_psd_cmyk(Image_Entry *ie, PSD_Header *head, FILE *f, int *error)
|
||||||
goto cleanup_error;
|
goto cleanup_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!psd_get_data(ie, head, f, surface, compressed, error))
|
if (!psd_get_data(ie, head, map, length, position, surface, compressed, error))
|
||||||
goto cleanup_error;
|
goto cleanup_error;
|
||||||
|
|
||||||
size = type * ie->w * ie->h;
|
size = type * ie->w * ie->h;
|
||||||
kchannel = malloc(size);
|
kchannel = malloc(size);
|
||||||
if (kchannel == NULL)
|
if (kchannel == NULL)
|
||||||
goto cleanup_error;
|
goto cleanup_error;
|
||||||
if (!get_single_channel(ie, head, f, kchannel, compressed))
|
if (!get_single_channel(ie, head, map, length, position, kchannel, compressed))
|
||||||
goto cleanup_error;
|
goto cleanup_error;
|
||||||
|
|
||||||
data_size = head->channels * type * ie->w * ie->h;
|
data_size = head->channels * type * ie->w * ie->h;
|
||||||
|
@ -861,20 +882,34 @@ evas_image_load_file_data_psd(Image_Entry *ie,
|
||||||
const char *key __UNUSED__,
|
const char *key __UNUSED__,
|
||||||
int *error)
|
int *error)
|
||||||
{
|
{
|
||||||
FILE *f;
|
Eina_File *f;
|
||||||
|
void *map;
|
||||||
|
size_t length;
|
||||||
|
size_t position;
|
||||||
PSD_Header header;
|
PSD_Header header;
|
||||||
Eina_Bool bpsd = EINA_FALSE;
|
Eina_Bool bpsd = EINA_FALSE;
|
||||||
|
|
||||||
f = fopen(file, "rb");
|
f = eina_file_open(file, 0);
|
||||||
if (f == NULL)
|
if (f == NULL)
|
||||||
{
|
{
|
||||||
*error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
|
*error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
|
||||||
return bpsd;
|
return bpsd;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!psd_get_header(&header, f) || !is_psd(&header))
|
map = eina_file_map_all(f, EINA_FILE_SEQUENTIAL);
|
||||||
|
length = eina_file_size_get(f);
|
||||||
|
position = 0;
|
||||||
|
if (!map || length < 1)
|
||||||
{
|
{
|
||||||
fclose(f);
|
eina_file_close(f);
|
||||||
|
*error = EVAS_LOAD_ERROR_CORRUPT_FILE;
|
||||||
|
return EINA_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!psd_get_header(&header, map, length, &position) || !is_psd(&header))
|
||||||
|
{
|
||||||
|
eina_file_map_free(f, map);
|
||||||
|
eina_file_close(f);
|
||||||
*error = EVAS_LOAD_ERROR_GENERIC;
|
*error = EVAS_LOAD_ERROR_GENERIC;
|
||||||
return EINA_FALSE;
|
return EINA_FALSE;
|
||||||
}
|
}
|
||||||
|
@ -887,39 +922,39 @@ evas_image_load_file_data_psd(Image_Entry *ie,
|
||||||
switch (header.mode)
|
switch (header.mode)
|
||||||
{
|
{
|
||||||
case PSD_GREYSCALE: // Greyscale
|
case PSD_GREYSCALE: // Greyscale
|
||||||
bpsd = read_psd_grey(ie, &header, f, error);
|
bpsd = read_psd_grey(ie, &header, map, length, &position, error);
|
||||||
break;
|
break;
|
||||||
case PSD_INDEXED: // Indexed
|
case PSD_INDEXED: // Indexed
|
||||||
bpsd = read_psd_indexed(ie, &header, f, error);
|
bpsd = read_psd_indexed(ie, &header, map, length, &position, error);
|
||||||
break;
|
break;
|
||||||
case PSD_RGB: // RGB
|
case PSD_RGB: // RGB
|
||||||
bpsd = read_psd_rgb(ie, &header, f, error);
|
bpsd = read_psd_rgb(ie, &header, map, length, &position, error);
|
||||||
break;
|
break;
|
||||||
case PSD_CMYK: // CMYK
|
case PSD_CMYK: // CMYK
|
||||||
bpsd = read_psd_cmyk(ie, &header, f, error);
|
bpsd = read_psd_cmyk(ie, &header, map, length, &position, error);
|
||||||
break;
|
break;
|
||||||
default :
|
default :
|
||||||
*error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
|
*error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
|
||||||
bpsd = EINA_FALSE;
|
bpsd = EINA_FALSE;
|
||||||
}
|
}
|
||||||
fclose(f);
|
|
||||||
|
eina_file_map_free(f, map);
|
||||||
|
eina_file_close(f);
|
||||||
|
|
||||||
return bpsd;
|
return bpsd;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Eina_Bool
|
static Eina_Bool
|
||||||
get_compressed_channels_length(PSD_Header *head,
|
get_compressed_channels_length(PSD_Header *head,
|
||||||
FILE * file,
|
const unsigned char *map, size_t length, size_t *position,
|
||||||
unsigned short *rle_table,
|
unsigned short *rle_table,
|
||||||
unsigned int *chanlen)
|
unsigned int *chanlen)
|
||||||
{
|
{
|
||||||
unsigned int j;
|
unsigned int j;
|
||||||
unsigned int c;
|
unsigned int c;
|
||||||
|
|
||||||
if (fread(rle_table,
|
if (!read_block(map, length, position, rle_table,
|
||||||
sizeof(unsigned short),
|
sizeof (unsigned short) * head->height * head->channel_num))
|
||||||
head->height * head->channel_num,
|
|
||||||
file) != head->height * head->channel_num)
|
|
||||||
return EINA_FALSE;
|
return EINA_FALSE;
|
||||||
|
|
||||||
memset(chanlen, 0, head->channel_num * sizeof(unsigned int));
|
memset(chanlen, 0, head->channel_num * sizeof(unsigned int));
|
||||||
|
|
Loading…
Reference in New Issue