[cairo-commit] cairo/src cairo-png.c,1.14,1.15
Owen Taylor
commit at pdx.freedesktop.org
Thu Jun 23 12:58:52 PDT 2005
Committed by: otaylor
Update of /cvs/cairo/cairo/src
In directory gabe:/tmp/cvs-serv18630/src
Modified Files:
cairo-png.c
Log Message:
2005-05-17 Owen Taylor <otaylor at redhat.com>
* src/cairo-png.c (write_png): Only unpremultiply ARGB32 data.
Call png_write_info() *before* we set up the write conversion...
it doesn't work after.
Index: cairo-png.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo-png.c,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -d -r1.14 -r1.15
--- cairo-png.c 10 Jun 2005 19:18:21 -0000 1.14
+++ cairo-png.c 23 Jun 2005 19:58:50 -0000 1.15
@@ -38,6 +38,7 @@
#include <png.h>
#include "cairoint.h"
+/* Unpremultiplies data and converts native endian ARGB => RGBA bytes */
static void
unpremultiply_data (png_structp png, png_row_infop row_info, png_bytep data)
{
@@ -53,14 +54,33 @@
if (alpha == 0) {
b[0] = b[1] = b[2] = b[3] = 0;
} else {
- b[0] = (((pixel & 0x0000ff) >> 0) * 255 + alpha / 2) / alpha;
+ b[0] = (((pixel & 0xff0000) >> 16) * 255 + alpha / 2) / alpha;
b[1] = (((pixel & 0x00ff00) >> 8) * 255 + alpha / 2) / alpha;
- b[2] = (((pixel & 0xff0000) >> 16) * 255 + alpha / 2) / alpha;
+ b[2] = (((pixel & 0x0000ff) >> 0) * 255 + alpha / 2) / alpha;
b[3] = alpha;
}
}
}
+/* Converts native endian xRGB => RGBx bytes */
+static void
+convert_data_to_bytes (png_structp png, png_row_infop row_info, png_bytep data)
+{
+ int i;
+
+ for (i = 0; i < row_info->rowbytes; i += 4) {
+ uint8_t *b = &data[i];
+ uint32_t pixel;
+
+ memcpy (&pixel, b, sizeof (uint32_t));
+
+ b[0] = (pixel & 0xff0000) >> 16;
+ b[1] = (pixel & 0x00ff00) >> 8;
+ b[2] = (pixel & 0x0000ff) >> 0;
+ b[3] = 0;
+ }
+}
+
static cairo_status_t
write_png (cairo_surface_t *surface,
png_rw_ptr write_func,
@@ -153,14 +173,19 @@
png_convert_from_time_t (&pt, time (NULL));
png_set_tIME (png, info, &pt);
- png_set_write_user_transform_fn (png, unpremultiply_data);
- if (image->format == CAIRO_FORMAT_ARGB32 ||
- image->format == CAIRO_FORMAT_RGB24)
- png_set_bgr (png);
+ /* We have to call png_write_info() before setting up the write
+ * transformation, since it stores data internally in 'png'
+ * that is needed for the write transformation functions to work.
+ */
+ png_write_info (png, info);
+
+ if (image->format == CAIRO_FORMAT_ARGB32)
+ png_set_write_user_transform_fn (png, unpremultiply_data);
+ else if (image->format == CAIRO_FORMAT_RGB24)
+ png_set_write_user_transform_fn (png, convert_data_to_bytes);
if (image->format == CAIRO_FORMAT_RGB24)
png_set_filler (png, 0, PNG_FILLER_AFTER);
-
- png_write_info (png, info);
+
png_write_image (png, rows);
png_write_end (png, info);
@@ -262,6 +287,7 @@
return write_png (surface, stream_write_func, &png_closure);
}
+/* Premultiplies data and converts RGBA bytes => native endian */
static void
premultiply_data (png_structp png,
png_row_infop row_info,
@@ -271,9 +297,9 @@
for (i = 0; i < row_info->rowbytes; i += 4) {
uint8_t *base = &data[i];
- uint8_t blue = base[0];
+ uint8_t red = base[0];
uint8_t green = base[1];
- uint8_t red = base[2];
+ uint8_t blue = base[2];
uint8_t alpha = base[3];
uint32_t p;
@@ -352,7 +378,6 @@
if (interlace != PNG_INTERLACE_NONE)
png_set_interlace_handling (png);
- png_set_bgr (png);
png_set_filler (png, 0xff, PNG_FILLER_AFTER);
png_set_read_user_transform_fn (png, premultiply_data);
More information about the cairo-commit
mailing list