mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2026-04-25 19:00:42 +02:00
test: Remove custom read/write-png code in favor of using cairo surfaces
Also combine image_diff and image_diff_flattened into a single function
This was manually taken from 9547521885
(It would have been a cherry-pick, but that doesn't yet handle file
renames.)
This commit is contained in:
parent
37dcbe61cf
commit
11127fc210
9 changed files with 145 additions and 563 deletions
|
|
@ -389,10 +389,6 @@ buffer-diff.c \
|
|||
buffer-diff.h \
|
||||
cairo-test.c \
|
||||
cairo-test.h \
|
||||
read-png.c \
|
||||
read-png.h \
|
||||
write-png.c \
|
||||
write-png.h \
|
||||
xmalloc.c \
|
||||
xmalloc.h
|
||||
|
||||
|
|
|
|||
|
|
@ -39,8 +39,6 @@
|
|||
#include "cairo-test.h"
|
||||
|
||||
#include "buffer-diff.h"
|
||||
#include "read-png.h"
|
||||
#include "write-png.h"
|
||||
#include "xmalloc.h"
|
||||
|
||||
static void
|
||||
|
|
@ -143,11 +141,142 @@ buffer_diff_noalpha (unsigned char *buf_a,
|
|||
width, height, stride_a, stride_b, stride_diff, 0x00ffffff);
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
stdio_write_func (void *closure, const unsigned char *data, unsigned int length)
|
||||
{
|
||||
FILE *file = closure;
|
||||
|
||||
if (fwrite (data, 1, length, file) != length)
|
||||
return CAIRO_STATUS_WRITE_ERROR;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* Flatten an ARGB surface by blending it over white. The resulting
|
||||
* surface, (still in ARGB32 format, but with only alpha==1.0
|
||||
* everywhere) is returned in the same surface pointer.
|
||||
*
|
||||
* The original surface will be destroyed.
|
||||
*
|
||||
* The (x,y) value specify an origin of interest for the original
|
||||
* image. The flattened image will be generated only from the box
|
||||
* extending from (x,y) to (width,height).
|
||||
*/
|
||||
static void
|
||||
flatten_surface (cairo_surface_t **surface, int x, int y)
|
||||
{
|
||||
cairo_surface_t *flat;
|
||||
cairo_t *cr;
|
||||
|
||||
flat = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
|
||||
cairo_image_surface_get_width (*surface) - x,
|
||||
cairo_image_surface_get_height (*surface) - y);
|
||||
cairo_surface_set_device_offset (flat, -x, -y);
|
||||
|
||||
cr = cairo_create (flat);
|
||||
cairo_set_source_rgb (cr, 1, 1, 1);
|
||||
cairo_paint (cr);
|
||||
cairo_set_source_surface (cr, *surface, 0, 0);
|
||||
cairo_paint (cr);
|
||||
cairo_destroy (cr);
|
||||
|
||||
cairo_surface_destroy (*surface);
|
||||
*surface = flat;
|
||||
}
|
||||
|
||||
/* Image comparison code courtesy of Richard Worth <richard@theworths.org>
|
||||
* Returns number of pixels changed, (or -1 on error).
|
||||
* Also saves a "diff" image intended to visually show where the
|
||||
* images differ.
|
||||
*/
|
||||
static int
|
||||
image_diff_core (const char *filename_a,
|
||||
const char *filename_b,
|
||||
const char *filename_diff,
|
||||
int ax,
|
||||
int ay,
|
||||
int bx,
|
||||
int by,
|
||||
cairo_bool_t flatten)
|
||||
{
|
||||
int pixels_changed;
|
||||
unsigned int width_a, height_a, stride_a;
|
||||
unsigned int width_b, height_b, stride_b;
|
||||
cairo_surface_t *surface_a, *surface_b, *surface_diff;
|
||||
|
||||
surface_a = cairo_image_surface_create_from_png (filename_a);
|
||||
if (cairo_surface_status (surface_a))
|
||||
return -1;
|
||||
|
||||
surface_b = cairo_image_surface_create_from_png (filename_b);
|
||||
if (cairo_surface_status (surface_b)) {
|
||||
cairo_surface_destroy (surface_a);
|
||||
return -1;
|
||||
}
|
||||
|
||||
width_a = cairo_image_surface_get_width (surface_a) - ax;
|
||||
height_a = cairo_image_surface_get_height (surface_a) - ay;
|
||||
width_b = cairo_image_surface_get_width (surface_b) - bx;
|
||||
height_b = cairo_image_surface_get_height (surface_b) - by;
|
||||
|
||||
if (width_a != width_b ||
|
||||
height_a != height_b)
|
||||
{
|
||||
cairo_test_log ("Error: Image size mismatch: (%dx%d) vs. (%dx%d)\n"
|
||||
" for %s vs. %s\n",
|
||||
width_a, height_a,
|
||||
width_b, height_b,
|
||||
filename_a, filename_b);
|
||||
cairo_surface_destroy (surface_a);
|
||||
cairo_surface_destroy (surface_b);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (flatten) {
|
||||
flatten_surface (&surface_a, ax, ay);
|
||||
flatten_surface (&surface_b, bx, by);
|
||||
ax = ay = bx = by = 0;
|
||||
}
|
||||
|
||||
surface_diff = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
|
||||
width_a, height_a);
|
||||
|
||||
stride_a = cairo_image_surface_get_stride (surface_a);
|
||||
stride_b = cairo_image_surface_get_stride (surface_b);
|
||||
|
||||
pixels_changed = buffer_diff (cairo_image_surface_get_data (surface_a)
|
||||
+ (ay * stride_a) + ax * 4,
|
||||
cairo_image_surface_get_data (surface_b)
|
||||
+ (by * stride_b) + by * 4,
|
||||
cairo_image_surface_get_data (surface_diff),
|
||||
width_a, height_a,
|
||||
stride_a, stride_b,
|
||||
cairo_image_surface_get_stride (surface_diff));
|
||||
|
||||
if (pixels_changed) {
|
||||
FILE *png_file;
|
||||
|
||||
if (filename_diff)
|
||||
png_file = fopen (filename_diff, "wb");
|
||||
else
|
||||
png_file = stdout;
|
||||
|
||||
cairo_surface_write_to_png_stream (surface_diff, stdio_write_func, png_file);
|
||||
|
||||
if (png_file != stdout)
|
||||
fclose (png_file);
|
||||
} else {
|
||||
if (filename_diff)
|
||||
xunlink (filename_diff);
|
||||
}
|
||||
|
||||
cairo_surface_destroy (surface_a);
|
||||
cairo_surface_destroy (surface_b);
|
||||
cairo_surface_destroy (surface_diff);
|
||||
|
||||
return pixels_changed;
|
||||
}
|
||||
|
||||
int
|
||||
image_diff (const char *filename_a,
|
||||
const char *filename_b,
|
||||
|
|
@ -157,83 +286,11 @@ image_diff (const char *filename_a,
|
|||
int bx,
|
||||
int by)
|
||||
{
|
||||
int pixels_changed;
|
||||
unsigned int width_a, height_a, stride_a;
|
||||
unsigned int width_b, height_b, stride_b;
|
||||
unsigned int stride_diff;
|
||||
unsigned char *buf_a, *buf_b, *buf_diff;
|
||||
read_png_status_t status;
|
||||
|
||||
status = read_png_argb32 (filename_a, &buf_a, &width_a, &height_a, &stride_a);
|
||||
if (status)
|
||||
return -1;
|
||||
|
||||
status = read_png_argb32 (filename_b, &buf_b, &width_b, &height_b, &stride_b);
|
||||
if (status) {
|
||||
free (buf_a);
|
||||
return -1;
|
||||
}
|
||||
|
||||
width_a -= ax;
|
||||
height_a -= ay;
|
||||
width_b -= bx;
|
||||
height_b -= by;
|
||||
|
||||
if (width_a != width_b ||
|
||||
height_a != height_b)
|
||||
{
|
||||
cairo_test_log ("Error: Image size mismatch: (%dx%d@%d) vs. (%dx%d@%d)\n"
|
||||
" for %s vs. %s\n",
|
||||
width_a, height_a, stride_a,
|
||||
width_b, height_b, stride_b,
|
||||
filename_a, filename_b);
|
||||
free (buf_a);
|
||||
free (buf_b);
|
||||
return -1;
|
||||
}
|
||||
|
||||
stride_diff = 4 * width_a;
|
||||
buf_diff = xcalloc (stride_diff * height_a, 1);
|
||||
|
||||
pixels_changed = buffer_diff (buf_a + (ay * stride_a) + ax * 4,
|
||||
buf_b + (by * stride_b) + by * 4,
|
||||
buf_diff,
|
||||
width_a, height_a,
|
||||
stride_a, stride_b, stride_diff);
|
||||
|
||||
if (pixels_changed) {
|
||||
FILE *png_file;
|
||||
if (filename_diff)
|
||||
png_file = fopen (filename_diff, "wb");
|
||||
else
|
||||
png_file = stdout;
|
||||
write_png_argb32 (buf_diff, png_file, width_a, height_a, stride_diff);
|
||||
if (png_file != stdout)
|
||||
fclose (png_file);
|
||||
} else {
|
||||
if (filename_diff)
|
||||
xunlink (filename_diff);
|
||||
}
|
||||
|
||||
free (buf_a);
|
||||
free (buf_b);
|
||||
free (buf_diff);
|
||||
|
||||
return pixels_changed;
|
||||
return image_diff_core (filename_a, filename_b, filename_diff,
|
||||
ax, ay, bx, by,
|
||||
FALSE);
|
||||
}
|
||||
|
||||
/* Like image_diff, but first "flatten" the contents of filename_b by
|
||||
* blending over white.
|
||||
*
|
||||
* Yes, this is an ugly copy-and-paste of another function. I'm doing
|
||||
* this for two reasons:
|
||||
*
|
||||
* 1) I want to rewrite all of the image_diff interfaces anyway
|
||||
* (should use cairo_image_surface_create_from_png, should save
|
||||
* loaded buffers for re-use).
|
||||
*
|
||||
* 2) There is a second reason no more.
|
||||
*/
|
||||
int
|
||||
image_diff_flattened (const char *filename_a,
|
||||
const char *filename_b,
|
||||
|
|
@ -243,106 +300,7 @@ image_diff_flattened (const char *filename_a,
|
|||
int bx,
|
||||
int by)
|
||||
{
|
||||
int pixels_changed;
|
||||
unsigned int width_a, height_a, stride_a;
|
||||
unsigned int width_b, height_b, stride_b;
|
||||
unsigned char *buf_a, *buf_b, *buf_diff;
|
||||
unsigned char *a_flat, *b_flat;
|
||||
cairo_surface_t *buf_a_surface, *a_flat_surface;
|
||||
cairo_surface_t *buf_b_surface, *b_flat_surface;
|
||||
cairo_t *cr;
|
||||
read_png_status_t status;
|
||||
|
||||
status = read_png_argb32 (filename_a, &buf_a, &width_a, &height_a, &stride_a);
|
||||
if (status)
|
||||
return -1;
|
||||
|
||||
status = read_png_argb32 (filename_b, &buf_b, &width_b, &height_b, &stride_b);
|
||||
if (status) {
|
||||
free (buf_a);
|
||||
return -1;
|
||||
}
|
||||
|
||||
width_a -= ax;
|
||||
height_a -= ay;
|
||||
width_b -= bx;
|
||||
height_b -= by;
|
||||
|
||||
if (width_a != width_b ||
|
||||
height_a != height_b)
|
||||
{
|
||||
cairo_test_log ("Error: Image size mismatch: (%dx%d@%d) vs. (%dx%d@%d)\n"
|
||||
" for %s vs. %s\n",
|
||||
width_a, height_a, stride_a,
|
||||
width_b, height_b, stride_b,
|
||||
filename_a, filename_b);
|
||||
free (buf_a);
|
||||
free (buf_b);
|
||||
return -1;
|
||||
}
|
||||
|
||||
buf_a_surface = cairo_image_surface_create_for_data (buf_a,
|
||||
CAIRO_FORMAT_ARGB32,
|
||||
width_a + ax, height_a + ay,
|
||||
stride_a);
|
||||
buf_b_surface = cairo_image_surface_create_for_data (buf_b,
|
||||
CAIRO_FORMAT_ARGB32,
|
||||
width_b + bx, height_b + by,
|
||||
stride_b);
|
||||
|
||||
buf_diff = xcalloc (stride_a * height_a, 1);
|
||||
|
||||
a_flat = xcalloc (stride_a * height_a, 1);
|
||||
b_flat = xcalloc (stride_b * height_b, 1);
|
||||
|
||||
a_flat_surface = cairo_image_surface_create_for_data (a_flat,
|
||||
CAIRO_FORMAT_ARGB32,
|
||||
width_a, height_a,
|
||||
stride_a);
|
||||
cairo_surface_set_device_offset (a_flat_surface, -ax, -ay);
|
||||
b_flat_surface = cairo_image_surface_create_for_data (b_flat,
|
||||
CAIRO_FORMAT_ARGB32,
|
||||
width_b, height_b,
|
||||
stride_b);
|
||||
cairo_surface_set_device_offset (b_flat_surface, -bx, -by);
|
||||
|
||||
cr = cairo_create (a_flat_surface);
|
||||
cairo_set_source_rgb (cr, 1, 1, 1);
|
||||
cairo_paint (cr);
|
||||
cairo_set_source_surface (cr, buf_a_surface, 0, 0);
|
||||
cairo_paint (cr);
|
||||
cairo_destroy (cr);
|
||||
cairo_surface_destroy (a_flat_surface);
|
||||
cairo_surface_destroy (buf_a_surface);
|
||||
|
||||
cr = cairo_create (b_flat_surface);
|
||||
cairo_set_source_rgb (cr, 1, 1, 1);
|
||||
cairo_paint (cr);
|
||||
cairo_set_source_surface (cr, buf_b_surface, 0, 0);
|
||||
cairo_paint (cr);
|
||||
cairo_destroy (cr);
|
||||
cairo_surface_destroy (b_flat_surface);
|
||||
cairo_surface_destroy (buf_b_surface);
|
||||
|
||||
pixels_changed = buffer_diff (a_flat,
|
||||
b_flat,
|
||||
buf_diff,
|
||||
width_a, height_a,
|
||||
stride_a, stride_b, stride_a);
|
||||
|
||||
if (pixels_changed) {
|
||||
FILE *png_file = fopen (filename_diff, "wb");
|
||||
write_png_argb32 (buf_diff, png_file, width_a, height_a, stride_a);
|
||||
fclose (png_file);
|
||||
} else {
|
||||
xunlink (filename_diff);
|
||||
}
|
||||
|
||||
free (buf_a);
|
||||
free (buf_b);
|
||||
free (a_flat);
|
||||
free (b_flat);
|
||||
free (buf_diff);
|
||||
|
||||
return pixels_changed;
|
||||
return image_diff_core (filename_a, filename_b, filename_diff,
|
||||
ax, ay, bx, by,
|
||||
TRUE);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright © 2004 Red Hat, Inc.
|
||||
* Copyright © 2004,2006 Red Hat, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software
|
||||
* and its documentation for any purpose is hereby granted without
|
||||
|
|
@ -48,8 +48,6 @@
|
|||
#include "cairo-test.h"
|
||||
|
||||
#include "buffer-diff.h"
|
||||
#include "read-png.h"
|
||||
#include "write-png.h"
|
||||
#include "xmalloc.h"
|
||||
|
||||
/* This is copied from cairoint.h. That makes it painful to keep in
|
||||
|
|
|
|||
|
|
@ -143,6 +143,13 @@ cairo_test_paint_checkered (cairo_t *cr);
|
|||
void
|
||||
xasprintf (char **strp, const char *fmt, ...) CAIRO_PRINTF_FORMAT(2, 3);
|
||||
|
||||
#ifndef FALSE
|
||||
#define FALSE 0
|
||||
#endif
|
||||
#ifndef TRUE
|
||||
#define TRUE !FALSE
|
||||
#endif
|
||||
|
||||
CAIRO_END_DECLS
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -27,8 +27,6 @@
|
|||
#include <stdlib.h>
|
||||
|
||||
#include "buffer-diff.h"
|
||||
#include "read-png.h"
|
||||
#include "write-png.h"
|
||||
#include "xmalloc.h"
|
||||
|
||||
int
|
||||
|
|
|
|||
196
test/read-png.c
196
test/read-png.c
|
|
@ -1,196 +0,0 @@
|
|||
/*
|
||||
* Copyright © 2003 USC, Information Sciences Institute
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software
|
||||
* and its documentation for any purpose is hereby granted without
|
||||
* fee, provided that the above copyright notice appear in all copies
|
||||
* and that both that copyright notice and this permission notice
|
||||
* appear in supporting documentation, and that the name of the
|
||||
* University of Southern California not be used in advertising or
|
||||
* publicity pertaining to distribution of the software without
|
||||
* specific, written prior permission. The University of Southern
|
||||
* California makes no representations about the suitability of this
|
||||
* software for any purpose. It is provided "as is" without express
|
||||
* or implied warranty.
|
||||
*
|
||||
* THE UNIVERSITY OF SOUTHERN CALIFORNIA DISCLAIMS ALL WARRANTIES WITH
|
||||
* REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL THE UNIVERSITY OF
|
||||
* SOUTHERN CALIFORNIA BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
|
||||
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* Author: Carl D. Worth <cworth@isi.edu>
|
||||
*/
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#if HAVE_STDINT_H
|
||||
# include <stdint.h>
|
||||
#elif HAVE_INTTYPES_H
|
||||
# include <inttypes.h>
|
||||
#elif HAVE_SYS_INT_TYPES_H
|
||||
# include <sys/int_types.h>
|
||||
#elif defined(_MSC_VER)
|
||||
typedef __int8 int8_t;
|
||||
typedef unsigned __int8 uint8_t;
|
||||
typedef __int16 int16_t;
|
||||
typedef unsigned __int16 uint16_t;
|
||||
typedef __int32 int32_t;
|
||||
typedef unsigned __int32 uint32_t;
|
||||
typedef __int64 int64_t;
|
||||
typedef unsigned __int64 uint64_t;
|
||||
# ifndef HAVE_UINT64_T
|
||||
# define HAVE_UINT64_T 1
|
||||
# endif
|
||||
#else
|
||||
#error Cannot find definitions for fixed-width integral types (uint8_t, uint32_t, etc.)
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <png.h>
|
||||
|
||||
#include "cairo-test.h"
|
||||
#include "read-png.h"
|
||||
#include "xmalloc.h"
|
||||
|
||||
static void
|
||||
premultiply_data (png_structp png,
|
||||
png_row_infop row_info,
|
||||
png_bytep data)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < row_info->rowbytes; i += 4) {
|
||||
uint8_t *base = &data[i];
|
||||
uint8_t blue = base[0];
|
||||
uint8_t green = base[1];
|
||||
uint8_t red = base[2];
|
||||
uint8_t alpha = base[3];
|
||||
uint32_t p;
|
||||
|
||||
red = ((unsigned) red * (unsigned) alpha + 127) / 255;
|
||||
green = ((unsigned) green * (unsigned) alpha + 127) / 255;
|
||||
blue = ((unsigned) blue * (unsigned) alpha + 127) / 255;
|
||||
p = (alpha << 24) | (red << 16) | (green << 8) | (blue << 0);
|
||||
memcpy (base, &p, sizeof (uint32_t));
|
||||
}
|
||||
}
|
||||
|
||||
read_png_status_t
|
||||
read_png_argb32 (const char *filename,
|
||||
unsigned char **data,
|
||||
unsigned int *width,
|
||||
unsigned int *height,
|
||||
unsigned int *stride)
|
||||
{
|
||||
size_t i;
|
||||
FILE *file;
|
||||
#define PNG_SIG_SIZE 8
|
||||
unsigned char png_sig[PNG_SIG_SIZE];
|
||||
int sig_bytes;
|
||||
png_struct *png;
|
||||
png_info *info;
|
||||
png_uint_32 png_width, png_height;
|
||||
int depth, color_type, interlace;
|
||||
unsigned int pixel_size;
|
||||
png_byte **row_pointers;
|
||||
|
||||
file = fopen (filename, "rb");
|
||||
if (file == NULL) {
|
||||
cairo_test_log ("Error: File not found: %s\n", filename);
|
||||
return READ_PNG_FILE_NOT_FOUND;
|
||||
}
|
||||
|
||||
sig_bytes = fread (png_sig, 1, PNG_SIG_SIZE, file);
|
||||
if (png_check_sig (png_sig, sig_bytes) == 0) {
|
||||
fclose (file);
|
||||
cairo_test_log ("Error: File is not a PNG image: %s\n", filename);
|
||||
return READ_PNG_FILE_NOT_PNG;
|
||||
}
|
||||
|
||||
/* XXX: Perhaps we'll want some other error handlers? */
|
||||
png = png_create_read_struct (PNG_LIBPNG_VER_STRING,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
if (png == NULL) {
|
||||
fclose (file);
|
||||
cairo_test_log ("Error: Out of memory while reading %s\n", filename);
|
||||
return READ_PNG_NO_MEMORY;
|
||||
}
|
||||
|
||||
info = png_create_info_struct (png);
|
||||
if (info == NULL) {
|
||||
fclose (file);
|
||||
png_destroy_read_struct (&png, NULL, NULL);
|
||||
cairo_test_log ("Error: Out of memory while reading %s\n", filename);
|
||||
return READ_PNG_NO_MEMORY;
|
||||
}
|
||||
|
||||
png_init_io (png, file);
|
||||
png_set_sig_bytes (png, sig_bytes);
|
||||
|
||||
png_read_info (png, info);
|
||||
|
||||
png_get_IHDR (png, info,
|
||||
&png_width, &png_height, &depth,
|
||||
&color_type, &interlace, NULL, NULL);
|
||||
*width = png_width;
|
||||
*height = png_height;
|
||||
*stride = 4 * png_width;
|
||||
|
||||
/* convert palette/gray image to rgb */
|
||||
if (color_type == PNG_COLOR_TYPE_PALETTE)
|
||||
png_set_palette_to_rgb (png);
|
||||
|
||||
/* expand gray bit depth if needed */
|
||||
if (color_type == PNG_COLOR_TYPE_GRAY && depth < 8)
|
||||
png_set_gray_1_2_4_to_8 (png);
|
||||
/* transform transparency to alpha */
|
||||
if (png_get_valid(png, info, PNG_INFO_tRNS))
|
||||
png_set_tRNS_to_alpha (png);
|
||||
|
||||
if (depth == 16)
|
||||
png_set_strip_16 (png);
|
||||
|
||||
if (depth < 8)
|
||||
png_set_packing (png);
|
||||
|
||||
/* convert grayscale to RGB */
|
||||
if (color_type == PNG_COLOR_TYPE_GRAY
|
||||
|| color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
|
||||
png_set_gray_to_rgb (png);
|
||||
|
||||
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);
|
||||
|
||||
png_read_update_info (png, info);
|
||||
|
||||
pixel_size = 4;
|
||||
*data = xmalloc (png_width * png_height * pixel_size);
|
||||
|
||||
row_pointers = malloc (png_height * sizeof(char *));
|
||||
for (i=0; i < png_height; i++)
|
||||
row_pointers[i] = (png_byte *) (*data + i * png_width * pixel_size);
|
||||
|
||||
png_read_image (png, row_pointers);
|
||||
png_read_end (png, info);
|
||||
|
||||
free (row_pointers);
|
||||
fclose (file);
|
||||
|
||||
png_destroy_read_struct (&png, &info, NULL);
|
||||
|
||||
return READ_PNG_SUCCESS;
|
||||
}
|
||||
|
|
@ -1,45 +0,0 @@
|
|||
/*
|
||||
* Copyright © 2003 USC, Information Sciences Institute
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software
|
||||
* and its documentation for any purpose is hereby granted without
|
||||
* fee, provided that the above copyright notice appear in all copies
|
||||
* and that both that copyright notice and this permission notice
|
||||
* appear in supporting documentation, and that the name of the
|
||||
* University of Southern California not be used in advertising or
|
||||
* publicity pertaining to distribution of the software without
|
||||
* specific, written prior permission. The University of Southern
|
||||
* California makes no representations about the suitability of this
|
||||
* software for any purpose. It is provided "as is" without express
|
||||
* or implied warranty.
|
||||
*
|
||||
* THE UNIVERSITY OF SOUTHERN CALIFORNIA DISCLAIMS ALL WARRANTIES WITH
|
||||
* REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL THE UNIVERSITY OF
|
||||
* SOUTHERN CALIFORNIA BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
|
||||
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* Author: Carl D. Worth <cworth@isi.edu>
|
||||
*/
|
||||
|
||||
#ifndef READ_PNG_H
|
||||
#define READ_PNG_H
|
||||
|
||||
typedef enum {
|
||||
READ_PNG_SUCCESS = 0,
|
||||
READ_PNG_FILE_NOT_FOUND,
|
||||
READ_PNG_FILE_NOT_PNG,
|
||||
READ_PNG_NO_MEMORY
|
||||
} read_png_status_t;
|
||||
|
||||
read_png_status_t
|
||||
read_png_argb32 (const char *filename,
|
||||
unsigned char **data,
|
||||
unsigned int *width,
|
||||
unsigned int *height,
|
||||
unsigned int *stride);
|
||||
|
||||
#endif
|
||||
|
|
@ -1,99 +0,0 @@
|
|||
/*
|
||||
* Copyright © 2003 USC, Information Sciences Institute
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software
|
||||
* and its documentation for any purpose is hereby granted without
|
||||
* fee, provided that the above copyright notice appear in all copies
|
||||
* and that both that copyright notice and this permission notice
|
||||
* appear in supporting documentation, and that the name of the
|
||||
* University of Southern California not be used in advertising or
|
||||
* publicity pertaining to distribution of the software without
|
||||
* specific, written prior permission. The University of Southern
|
||||
* California makes no representations about the suitability of this
|
||||
* software for any purpose. It is provided "as is" without express
|
||||
* or implied warranty.
|
||||
*
|
||||
* THE UNIVERSITY OF SOUTHERN CALIFORNIA DISCLAIMS ALL WARRANTIES WITH
|
||||
* REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL THE UNIVERSITY OF
|
||||
* SOUTHERN CALIFORNIA BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
|
||||
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* Author: Carl D. Worth <cworth@cworth.org>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <png.h>
|
||||
|
||||
#include "write-png.h"
|
||||
|
||||
static void
|
||||
unpremultiply_data (png_structp png, png_row_infop row_info, png_bytep data)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < row_info->rowbytes; i += 4) {
|
||||
unsigned char *b = &data[i];
|
||||
unsigned int pixel;
|
||||
unsigned char alpha;
|
||||
|
||||
memcpy (&pixel, b, sizeof (unsigned int));
|
||||
alpha = (pixel & 0xff000000) >> 24;
|
||||
if (alpha == 0) {
|
||||
b[0] = b[1] = b[2] = b[3] = 0;
|
||||
} else {
|
||||
b[0] = (((pixel & 0x0000ff) >> 0) * 255 + alpha / 2) / alpha;
|
||||
b[1] = (((pixel & 0x00ff00) >> 8) * 255 + alpha / 2) / alpha;
|
||||
b[2] = (((pixel & 0xff0000) >> 16) * 255 + alpha / 2) / alpha;
|
||||
b[3] = alpha;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
write_png_argb32 (unsigned char *buffer, FILE *file,
|
||||
int width, int height, int stride)
|
||||
{
|
||||
int i;
|
||||
png_struct *png;
|
||||
png_info *info;
|
||||
png_byte **rows;
|
||||
png_color_16 white;
|
||||
|
||||
rows = malloc (height * sizeof(png_byte*));
|
||||
|
||||
for (i = 0; i < height; i++) {
|
||||
rows[i] = buffer + i * stride;
|
||||
}
|
||||
|
||||
png = png_create_write_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
|
||||
info = png_create_info_struct (png);
|
||||
|
||||
png_init_io (png, file);
|
||||
png_set_IHDR (png, info,
|
||||
width, height, 8,
|
||||
PNG_COLOR_TYPE_RGB_ALPHA,
|
||||
PNG_INTERLACE_NONE,
|
||||
PNG_COMPRESSION_TYPE_DEFAULT,
|
||||
PNG_FILTER_TYPE_DEFAULT);
|
||||
|
||||
white.red = 0xff;
|
||||
white.blue = 0xff;
|
||||
white.green = 0xff;
|
||||
png_set_bKGD (png, info, &white);
|
||||
|
||||
png_set_write_user_transform_fn (png, unpremultiply_data);
|
||||
png_set_bgr (png);
|
||||
|
||||
png_write_info (png, info);
|
||||
png_write_image (png, rows);
|
||||
png_write_end (png, info);
|
||||
|
||||
png_destroy_write_struct (&png, &info);
|
||||
|
||||
free (rows);
|
||||
}
|
||||
|
|
@ -1,35 +0,0 @@
|
|||
/*
|
||||
* Copyright © 2003 USC, Information Sciences Institute
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software
|
||||
* and its documentation for any purpose is hereby granted without
|
||||
* fee, provided that the above copyright notice appear in all copies
|
||||
* and that both that copyright notice and this permission notice
|
||||
* appear in supporting documentation, and that the name of the
|
||||
* University of Southern California not be used in advertising or
|
||||
* publicity pertaining to distribution of the software without
|
||||
* specific, written prior permission. The University of Southern
|
||||
* California makes no representations about the suitability of this
|
||||
* software for any purpose. It is provided "as is" without express
|
||||
* or implied warranty.
|
||||
*
|
||||
* THE UNIVERSITY OF SOUTHERN CALIFORNIA DISCLAIMS ALL WARRANTIES WITH
|
||||
* REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL THE UNIVERSITY OF
|
||||
* SOUTHERN CALIFORNIA BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
|
||||
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* Author: Carl D. Worth <cworth@isi.edu>
|
||||
*/
|
||||
|
||||
#ifndef WRITE_PNG_H
|
||||
#define WRITE_PNG_H
|
||||
|
||||
void
|
||||
write_png_argb32 (unsigned char *buffer, FILE * file,
|
||||
int width, int height, int stride);
|
||||
|
||||
#endif
|
||||
Loading…
Add table
Reference in a new issue