[Pkg-e-commits] [SCM] Enlightenment DR17 file chunk reading/writing library branch, upstream-vcs, updated. 724ff1721ded78eea468a35945bd2796b5219fbc

cedric cedric at alioth.debian.org
Sat Jun 7 17:45:16 UTC 2008


The following commit has been merged in the upstream-vcs branch:
commit 0d858b23d3bb6cc2d62ad2f8294ed545546ef8e3
Author: cedric <cedric>
Date:   Mon Jun 2 16:01:18 2008 +0000

    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.

diff --git a/src/lib/Eet.h b/src/lib/Eet.h
index 0171381..6ef1182 100644
--- a/src/lib/Eet.h
+++ b/src/lib/Eet.h
@@ -470,6 +470,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.
     * @param name Name of the entry. eg: "/base/file_i_want".
@@ -576,6 +615,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.
     * @param size_ret A pointer to an int to hold the size of the returned data.
diff --git a/src/lib/eet_image.c b/src/lib/eet_image.c
index e34dbd6..536d2db 100644
--- a/src/lib/eet_image.c
+++ b/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 */
@@ -786,6 +821,33 @@ eet_data_image_read(Eet_File *ef, const char *name,
 }
 
 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,
 			   int *compress, int *quality, int *lossy)
@@ -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);
-	     if (words_bigendian)
-	       {
-		  int x;
-
-		  for (x = 0; x < (iw * ih); x++) SWAP32(d[x]);
-	       }
+	     _eet_data_image_copy_buffer(body, src_x, src_y, src_w, d, w, h, row_stride);
 	  }
 	else
 	  {
-	     uLongf dlen;
+	     if (src_h == h && src_w == w && row_stride == src_w * 4)
+	       {
+		  uLongf dlen;
 
-	     dlen = iw * ih * 4;
-	     uncompress((Bytef *)d, &dlen, (Bytef *)body,
-			(uLongf)(size - 32));
-	     if (words_bigendian)
+		  dlen = w * h * 4;
+		  uncompress((Bytef *)d, &dlen, (Bytef *)body,
+			     (uLongf)(size - 32));
+	       }
+	     else
 	       {
-		  int x;
+		  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;
 
-		  for (x = 0; x < (iw * ih); x++) SWAP32(d[x]);
+		  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 (d)
+
+	/* Fix swapiness. */
+	if (words_bigendian)
 	  {
-	     if (w) *w = iw;
-	     if (h) *h = ih;
-	     if (alpha) *alpha = al;
-	     if (compress) *compress = cp;
-	     if (lossy) *lossy = 0;
-	     if (quality) *quality = 100;
+	     unsigned int x;
+
+	     for (x = 0; x < (w * h); x++) SWAP32(d[x]);
 	  }
      }
-   else if ((unsigned)header[0] == 0xbeeff00d)
+   else if (compress == 0 && lossy == 1)
      {
-	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)
+	if (alpha)
 	  {
-	     dt += sz1;
-	     eet_data_image_jpeg_alpha_decode(dt, sz2, d, &iw, &ih);
+	     unsigned const char *dt;
+	     int header[8];
+	     int sz1, sz2;
+
+	     memcpy(header, data, 32);
+	     if (words_bigendian)
+	       {
+		  int i;
+
+		  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;
+	       }
 	  }
-	if (d)
+	else
 	  {
-	     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;
+	abort();
+     }
 
-	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;
-	  }
+   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/src/tests/eet_suite.c b/src/tests/eet_suite.c
index fece679..9026b65 100644
--- a/src/tests/eet_suite.c
+++ b/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);

-- 
Enlightenment DR17 file chunk reading/writing library



More information about the Pkg-e-commits mailing list