diff --git a/legacy/eet/src/lib/Eet.h b/legacy/eet/src/lib/Eet.h index 0171381cdf..6ef11821bd 100644 --- a/legacy/eet/src/lib/Eet.h +++ b/legacy/eet/src/lib/Eet.h @@ -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); + /** + * 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. * @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); + /** + * 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. * @param data A pointer to the image pixel data. diff --git a/legacy/eet/src/lib/eet_image.c b/legacy/eet/src/lib/eet_image.c index e34dbd6e4e..536d2db378 100644 --- a/legacy/eet/src/lib/eet_image.c +++ b/legacy/eet/src/lib/eet_image.c @@ -55,8 +55,8 @@ static void _JPEGErrorHandler(j_common_ptr cinfo); 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 void *eet_data_image_jpeg_rgb_decode(const void *data, int size, unsigned int *w, unsigned int *h); -static void *eet_data_image_jpeg_alpha_decode(const void *data, int size, unsigned int *d, 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 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_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); @@ -168,20 +168,24 @@ eet_data_image_jpeg_header_decode(const void *data, int size, unsigned int *w, u return 1; } -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) { - unsigned int *d; struct jpeg_decompress_struct cinfo; struct _JPEG_error_mgr jerr; unsigned char *ptr, *line[16], *tdata = NULL; - unsigned int *ptr2; - unsigned int x, y, l, scans; + unsigned int *ptr2, *tmp; + unsigned int iw, ih; + int x, y, l, scans; int i, count, prevy; 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); - if (!f) return NULL; + if (!f) return 0; cinfo.err = jpeg_std_error(&(jerr.pub)); jerr.pub.error_exit = _JPEGFatalErrorHandler; 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); jpeg_destroy_decompress(&cinfo); _eet_memfile_read_close(f); - return NULL; + return 0; } jpeg_create_decompress(&cinfo); 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); /* head decoding */ - *w = cinfo.output_width; - *h = cinfo.output_height; - if ((*w < 1) || (*h < 1) || (*w > 8192) || (*h > 8192)) + iw = cinfo.output_width; + ih = cinfo.output_height; + if ((iw != w) || (ih != h)) { jpeg_destroy_decompress(&cinfo); _eet_memfile_read_close(f); - return NULL; + return 0; } /* end head decoding */ /* data decoding */ @@ -216,79 +220,102 @@ eet_data_image_jpeg_rgb_decode(const void *data, int size, unsigned int *w, unsi { jpeg_destroy_decompress(&cinfo); _eet_memfile_read_close(f); - return NULL; - } - tdata = alloca((*w) * 16 * 3); - d = malloc((*w) * (*h) * 4); - if (!d) - { - jpeg_destroy_decompress(&cinfo); - _eet_memfile_read_close(f); - return NULL; + return 0; } + tdata = alloca((iw) * 16 * 3); ptr2 = d; count = 0; prevy = 0; + if (cinfo.output_components == 3) { for (i = 0; i < cinfo.rec_outbuf_height; i++) - line[i] = tdata + (i * (*w) * 3); - for (l = 0; l < (*h); l += cinfo.rec_outbuf_height) + line[i] = tdata + (i * (iw) * 3); + for (l = 0; l < ih; l += cinfo.rec_outbuf_height) { jpeg_read_scanlines(&cinfo, line, cinfo.rec_outbuf_height); - scans = cinfo.rec_outbuf_height; - if (((*h) - l) < scans) scans = (*h) - l; + scans = cinfo.rec_outbuf_height; + if ((ih - l) < scans) scans = ih - l; 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++) { - *ptr2 = - (0xff000000) | ((ptr[0]) << 16) | ((ptr[1]) << 8) | (ptr[2]); - ptr += 3; - ptr2++; + tmp = ptr2; + ptr += 3 * src_x; + for (x = 0; x < w; x++) + { + *ptr2 = + (0xff000000) | ((ptr[0]) << 16) | ((ptr[1]) << 8) | (ptr[2]); + ptr += 3; + ptr2++; + } + ptr += 3 * (iw - w); + ptr2 = tmp + row_stride / 4; } } + else + { + ptr += 3 * iw * scans; + } } } else if (cinfo.output_components == 1) { for (i = 0; i < cinfo.rec_outbuf_height; i++) - line[i] = tdata + (i * (*w)); - for (l = 0; l < (*h); l += cinfo.rec_outbuf_height) + line[i] = tdata + (i * (iw)); + for (l = 0; l < (ih); l += cinfo.rec_outbuf_height) { jpeg_read_scanlines(&cinfo, line, 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; - 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++) { - *ptr2 = - (0xff000000) | ((ptr[0]) << 16) | ((ptr[0]) << 8) | (ptr[0]); - ptr++; - ptr2++; + tmp = ptr2; + ptr += src_x; + for (x = 0; x < w; x++) + { + *ptr2 = + (0xff000000) | ((ptr[0]) << 16) | ((ptr[0]) << 8) | (ptr[0]); + ptr++; + ptr2++; + } + ptr += iw - w; + ptr2 = tmp + row_stride / 4; } } + else + { + ptr += iw * scans; + } } } /* end data decoding */ jpeg_finish_decompress(&cinfo); jpeg_destroy_decompress(&cinfo); _eet_memfile_read_close(f); - return d; + return 1; } 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_error_mgr jerr; unsigned char *ptr, *line[16], *tdata = NULL; - unsigned int *ptr2; - unsigned int x, y, l, scans; - int i, count, prevy; + unsigned int *ptr2, *tmp; + int x, y, l, scans; + int i, count, prevy, iw; FILE *f; 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); /* head decoding */ - if ((*w) != cinfo.output_width) + iw = cinfo.output_width; + if (w != cinfo.output_width + || h != cinfo.output_height) { jpeg_destroy_decompress(&cinfo); _eet_memfile_read_close(f); 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 */ /* data decoding */ if (cinfo.rec_outbuf_height > 16) @@ -344,31 +365,45 @@ eet_data_image_jpeg_alpha_decode(const void *data, int size, unsigned int *d, un _eet_memfile_read_close(f); return NULL; } - tdata = alloca((*w) * 16 * 3); + tdata = alloca(w * 16 * 3); ptr2 = d; count = 0; prevy = 0; if (cinfo.output_components == 1) { for (i = 0; i < cinfo.rec_outbuf_height; i++) - line[i] = tdata + (i * (*w)); - for (l = 0; l < (*h); l += cinfo.rec_outbuf_height) + line[i] = tdata + (i * w); + for (l = 0; l < h; l += cinfo.rec_outbuf_height) { jpeg_read_scanlines(&cinfo, line, 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; - 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++) { - *ptr2 = - ((*ptr2) & 0x00ffffff) | - ((ptr[0]) << 24); - ptr++; - ptr2++; + tmp = ptr2; + ptr += src_x; + for (x = 0; x < w; x++) + { + *ptr2 = + ((*ptr2) & 0x00ffffff) | + ((ptr[0]) << 24); + ptr++; + ptr2++; + } + ptr += iw - w; + ptr2 = tmp + row_stride / 4; } } + else + { + ptr += iw * scans; + } } } /* end data decoding */ @@ -785,6 +820,33 @@ eet_data_image_read(Eet_File *ef, const char *name, 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 eet_data_image_header_read(Eet_File *ef, const char *name, 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 (w) *w = iw; if (h) *h = ih; - if (alpha) *alpha = al; + if (alpha) *alpha = al ? 1 : 0; if (compress) *compress = cp; if (lossy) *lossy = 0; if (quality) *quality = 100; @@ -918,118 +980,172 @@ eet_data_image_header_decode(const void *data, int size, unsigned int *w, unsign return 0; } -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) +static void +_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; - int header[8]; + src += src_x + src_y * src_w; - if (words_bigendian == -1) + if (row_stride == src_w * 4 && w == src_w) { - unsigned long int v; - - v = htonl(0x12345678); - if (v == 0x12345678) words_bigendian = 1; - else words_bigendian = 0; + memcpy(dst, src, row_stride * h); } - - if (size < 32) return NULL; - - memcpy(header, data, 32); - if (words_bigendian) + else { - int i; + unsigned int *over = dst; + unsigned int y; - for (i = 0; i < 8; i++) SWAP32(header[i]); + for (y = 0; y < h; ++y, src += src_w, over += row_stride) + memcpy(over, src, w * 4); } - if ((unsigned)header[0] == 0xac1dfeed) +} + + +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) { - 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) + if (!compress) { - memcpy(d, body, iw * ih * 4); + _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); + } + } + + /* 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); if (words_bigendian) { - int x; + int i; - for (x = 0; x < (iw * ih); x++) SWAP32(d[x]); + for (i = 0; i < 8; i++) SWAP32(header[i]); + } + + sz1 = header[1]; + sz2 = header[2]; + dt = data; + dt += 12; + + if (eet_data_image_jpeg_rgb_decode(dt, sz1, src_x, src_y, d, w, h, row_stride)) + { + dt += sz1; + if (!eet_data_image_jpeg_alpha_decode(dt, sz2, src_x, src_y, d, w, h, row_stride)) + return 0; } } 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]; - sz2 = header[2]; - dt = data; - dt += 12; - d = eet_data_image_jpeg_rgb_decode(dt, sz1, &iw, &ih); - if (d) - { - dt += sz1; - eet_data_image_jpeg_alpha_decode(dt, sz2, d, &iw, &ih); - } - 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; + if (!eet_data_image_jpeg_rgb_decode(data, size, src_x, src_y, d, w, h, row_stride)) + return 0; } } else { - unsigned int iw = 0, ih = 0; - - d = eet_data_image_jpeg_rgb_decode(data, size, &iw, &ih); - if (d) - { - if (w) *w = iw; - if (h) *h = ih; - if (alpha) *alpha = 0; - if (compress) *compress = 0; - if (lossy) *lossy = 1; - if (quality) *quality = 75; - } + 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 (h) *h = ih; + if (alpha) *alpha = ialpha; + if (compress) *compress = icompress; + if (quality) *quality = iquality; + if (lossy) *lossy = ilossy; + 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; +} diff --git a/legacy/eet/src/tests/eet_suite.c b/legacy/eet/src/tests/eet_suite.c index fece6795de..9026b65ded 100644 --- a/legacy/eet/src/tests/eet_suite.c +++ b/legacy/eet/src/tests/eet_suite.c @@ -903,10 +903,21 @@ START_TEST(eet_image) fail_if(compress != 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(w != test_noalpha.w); - fail_if(h != test_noalpha.h); + 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(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(compress != 0); fail_if(quality != 100);