summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSøren Sandmann Pedersen <ssp@redhat.com>2011-02-22 05:20:36 -0500
committerSøren Sandmann Pedersen <ssp@redhat.com>2011-09-10 04:07:50 -0400
commit99a53667da3014a463b8a0e2b6c317efe0ebb220 (patch)
tree5945aa6f243a96296afbf9dc401ff258b530e858
parent1e1ae0bf6e9dd2189133539b9c34a0f6826b7393 (diff)
test: New function to save a pixman image to .png
When debugging it is often very useful to be able to save an image as a png file. This commit adds a function "write_png()" that does that. If libpng is not available, then the function becomes a noop.
-rw-r--r--configure.ac11
-rw-r--r--test/Makefile.am2
-rw-r--r--test/utils.c112
-rw-r--r--test/utils.h3
4 files changed, 127 insertions, 1 deletions
diff --git a/configure.ac b/configure.ac
index d06bff1..21613e1 100644
--- a/configure.ac
+++ b/configure.ac
@@ -801,6 +801,17 @@ fi
AC_MSG_RESULT($support_for_attribute_constructor)
AC_SUBST(TOOLCHAIN_SUPPORTS_ATTRIBUTE_CONSTRUCTOR)
+dnl ==================
+dnl libpng
+
+AC_CHECK_LIB([png], [png_write_info], [have_libpng=yes], [have_libpng=no])
+
+if test x$have_libpng = xyes; then
+ AC_DEFINE([HAVE_LIBPNG], [1], [Whether we have libpng])
+fi
+
+AC_SUBST(HAVE_LIBPNG)
+
AC_OUTPUT([pixman-1.pc
pixman-1-uninstalled.pc
Makefile
diff --git a/test/Makefile.am b/test/Makefile.am
index 9f61fc9..52ef8ad 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 44188ea..adabd75 100644
--- a/test/utils.c
+++ b/test/utils.c
@@ -21,6 +21,10 @@
#include <fenv.h>
#endif
+#ifdef HAVE_LIBPNG
+#include <png.h>
+#endif
+
/* Random number seed
*/
@@ -335,6 +339,114 @@ make_random_bytes (int n_bytes)
return bytes;
}
+#ifdef HAVE_LIBPNG
+
+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;
+ png_struct *write_struct;
+ png_info *info_struct;
+ pixman_bool_t result = FALSE;
+ FILE *f = fopen (filename, "wb");
+ png_bytep *row_pointers;
+ int i;
+
+ if (!f)
+ return FALSE;
+
+ row_pointers = malloc (height * sizeof (png_bytep));
+
+ 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,
+ 8, PNG_COLOR_TYPE_RGB_ALPHA,
+ 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;
+}
+
+#else /* no libpng */
+
+pixman_bool_t
+write_png (pixman_image_t *image, const char *filename)
+{
+ return FALSE;
+}
+
+#endif
+
/*
* 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 f0c9c30..3790483 100644
--- a/test/utils.h
+++ b/test/utils.h
@@ -105,6 +105,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