summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSøren Sandmann Pedersen <ssp@redhat.com>2011-03-07 09:12:28 -0500
committerSøren Sandmann Pedersen <ssp@redhat.com>2011-03-07 09:12:28 -0500
commit0dd55f7085cc8776c6574d628baff8a92c88142a (patch)
tree0c1a52b632841db709cf70b367cfb0c115ea5256
parent3d458ff25800d9a059af4b82f4079fb899ed2d0f (diff)
parent5841d93bfb69aaa701b5783b6cc9390a332ed00f (diff)
Merge remote-tracking branch 'ssp/png' into endian
-rw-r--r--test/Makefile.am2
-rw-r--r--test/utils.c118
-rw-r--r--test/utils.h3
3 files changed, 122 insertions, 1 deletions
diff --git a/test/Makefile.am b/test/Makefile.am
index 9dc72199..7c42c2fc 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -1,6 +1,6 @@
AM_CFLAGS = @OPENMP_CFLAGS@
AM_LDFLAGS = @OPENMP_CFLAGS@ @TESTPROGS_EXTRA_LDFLAGS@
-LDADD = $(top_builddir)/pixman/libpixman-1.la -lm
+LDADD = $(top_builddir)/pixman/libpixman-1.la -lm -lpng
INCLUDES = -I$(top_srcdir)/pixman -I$(top_builddir)/pixman
TESTPROGRAMS = \
diff --git a/test/utils.c b/test/utils.c
index 2f213984..edf6f9ef 100644
--- a/test/utils.c
+++ b/test/utils.c
@@ -21,6 +21,8 @@
#include <fenv.h>
#endif
+#include <png.h>
+
/* Random number seed
*/
@@ -323,6 +325,122 @@ make_random_bytes (int n_bytes)
return bytes;
}
+static void
+pngify_pixels (uint32_t *pixels, int n_pixels)
+{
+ int i;
+
+ for (i = 0; i < n_pixels; ++i)
+ {
+ uint32_t p = pixels[i];
+ uint8_t *out = (uint8_t *)&(pixels[i]);
+ uint8_t a, r, g, b;
+
+ a = (p & 0xff000000) >> 24;
+ r = (p & 0x00ff0000) >> 16;
+ g = (p & 0x0000ff00) >> 8;
+ b = (p & 0x000000ff) >> 0;
+
+ if (a != 0)
+ {
+ r = (r * 255) / a;
+ g = (g * 255) / a;
+ b = (b * 255) / a;
+ }
+
+ *out++ = r;
+ *out++ = g;
+ *out++ = b;
+ *out++ = a;
+ }
+}
+
+pixman_bool_t
+write_png (pixman_image_t *image, const char *filename)
+{
+ int width = pixman_image_get_width (image);
+ int height = pixman_image_get_height (image);
+ int stride = width * 4;
+ uint32_t *data = malloc (height * stride);
+ pixman_image_t *copy;
+ int color_type;
+ png_struct *write_struct;
+ png_info *info_struct;
+ pixman_bool_t result = FALSE;
+ FILE *f = fopen (filename, "wb");
+ png_bytep *row_pointers;
+ int depth;
+ int i;
+
+ if (!f)
+ return FALSE;
+
+ row_pointers = malloc (height * sizeof (png_bytep));
+
+ depth = 8;
+ switch (pixman_image_get_format (image))
+ {
+ case PIXMAN_x8r8g8b8:
+ color_type = PNG_COLOR_TYPE_RGB;
+ break;
+
+ case PIXMAN_a1:
+ depth = 1;
+ case PIXMAN_a8:
+ color_type = PNG_COLOR_TYPE_GRAY;
+ break;
+
+ default:
+ case PIXMAN_a8r8g8b8:
+ color_type = PNG_COLOR_TYPE_RGB_ALPHA;
+ break;
+ }
+
+ copy = pixman_image_create_bits (
+ PIXMAN_a8r8g8b8, width, height, data, stride);
+
+ pixman_image_composite32 (
+ PIXMAN_OP_SRC, image, NULL, copy, 0, 0, 0, 0, 0, 0, width, height);
+
+ pngify_pixels (data, height * width);
+
+ for (i = 0; i < height; ++i)
+ row_pointers[i] = (png_bytep)(data + i * width);
+
+ if (!(write_struct = png_create_write_struct (
+ PNG_LIBPNG_VER_STRING, NULL, NULL, NULL)))
+ goto out1;
+
+ if (!(info_struct = png_create_info_struct (write_struct)))
+ goto out2;
+
+ png_init_io (write_struct, f);
+
+ png_set_IHDR (write_struct, info_struct, width, height, depth, color_type,
+ PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE,
+ PNG_FILTER_TYPE_BASE);
+
+ png_write_info (write_struct, info_struct);
+
+ png_write_image (write_struct, row_pointers);
+
+ png_write_end (write_struct, NULL);
+
+ result = TRUE;
+
+out2:
+ png_destroy_write_struct (&write_struct, &info_struct);
+
+out1:
+ if (fclose (f) != 0)
+ result = FALSE;
+
+ pixman_image_unref (copy);
+ free (row_pointers);
+ free (data);
+ return result;
+}
+
/*
* A function, which can be used as a core part of the test programs,
* intended to detect various problems with the help of fuzzing input
diff --git a/test/utils.h b/test/utils.h
index 9c7bdb1c..fc9dfb1c 100644
--- a/test/utils.h
+++ b/test/utils.h
@@ -94,6 +94,9 @@ fail_after (int seconds, const char *msg);
/* If possible, enable traps for floating point exceptions */
void enable_fp_exceptions(void);
+pixman_bool_t
+write_png (pixman_image_t *image, const char *filename);
+
/* A pair of macros which can help to detect corruption of
* floating point registers after a function call. This may
* happen if _mm_empty() call is forgotten in MMX/SSE2 fast