forked from enlightenment/efl
Add eet_data_image_read_to_surface and eet_data_image_decode_to_surface.
This functions provide a way to support tiles with eet. They also give the possibility to directly decompress eet image inside an engine surface. SVN revision: 34725
This commit is contained in:
parent
03109fff6c
commit
2b37d10029
|
@ -469,6 +469,45 @@ extern "C" {
|
||||||
*/
|
*/
|
||||||
EAPI void *eet_data_image_read(Eet_File *ef, const char *name, unsigned int *w, unsigned int *h, int *alpha, int *compress, int *quality, int *lossy);
|
EAPI void *eet_data_image_read(Eet_File *ef, const char *name, unsigned int *w, unsigned int *h, int *alpha, int *compress, int *quality, int *lossy);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read image data from the named key in the eet file.
|
||||||
|
* @param ef A valid eet file handle opened for reading.
|
||||||
|
* @param name Name of the entry. eg: "/base/file_i_want".
|
||||||
|
* @param src_x The starting x coordinate from where to dump the stream.
|
||||||
|
* @param src_y The starting y coordinate from where to dump the stream.
|
||||||
|
* @param d A pointer to the pixel surface.
|
||||||
|
* @param w The expected width in pixels of the pixel surface to decode.
|
||||||
|
* @param h The expected height in pixels of the pixel surface to decode.
|
||||||
|
* @param row_stride The length of a pixels line in the destination surface.
|
||||||
|
* @param alpha A pointer to the int to hold the alpha flag.
|
||||||
|
* @param compress A pointer to the int to hold the compression amount.
|
||||||
|
* @param quality A pointer to the int to hold the quality amount.
|
||||||
|
* @param lossy A pointer to the int to hold the lossiness flag.
|
||||||
|
* @return 1 on success, 0 otherwise.
|
||||||
|
*
|
||||||
|
* This function reads an image from an eet file stored under the named
|
||||||
|
* key in the eet file and return a pointer to the decompressed pixel data.
|
||||||
|
*
|
||||||
|
* The other parameters of the image (width, height etc.) are placed into
|
||||||
|
* the values pointed to (they must be supplied). The pixel data is a linear
|
||||||
|
* array of pixels starting from the top-left of the image scanning row by
|
||||||
|
* row from left to right. Each pile is a 32bit value, with the high byte
|
||||||
|
* being the alpha channel, the next being red, then green, and the low byte
|
||||||
|
* being blue. The width and height are measured in pixels and will be
|
||||||
|
* greater than 0 when returned. The alpha flag is either 0 or 1. 0 denotes
|
||||||
|
* that the alpha channel is not used. 1 denotes that it is significant.
|
||||||
|
* Compress is filled with the compression value/amount the image was
|
||||||
|
* stored with. The quality value is filled with the quality encoding of
|
||||||
|
* the image file (0 - 100). The lossy flags is either 0 or 1 as to if
|
||||||
|
* the image was encoded lossily or not.
|
||||||
|
*
|
||||||
|
* On success the function returns 1, and 0 on failure. On failure the
|
||||||
|
* parameter values may not contain any sensible data.
|
||||||
|
*
|
||||||
|
* @since 1.0.2
|
||||||
|
*/
|
||||||
|
EAPI int eet_data_image_read_to_surface(Eet_File *ef, const char *name, unsigned int src_x, unsigned int src_y, unsigned int *d, unsigned int w, unsigned int h, unsigned int row_stride, int *alpha, int *compress, int *quality, int *lossy);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Write image data to the named key in an eet file.
|
* Write image data to the named key in an eet file.
|
||||||
* @param ef A valid eet file handle opened for writing.
|
* @param ef A valid eet file handle opened for writing.
|
||||||
|
@ -575,6 +614,45 @@ extern "C" {
|
||||||
*/
|
*/
|
||||||
EAPI void *eet_data_image_decode(const void *data, int size, unsigned int *w, unsigned int *h, int *alpha, int *compress, int *quality, int *lossy);
|
EAPI void *eet_data_image_decode(const void *data, int size, unsigned int *w, unsigned int *h, int *alpha, int *compress, int *quality, int *lossy);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decode Image data into pixel data.
|
||||||
|
* @param data The encoded pixel data.
|
||||||
|
* @param size The size, in bytes, of the encoded pixel data.
|
||||||
|
* @param src_x The starting x coordinate from where to dump the stream.
|
||||||
|
* @param src_y The starting y coordinate from where to dump the stream.
|
||||||
|
* @param d A pointer to the pixel surface.
|
||||||
|
* @param w The expected width in pixels of the pixel surface to decode.
|
||||||
|
* @param h The expected height in pixels of the pixel surface to decode.
|
||||||
|
* @param row_stride The length of a pixels line in the destination surface.
|
||||||
|
* @param alpha A pointer to the int to hold the alpha flag.
|
||||||
|
* @param compress A pointer to the int to hold the compression amount.
|
||||||
|
* @param quality A pointer to the int to hold the quality amount.
|
||||||
|
* @param lossy A pointer to the int to hold the lossiness flag.
|
||||||
|
* @return 1 on success, 0 otherwise.
|
||||||
|
*
|
||||||
|
* This function takes encoded pixel data and decodes it into raw RGBA
|
||||||
|
* pixels on success.
|
||||||
|
*
|
||||||
|
* The other parameters of the image (alpha, compress etc.) are placed into
|
||||||
|
* the values pointed to (they must be supplied). The pixel data is a linear
|
||||||
|
* array of pixels starting from the top-left of the image scanning row by
|
||||||
|
* row from left to right. Each pixel is a 32bit value, with the high byte
|
||||||
|
* being the alpha channel, the next being red, then green, and the low byte
|
||||||
|
* being blue. The width and height are measured in pixels and will be
|
||||||
|
* greater than 0 when returned. The alpha flag is either 0 or 1. 0 denotes
|
||||||
|
* that the alpha channel is not used. 1 denotes that it is significant.
|
||||||
|
* Compress is filled with the compression value/amount the image was
|
||||||
|
* stored with. The quality value is filled with the quality encoding of
|
||||||
|
* the image file (0 - 100). The lossy flags is either 0 or 1 as to if
|
||||||
|
* the image was encoded lossily or not.
|
||||||
|
*
|
||||||
|
* On success the function returns 1, and 0 on failure. On failure the
|
||||||
|
* parameter values may not contain any sensible data.
|
||||||
|
*
|
||||||
|
* @since 1.0.2
|
||||||
|
*/
|
||||||
|
EAPI int eet_data_image_decode_to_surface(const void *data, int size, unsigned int src_x, unsigned int src_y, unsigned int *d, unsigned int w, unsigned int h, unsigned int row_stride, int *alpha, int *compress, int *quality, int *lossy);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Encode image data for storage or transmission.
|
* Encode image data for storage or transmission.
|
||||||
* @param data A pointer to the image pixel data.
|
* @param data A pointer to the image pixel data.
|
||||||
|
|
|
@ -55,8 +55,8 @@ static void _JPEGErrorHandler(j_common_ptr cinfo);
|
||||||
static void _JPEGErrorHandler2(j_common_ptr cinfo, int msg_level);
|
static void _JPEGErrorHandler2(j_common_ptr cinfo, int msg_level);
|
||||||
|
|
||||||
static int eet_data_image_jpeg_header_decode(const void *data, int size, unsigned int *w, unsigned int *h);
|
static int eet_data_image_jpeg_header_decode(const void *data, int size, unsigned int *w, unsigned int *h);
|
||||||
static void *eet_data_image_jpeg_rgb_decode(const void *data, int size, unsigned int *w, unsigned int *h);
|
static int eet_data_image_jpeg_rgb_decode(const void *data, int size, unsigned int src_x, unsigned int src_y, unsigned int *d, unsigned int w, unsigned int h, unsigned int row_stride);
|
||||||
static void *eet_data_image_jpeg_alpha_decode(const void *data, int size, unsigned int *d, unsigned int *w, unsigned int *h);
|
static void *eet_data_image_jpeg_alpha_decode(const void *data, int size, unsigned int src_x, unsigned int src_y, unsigned int *d, unsigned int w, unsigned int h, unsigned int row_stride);
|
||||||
static void *eet_data_image_lossless_convert(int *size, const void *data, unsigned int w, unsigned int h, int alpha);
|
static void *eet_data_image_lossless_convert(int *size, const void *data, unsigned int w, unsigned int h, int alpha);
|
||||||
static void *eet_data_image_lossless_compressed_convert(int *size, const void *data, unsigned int w, unsigned int h, int alpha, int compression);
|
static void *eet_data_image_lossless_compressed_convert(int *size, const void *data, unsigned int w, unsigned int h, int alpha, int compression);
|
||||||
static void *eet_data_image_jpeg_convert(int *size, const void *data, unsigned int w, unsigned int h, int alpha, int quality);
|
static void *eet_data_image_jpeg_convert(int *size, const void *data, unsigned int w, unsigned int h, int alpha, int quality);
|
||||||
|
@ -168,20 +168,24 @@ eet_data_image_jpeg_header_decode(const void *data, int size, unsigned int *w, u
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *
|
static int
|
||||||
eet_data_image_jpeg_rgb_decode(const void *data, int size, unsigned int *w, unsigned int *h)
|
eet_data_image_jpeg_rgb_decode(const void *data, int size, unsigned int src_x, unsigned int src_y,
|
||||||
|
unsigned int *d, unsigned int w, unsigned int h, unsigned int row_stride)
|
||||||
{
|
{
|
||||||
unsigned int *d;
|
|
||||||
struct jpeg_decompress_struct cinfo;
|
struct jpeg_decompress_struct cinfo;
|
||||||
struct _JPEG_error_mgr jerr;
|
struct _JPEG_error_mgr jerr;
|
||||||
unsigned char *ptr, *line[16], *tdata = NULL;
|
unsigned char *ptr, *line[16], *tdata = NULL;
|
||||||
unsigned int *ptr2;
|
unsigned int *ptr2, *tmp;
|
||||||
unsigned int x, y, l, scans;
|
unsigned int iw, ih;
|
||||||
|
int x, y, l, scans;
|
||||||
int i, count, prevy;
|
int i, count, prevy;
|
||||||
FILE *f;
|
FILE *f;
|
||||||
|
|
||||||
|
/* FIXME: handle src_x, src_y and row_stride correctly */
|
||||||
|
if (!d) return 0;
|
||||||
|
|
||||||
f = _eet_memfile_read_open(data, (size_t)size);
|
f = _eet_memfile_read_open(data, (size_t)size);
|
||||||
if (!f) return NULL;
|
if (!f) return 0;
|
||||||
cinfo.err = jpeg_std_error(&(jerr.pub));
|
cinfo.err = jpeg_std_error(&(jerr.pub));
|
||||||
jerr.pub.error_exit = _JPEGFatalErrorHandler;
|
jerr.pub.error_exit = _JPEGFatalErrorHandler;
|
||||||
jerr.pub.emit_message = _JPEGErrorHandler2;
|
jerr.pub.emit_message = _JPEGErrorHandler2;
|
||||||
|
@ -191,7 +195,7 @@ eet_data_image_jpeg_rgb_decode(const void *data, int size, unsigned int *w, unsi
|
||||||
if (tdata) free(tdata);
|
if (tdata) free(tdata);
|
||||||
jpeg_destroy_decompress(&cinfo);
|
jpeg_destroy_decompress(&cinfo);
|
||||||
_eet_memfile_read_close(f);
|
_eet_memfile_read_close(f);
|
||||||
return NULL;
|
return 0;
|
||||||
}
|
}
|
||||||
jpeg_create_decompress(&cinfo);
|
jpeg_create_decompress(&cinfo);
|
||||||
jpeg_stdio_src(&cinfo, f);
|
jpeg_stdio_src(&cinfo, f);
|
||||||
|
@ -202,13 +206,13 @@ eet_data_image_jpeg_rgb_decode(const void *data, int size, unsigned int *w, unsi
|
||||||
jpeg_start_decompress(&cinfo);
|
jpeg_start_decompress(&cinfo);
|
||||||
|
|
||||||
/* head decoding */
|
/* head decoding */
|
||||||
*w = cinfo.output_width;
|
iw = cinfo.output_width;
|
||||||
*h = cinfo.output_height;
|
ih = cinfo.output_height;
|
||||||
if ((*w < 1) || (*h < 1) || (*w > 8192) || (*h > 8192))
|
if ((iw != w) || (ih != h))
|
||||||
{
|
{
|
||||||
jpeg_destroy_decompress(&cinfo);
|
jpeg_destroy_decompress(&cinfo);
|
||||||
_eet_memfile_read_close(f);
|
_eet_memfile_read_close(f);
|
||||||
return NULL;
|
return 0;
|
||||||
}
|
}
|
||||||
/* end head decoding */
|
/* end head decoding */
|
||||||
/* data decoding */
|
/* data decoding */
|
||||||
|
@ -216,60 +220,82 @@ eet_data_image_jpeg_rgb_decode(const void *data, int size, unsigned int *w, unsi
|
||||||
{
|
{
|
||||||
jpeg_destroy_decompress(&cinfo);
|
jpeg_destroy_decompress(&cinfo);
|
||||||
_eet_memfile_read_close(f);
|
_eet_memfile_read_close(f);
|
||||||
return NULL;
|
return 0;
|
||||||
}
|
|
||||||
tdata = alloca((*w) * 16 * 3);
|
|
||||||
d = malloc((*w) * (*h) * 4);
|
|
||||||
if (!d)
|
|
||||||
{
|
|
||||||
jpeg_destroy_decompress(&cinfo);
|
|
||||||
_eet_memfile_read_close(f);
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
tdata = alloca((iw) * 16 * 3);
|
||||||
ptr2 = d;
|
ptr2 = d;
|
||||||
count = 0;
|
count = 0;
|
||||||
prevy = 0;
|
prevy = 0;
|
||||||
|
|
||||||
if (cinfo.output_components == 3)
|
if (cinfo.output_components == 3)
|
||||||
{
|
{
|
||||||
for (i = 0; i < cinfo.rec_outbuf_height; i++)
|
for (i = 0; i < cinfo.rec_outbuf_height; i++)
|
||||||
line[i] = tdata + (i * (*w) * 3);
|
line[i] = tdata + (i * (iw) * 3);
|
||||||
for (l = 0; l < (*h); l += cinfo.rec_outbuf_height)
|
for (l = 0; l < ih; l += cinfo.rec_outbuf_height)
|
||||||
{
|
{
|
||||||
jpeg_read_scanlines(&cinfo, line, cinfo.rec_outbuf_height);
|
jpeg_read_scanlines(&cinfo, line, cinfo.rec_outbuf_height);
|
||||||
scans = cinfo.rec_outbuf_height;
|
scans = cinfo.rec_outbuf_height;
|
||||||
if (((*h) - l) < scans) scans = (*h) - l;
|
if ((ih - l) < scans) scans = ih - l;
|
||||||
ptr = tdata;
|
ptr = tdata;
|
||||||
for (y = 0; y < scans; y++)
|
|
||||||
|
if (l + scans >= src_y && l < src_y + h)
|
||||||
{
|
{
|
||||||
for (x = 0; x < (*w); x++)
|
y = src_y - l;
|
||||||
|
if (y < 0) y = 0;
|
||||||
|
for (ptr += 3 * iw * y; y < scans && (y + l) < (src_y + h); y++)
|
||||||
|
{
|
||||||
|
tmp = ptr2;
|
||||||
|
ptr += 3 * src_x;
|
||||||
|
for (x = 0; x < w; x++)
|
||||||
{
|
{
|
||||||
*ptr2 =
|
*ptr2 =
|
||||||
(0xff000000) | ((ptr[0]) << 16) | ((ptr[1]) << 8) | (ptr[2]);
|
(0xff000000) | ((ptr[0]) << 16) | ((ptr[1]) << 8) | (ptr[2]);
|
||||||
ptr += 3;
|
ptr += 3;
|
||||||
ptr2++;
|
ptr2++;
|
||||||
}
|
}
|
||||||
|
ptr += 3 * (iw - w);
|
||||||
|
ptr2 = tmp + row_stride / 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ptr += 3 * iw * scans;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (cinfo.output_components == 1)
|
else if (cinfo.output_components == 1)
|
||||||
{
|
{
|
||||||
for (i = 0; i < cinfo.rec_outbuf_height; i++)
|
for (i = 0; i < cinfo.rec_outbuf_height; i++)
|
||||||
line[i] = tdata + (i * (*w));
|
line[i] = tdata + (i * (iw));
|
||||||
for (l = 0; l < (*h); l += cinfo.rec_outbuf_height)
|
for (l = 0; l < (ih); l += cinfo.rec_outbuf_height)
|
||||||
{
|
{
|
||||||
jpeg_read_scanlines(&cinfo, line, cinfo.rec_outbuf_height);
|
jpeg_read_scanlines(&cinfo, line, cinfo.rec_outbuf_height);
|
||||||
scans = cinfo.rec_outbuf_height;
|
scans = cinfo.rec_outbuf_height;
|
||||||
if (((*h) - l) < scans) scans = (*h) - l;
|
if (((ih) - l) < scans) scans = (ih) - l;
|
||||||
ptr = tdata;
|
ptr = tdata;
|
||||||
for (y = 0; y < scans; y++)
|
|
||||||
|
if (l >= src_y && l < src_y + h)
|
||||||
{
|
{
|
||||||
for (x = 0; x < (*w); x++)
|
y = src_y - l;
|
||||||
|
if (y < 0) y = 0;
|
||||||
|
for (ptr += iw * y; y < scans && (y + l) < (src_y + h); y++)
|
||||||
|
{
|
||||||
|
tmp = ptr2;
|
||||||
|
ptr += src_x;
|
||||||
|
for (x = 0; x < w; x++)
|
||||||
{
|
{
|
||||||
*ptr2 =
|
*ptr2 =
|
||||||
(0xff000000) | ((ptr[0]) << 16) | ((ptr[0]) << 8) | (ptr[0]);
|
(0xff000000) | ((ptr[0]) << 16) | ((ptr[0]) << 8) | (ptr[0]);
|
||||||
ptr++;
|
ptr++;
|
||||||
ptr2++;
|
ptr2++;
|
||||||
}
|
}
|
||||||
|
ptr += iw - w;
|
||||||
|
ptr2 = tmp + row_stride / 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ptr += iw * scans;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -277,18 +303,19 @@ eet_data_image_jpeg_rgb_decode(const void *data, int size, unsigned int *w, unsi
|
||||||
jpeg_finish_decompress(&cinfo);
|
jpeg_finish_decompress(&cinfo);
|
||||||
jpeg_destroy_decompress(&cinfo);
|
jpeg_destroy_decompress(&cinfo);
|
||||||
_eet_memfile_read_close(f);
|
_eet_memfile_read_close(f);
|
||||||
return d;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *
|
static void *
|
||||||
eet_data_image_jpeg_alpha_decode(const void *data, int size, unsigned int *d, unsigned int *w, unsigned int *h)
|
eet_data_image_jpeg_alpha_decode(const void *data, int size, unsigned int src_x, unsigned int src_y,
|
||||||
|
unsigned int *d, unsigned int w, unsigned int h, unsigned int row_stride)
|
||||||
{
|
{
|
||||||
struct jpeg_decompress_struct cinfo;
|
struct jpeg_decompress_struct cinfo;
|
||||||
struct _JPEG_error_mgr jerr;
|
struct _JPEG_error_mgr jerr;
|
||||||
unsigned char *ptr, *line[16], *tdata = NULL;
|
unsigned char *ptr, *line[16], *tdata = NULL;
|
||||||
unsigned int *ptr2;
|
unsigned int *ptr2, *tmp;
|
||||||
unsigned int x, y, l, scans;
|
int x, y, l, scans;
|
||||||
int i, count, prevy;
|
int i, count, prevy, iw;
|
||||||
FILE *f;
|
FILE *f;
|
||||||
|
|
||||||
f = _eet_memfile_read_open(data, (size_t)size);
|
f = _eet_memfile_read_open(data, (size_t)size);
|
||||||
|
@ -322,20 +349,14 @@ eet_data_image_jpeg_alpha_decode(const void *data, int size, unsigned int *d, un
|
||||||
jpeg_start_decompress(&cinfo);
|
jpeg_start_decompress(&cinfo);
|
||||||
|
|
||||||
/* head decoding */
|
/* head decoding */
|
||||||
if ((*w) != cinfo.output_width)
|
iw = cinfo.output_width;
|
||||||
|
if (w != cinfo.output_width
|
||||||
|
|| h != cinfo.output_height)
|
||||||
{
|
{
|
||||||
jpeg_destroy_decompress(&cinfo);
|
jpeg_destroy_decompress(&cinfo);
|
||||||
_eet_memfile_read_close(f);
|
_eet_memfile_read_close(f);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if ((*h) != cinfo.output_height)
|
|
||||||
{
|
|
||||||
jpeg_destroy_decompress(&cinfo);
|
|
||||||
_eet_memfile_read_close(f);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
*w = cinfo.output_width;
|
|
||||||
*h = cinfo.output_height;
|
|
||||||
/* end head decoding */
|
/* end head decoding */
|
||||||
/* data decoding */
|
/* data decoding */
|
||||||
if (cinfo.rec_outbuf_height > 16)
|
if (cinfo.rec_outbuf_height > 16)
|
||||||
|
@ -344,23 +365,30 @@ eet_data_image_jpeg_alpha_decode(const void *data, int size, unsigned int *d, un
|
||||||
_eet_memfile_read_close(f);
|
_eet_memfile_read_close(f);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
tdata = alloca((*w) * 16 * 3);
|
tdata = alloca(w * 16 * 3);
|
||||||
ptr2 = d;
|
ptr2 = d;
|
||||||
count = 0;
|
count = 0;
|
||||||
prevy = 0;
|
prevy = 0;
|
||||||
if (cinfo.output_components == 1)
|
if (cinfo.output_components == 1)
|
||||||
{
|
{
|
||||||
for (i = 0; i < cinfo.rec_outbuf_height; i++)
|
for (i = 0; i < cinfo.rec_outbuf_height; i++)
|
||||||
line[i] = tdata + (i * (*w));
|
line[i] = tdata + (i * w);
|
||||||
for (l = 0; l < (*h); l += cinfo.rec_outbuf_height)
|
for (l = 0; l < h; l += cinfo.rec_outbuf_height)
|
||||||
{
|
{
|
||||||
jpeg_read_scanlines(&cinfo, line, cinfo.rec_outbuf_height);
|
jpeg_read_scanlines(&cinfo, line, cinfo.rec_outbuf_height);
|
||||||
scans = cinfo.rec_outbuf_height;
|
scans = cinfo.rec_outbuf_height;
|
||||||
if (((*h) - l) < scans) scans = (*h) - l;
|
if ((h - l) < scans) scans = h - l;
|
||||||
ptr = tdata;
|
ptr = tdata;
|
||||||
for (y = 0; y < scans; y++)
|
|
||||||
|
if (l >= src_y && l < src_y + h)
|
||||||
{
|
{
|
||||||
for (x = 0; x < (*w); x++)
|
y = src_y - l;
|
||||||
|
if (y < 0) y = 0;
|
||||||
|
for (ptr += iw * y; y < scans && (y + l) < (src_y + h); y++)
|
||||||
|
{
|
||||||
|
tmp = ptr2;
|
||||||
|
ptr += src_x;
|
||||||
|
for (x = 0; x < w; x++)
|
||||||
{
|
{
|
||||||
*ptr2 =
|
*ptr2 =
|
||||||
((*ptr2) & 0x00ffffff) |
|
((*ptr2) & 0x00ffffff) |
|
||||||
|
@ -368,6 +396,13 @@ eet_data_image_jpeg_alpha_decode(const void *data, int size, unsigned int *d, un
|
||||||
ptr++;
|
ptr++;
|
||||||
ptr2++;
|
ptr2++;
|
||||||
}
|
}
|
||||||
|
ptr += iw - w;
|
||||||
|
ptr2 = tmp + row_stride / 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ptr += iw * scans;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -785,6 +820,33 @@ eet_data_image_read(Eet_File *ef, const char *name,
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EAPI int
|
||||||
|
eet_data_image_read_to_surface(Eet_File *ef, const char *name, unsigned int src_x, unsigned int src_y,
|
||||||
|
unsigned int *d, unsigned int w, unsigned int h, unsigned int row_stride,
|
||||||
|
int *alpha, int *compress, int *quality, int *lossy)
|
||||||
|
{
|
||||||
|
void *data;
|
||||||
|
int size;
|
||||||
|
int free_data = 0;
|
||||||
|
int res = 1;
|
||||||
|
|
||||||
|
|
||||||
|
data = (void *)eet_read_direct(ef, name, &size);
|
||||||
|
if (!data)
|
||||||
|
{
|
||||||
|
data = eet_read(ef, name, &size);
|
||||||
|
free_data = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!data) return 0;
|
||||||
|
res = eet_data_image_decode_to_surface(data, size, src_x, src_y, d, w, h, row_stride, alpha, compress, quality, lossy);
|
||||||
|
|
||||||
|
if (free_data)
|
||||||
|
free(data);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
EAPI int
|
EAPI int
|
||||||
eet_data_image_header_read(Eet_File *ef, const char *name,
|
eet_data_image_header_read(Eet_File *ef, const char *name,
|
||||||
unsigned int *w, unsigned int *h, int *alpha,
|
unsigned int *w, unsigned int *h, int *alpha,
|
||||||
|
@ -869,7 +931,7 @@ eet_data_image_header_decode(const void *data, int size, unsigned int *w, unsign
|
||||||
if ((cp == 0) && (size < ((iw * ih * 4) + 32))) return 0;
|
if ((cp == 0) && (size < ((iw * ih * 4) + 32))) return 0;
|
||||||
if (w) *w = iw;
|
if (w) *w = iw;
|
||||||
if (h) *h = ih;
|
if (h) *h = ih;
|
||||||
if (alpha) *alpha = al;
|
if (alpha) *alpha = al ? 1 : 0;
|
||||||
if (compress) *compress = cp;
|
if (compress) *compress = cp;
|
||||||
if (lossy) *lossy = 0;
|
if (lossy) *lossy = 0;
|
||||||
if (quality) *quality = 100;
|
if (quality) *quality = 100;
|
||||||
|
@ -918,22 +980,84 @@ eet_data_image_header_decode(const void *data, int size, unsigned int *w, unsign
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
EAPI void *
|
static void
|
||||||
eet_data_image_decode(const void *data, int size, unsigned int *w, unsigned int *h, int *alpha, int *compress, int *quality, int *lossy)
|
_eet_data_image_copy_buffer(const unsigned int *src, unsigned int src_x, unsigned int src_y, unsigned int src_w,
|
||||||
|
unsigned int *dst, unsigned int w, unsigned int h, unsigned int row_stride)
|
||||||
{
|
{
|
||||||
unsigned int *d = NULL;
|
src += src_x + src_y * src_w;
|
||||||
int header[8];
|
|
||||||
|
|
||||||
if (words_bigendian == -1)
|
if (row_stride == src_w * 4 && w == src_w)
|
||||||
{
|
{
|
||||||
unsigned long int v;
|
memcpy(dst, src, row_stride * h);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
unsigned int *over = dst;
|
||||||
|
unsigned int y;
|
||||||
|
|
||||||
v = htonl(0x12345678);
|
for (y = 0; y < h; ++y, src += src_w, over += row_stride)
|
||||||
if (v == 0x12345678) words_bigendian = 1;
|
memcpy(over, src, w * 4);
|
||||||
else words_bigendian = 0;
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
_eet_data_image_decode_inside(const void *data, int size, unsigned int src_x, unsigned int src_y,
|
||||||
|
unsigned int src_w, unsigned int src_h,
|
||||||
|
unsigned int *d, unsigned int w, unsigned int h, unsigned int row_stride,
|
||||||
|
int alpha, int compress, int quality, int lossy)
|
||||||
|
{
|
||||||
|
if (lossy == 0 && quality == 100)
|
||||||
|
{
|
||||||
|
unsigned int *body;
|
||||||
|
|
||||||
|
body = ((unsigned int *)data) + 8;
|
||||||
|
if (!compress)
|
||||||
|
{
|
||||||
|
_eet_data_image_copy_buffer(body, src_x, src_y, src_w, d, w, h, row_stride);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (src_h == h && src_w == w && row_stride == src_w * 4)
|
||||||
|
{
|
||||||
|
uLongf dlen;
|
||||||
|
|
||||||
|
dlen = w * h * 4;
|
||||||
|
uncompress((Bytef *)d, &dlen, (Bytef *)body,
|
||||||
|
(uLongf)(size - 32));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Bytef *dtmp;
|
||||||
|
uLongf dlen = src_w * src_h * 4;
|
||||||
|
|
||||||
|
/* FIXME: This could create a huge alloc. So compressed data and tile could not always work. */
|
||||||
|
dtmp = malloc(dlen);
|
||||||
|
if (!dtmp) return 0;
|
||||||
|
|
||||||
|
uncompress(dtmp, &dlen, (Bytef *)body, (uLongf)(size - 32));
|
||||||
|
|
||||||
|
_eet_data_image_copy_buffer((unsigned int *) dtmp, src_x, src_y, src_w, d, w, h, row_stride);
|
||||||
|
|
||||||
|
free(dtmp);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (size < 32) return NULL;
|
/* Fix swapiness. */
|
||||||
|
if (words_bigendian)
|
||||||
|
{
|
||||||
|
unsigned int x;
|
||||||
|
|
||||||
|
for (x = 0; x < (w * h); x++) SWAP32(d[x]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (compress == 0 && lossy == 1)
|
||||||
|
{
|
||||||
|
if (alpha)
|
||||||
|
{
|
||||||
|
unsigned const char *dt;
|
||||||
|
int header[8];
|
||||||
|
int sz1, sz2;
|
||||||
|
|
||||||
memcpy(header, data, 32);
|
memcpy(header, data, 32);
|
||||||
if (words_bigendian)
|
if (words_bigendian)
|
||||||
|
@ -942,94 +1066,86 @@ eet_data_image_decode(const void *data, int size, unsigned int *w, unsigned int
|
||||||
|
|
||||||
for (i = 0; i < 8; i++) SWAP32(header[i]);
|
for (i = 0; i < 8; i++) SWAP32(header[i]);
|
||||||
}
|
}
|
||||||
if ((unsigned)header[0] == 0xac1dfeed)
|
|
||||||
{
|
|
||||||
int iw, ih, al, cp;
|
|
||||||
unsigned int *body;
|
|
||||||
|
|
||||||
iw = header[1];
|
|
||||||
ih = header[2];
|
|
||||||
al = header[3];
|
|
||||||
cp = header[4];
|
|
||||||
if ((iw > 8192) || (ih > 8192)) return NULL;
|
|
||||||
if ((cp == 0) && (size < ((iw * ih * 4) + 32))) return NULL;
|
|
||||||
body = ((unsigned int *)data) + 8;
|
|
||||||
d = malloc(iw * ih * 4);
|
|
||||||
if (!d) return NULL;
|
|
||||||
if (!cp)
|
|
||||||
{
|
|
||||||
memcpy(d, body, iw * ih * 4);
|
|
||||||
if (words_bigendian)
|
|
||||||
{
|
|
||||||
int x;
|
|
||||||
|
|
||||||
for (x = 0; x < (iw * ih); x++) SWAP32(d[x]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
uLongf dlen;
|
|
||||||
|
|
||||||
dlen = iw * ih * 4;
|
|
||||||
uncompress((Bytef *)d, &dlen, (Bytef *)body,
|
|
||||||
(uLongf)(size - 32));
|
|
||||||
if (words_bigendian)
|
|
||||||
{
|
|
||||||
int x;
|
|
||||||
|
|
||||||
for (x = 0; x < (iw * ih); x++) SWAP32(d[x]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (d)
|
|
||||||
{
|
|
||||||
if (w) *w = iw;
|
|
||||||
if (h) *h = ih;
|
|
||||||
if (alpha) *alpha = al;
|
|
||||||
if (compress) *compress = cp;
|
|
||||||
if (lossy) *lossy = 0;
|
|
||||||
if (quality) *quality = 100;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if ((unsigned)header[0] == 0xbeeff00d)
|
|
||||||
{
|
|
||||||
unsigned int iw = 0, ih = 0;
|
|
||||||
unsigned const char *dt;
|
|
||||||
int sz1, sz2;
|
|
||||||
|
|
||||||
sz1 = header[1];
|
sz1 = header[1];
|
||||||
sz2 = header[2];
|
sz2 = header[2];
|
||||||
dt = data;
|
dt = data;
|
||||||
dt += 12;
|
dt += 12;
|
||||||
d = eet_data_image_jpeg_rgb_decode(dt, sz1, &iw, &ih);
|
|
||||||
if (d)
|
if (eet_data_image_jpeg_rgb_decode(dt, sz1, src_x, src_y, d, w, h, row_stride))
|
||||||
{
|
{
|
||||||
dt += sz1;
|
dt += sz1;
|
||||||
eet_data_image_jpeg_alpha_decode(dt, sz2, d, &iw, &ih);
|
if (!eet_data_image_jpeg_alpha_decode(dt, sz2, src_x, src_y, d, w, h, row_stride))
|
||||||
}
|
return 0;
|
||||||
if (d)
|
|
||||||
{
|
|
||||||
if (w) *w = iw;
|
|
||||||
if (h) *h = ih;
|
|
||||||
if (alpha) *alpha = 1;
|
|
||||||
if (compress) *compress = 0;
|
|
||||||
if (lossy) *lossy = 1;
|
|
||||||
if (quality) *quality = 75;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
unsigned int iw = 0, ih = 0;
|
if (!eet_data_image_jpeg_rgb_decode(data, size, src_x, src_y, d, w, h, row_stride))
|
||||||
|
return 0;
|
||||||
d = eet_data_image_jpeg_rgb_decode(data, size, &iw, &ih);
|
}
|
||||||
if (d)
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
EAPI void *
|
||||||
|
eet_data_image_decode(const void *data, int size, unsigned int *w, unsigned int *h, int *alpha, int *compress, int *quality, int *lossy)
|
||||||
|
{
|
||||||
|
unsigned int *d = NULL;
|
||||||
|
unsigned int iw, ih;
|
||||||
|
int ialpha, icompress, iquality, ilossy;
|
||||||
|
|
||||||
|
/* All check are done during header decode, this simplify the code a lot. */
|
||||||
|
if (!eet_data_image_header_decode(data, size, &iw, &ih, &ialpha, &icompress, &iquality, &ilossy))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
d = malloc(iw * ih * 4);
|
||||||
|
if (!d) return NULL;
|
||||||
|
|
||||||
|
if (!_eet_data_image_decode_inside(data, size, 0, 0, iw, ih, d, iw, ih, iw * 4, ialpha, icompress, iquality, ilossy))
|
||||||
|
{
|
||||||
|
if (d) free(d);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (w) *w = iw;
|
if (w) *w = iw;
|
||||||
if (h) *h = ih;
|
if (h) *h = ih;
|
||||||
if (alpha) *alpha = 0;
|
if (alpha) *alpha = ialpha;
|
||||||
if (compress) *compress = 0;
|
if (compress) *compress = icompress;
|
||||||
if (lossy) *lossy = 1;
|
if (quality) *quality = iquality;
|
||||||
if (quality) *quality = 75;
|
if (lossy) *lossy = ilossy;
|
||||||
}
|
|
||||||
}
|
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EAPI int
|
||||||
|
eet_data_image_decode_to_surface(const void *data, int size, unsigned int src_x, unsigned int src_y,
|
||||||
|
unsigned int *d, unsigned int w, unsigned int h, unsigned int row_stride,
|
||||||
|
int *alpha, int *compress, int *quality, int *lossy)
|
||||||
|
{
|
||||||
|
unsigned int iw, ih;
|
||||||
|
int ialpha, icompress, iquality, ilossy;
|
||||||
|
|
||||||
|
/* All check are done during header decode, this simplify the code a lot. */
|
||||||
|
if (!eet_data_image_header_decode(data, size, &iw, &ih, &ialpha, &icompress, &iquality, &ilossy))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (!d) return 0;
|
||||||
|
if (w * 4 > row_stride) return 0;
|
||||||
|
if (w > iw || h > ih) return 0;
|
||||||
|
|
||||||
|
if (!_eet_data_image_decode_inside(data, size, src_x, src_y, iw, ih, d, w, h, row_stride, ialpha, icompress, iquality, ilossy))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (alpha) *alpha = ialpha;
|
||||||
|
if (compress) *compress = icompress;
|
||||||
|
if (quality) *quality = iquality;
|
||||||
|
if (lossy) *lossy = ilossy;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
|
@ -903,10 +903,21 @@ START_TEST(eet_image)
|
||||||
fail_if(compress != 0);
|
fail_if(compress != 0);
|
||||||
fail_if(lossy != 0);
|
fail_if(lossy != 0);
|
||||||
|
|
||||||
data = eet_data_image_read(ef, EET_TEST_FILE_IMAGE "0", &w, &h, &alpha, &compress, &quality, &lossy);
|
data = malloc(w * h * 4);
|
||||||
fail_if(data == NULL);
|
fail_if(data == NULL);
|
||||||
fail_if(w != test_noalpha.w);
|
result = eet_data_image_read_to_surface(ef, EET_TEST_FILE_IMAGE "0", 4, 4, data, 2, 2, w * 4, &alpha, &compress, &quality, &lossy);
|
||||||
fail_if(h != test_noalpha.h);
|
fail_if(result != 1);
|
||||||
|
fail_if(alpha != test_noalpha.alpha);
|
||||||
|
fail_if(compress != 0);
|
||||||
|
fail_if(quality != 100);
|
||||||
|
fail_if(lossy != 0);
|
||||||
|
fail_if(data[0] != test_noalpha.color[4 + 4 * w]);
|
||||||
|
free(data);
|
||||||
|
|
||||||
|
data = malloc(w * h * 4);
|
||||||
|
fail_if(data == NULL);
|
||||||
|
result = eet_data_image_read_to_surface(ef, EET_TEST_FILE_IMAGE "0", 0, 0, data, w, h, w * 4, &alpha, &compress, &quality, &lossy);
|
||||||
|
fail_if(result != 1);
|
||||||
fail_if(alpha != test_noalpha.alpha);
|
fail_if(alpha != test_noalpha.alpha);
|
||||||
fail_if(compress != 0);
|
fail_if(compress != 0);
|
||||||
fail_if(quality != 100);
|
fail_if(quality != 100);
|
||||||
|
|
Loading…
Reference in New Issue