libpng 1.5.1

git-svn-id: svn://kolibrios.org@1897 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
Sergey Semyonov (Serge) 2011-03-01 21:41:20 +00:00
parent 1cf1e308d4
commit a359038b4b
37 changed files with 45530 additions and 66 deletions

View File

@ -8,9 +8,9 @@ CFLAGS = -c -O2 -fomit-frame-pointer
DEFINES = -DHAVE_CONFIG_H -DCAIRO_NO_MUTEX -U_WIN32 -U_MSC_VER -U__WIN32__ DEFINES = -DHAVE_CONFIG_H -DCAIRO_NO_MUTEX -U_WIN32 -U_MSC_VER -U__WIN32__
INCLUDES = -I../pixman -I../newlib/include -I../newlib/include/sys INCLUDES = -I../newlib/include -I../pixman -I../zlib -I../libpng
SOURCES = \ CAIRO_SOURCES = \
cairo-analysis-surface.c \ cairo-analysis-surface.c \
cairo-arc.c \ cairo-arc.c \
cairo-array.c \ cairo-array.c \
@ -24,67 +24,80 @@ SOURCES = \
cairo-boxes.c \ cairo-boxes.c \
cairo.c \ cairo.c \
cairo-cache.c \ cairo-cache.c \
cairo-clip.c \ cairo-clip.c \
cairo-color.c \ cairo-color.c \
cairo-composite-rectangles.c \ cairo-composite-rectangles.c \
cairo-device.c \ cairo-device.c \
cairo-fixed.c \ cairo-fixed.c \
cairo-font-face.c \ cairo-font-face.c \
cairo-font-face-twin.c \ cairo-font-face-twin.c \
cairo-font-face-twin-data.c \ cairo-font-face-twin-data.c \
cairo-font-options.c \ cairo-font-options.c \
cairo-freelist.c \ cairo-freelist.c \
cairo-freed-pool.c \ cairo-freed-pool.c \
cairo-gstate.c \ cairo-gstate.c \
cairo-hash.c \ cairo-hash.c \
cairo-hull.c \ cairo-hull.c \
cairo-image-info.c \ cairo-image-info.c \
cairo-image-surface.c \ cairo-image-surface.c \
cairo-lzw.c \ cairo-lzw.c \
cairo-matrix.c \ cairo-matrix.c \
cairo-recording-surface.c \ cairo-recording-surface.c \
cairo-misc.c \ cairo-misc.c \
cairo-mutex.c \ cairo-mutex.c \
cairo-observer.c \ cairo-observer.c \
cairo-output-stream.c \ cairo-output-stream.c \
cairo-paginated-surface.c \ cairo-paginated-surface.c \
cairo-path-bounds.c \ cairo-path-bounds.c \
cairo-path.c \ cairo-path.c \
cairo-path-fill.c \ cairo-path-fill.c \
cairo-path-fixed.c \ cairo-path-fixed.c \
cairo-path-in-fill.c \ cairo-path-in-fill.c \
cairo-path-stroke.c \ cairo-path-stroke.c \
cairo-pattern.c \ cairo-pattern.c \
cairo-pen.c \ cairo-pdf-operators.c \
cairo-polygon.c \ cairo-pen.c \
cairo-rectangle.c \ cairo-png.c \
cairo-rectangular-scan-converter.c \ cairo-polygon.c \
cairo-region.c \ cairo-rectangle.c \
cairo-rtree.c \ cairo-rectangular-scan-converter.c \
cairo-scaled-font.c \ cairo-region.c \
cairo-slope.c \ cairo-rtree.c \
cairo-spans.c \ cairo-scaled-font.c \
cairo-spline.c \ cairo-slope.c \
cairo-stroke-style.c \ cairo-spans.c \
cairo-surface.c \ cairo-spline.c \
cairo-surface-fallback.c \ cairo-stroke-style.c \
cairo-surface-clipper.c \ cairo-surface.c \
cairo-surface-offset.c \ cairo-surface-fallback.c \
cairo-surface-snapshot.c \ cairo-surface-clipper.c \
cairo-surface-subsurface.c \ cairo-surface-offset.c \
cairo-surface-wrapper.c \ cairo-surface-snapshot.c \
cairo-tor-scan-converter.c \ cairo-surface-subsurface.c \
cairo-toy-font-face.c \ cairo-surface-wrapper.c \
cairo-traps.c \ cairo-svg-surface.c \
cairo-unicode.c \ cairo-tor-scan-converter.c \
cairo-user-font.c \ cairo-toy-font-face.c \
cairo-version.c \ cairo-traps.c \
cairo-wideint.c \ cairo-unicode.c \
cairo-user-font.c \
cairo-version.c \
cairo-wideint.c \
$(NULL) $(NULL)
CAIRO_FONT = \
cairo-cff-subset.c \
cairo-scaled-font-subsets.c \
cairo-truetype-subset.c \
cairo-type1-fallback.c \
cairo-type1-subset.c \
cairo-type3-glyph-surface.c \
$(NULL)
SOURCES= $(CAIRO_SOURCES) $(CAIRO_FONT)
OBJECTS = $(patsubst %.c, src/%.o, $(SOURCES)) OBJECTS = $(patsubst %.c, src/%.o, $(SOURCES))

View File

@ -24,11 +24,13 @@
/* Define to 1 to enable cairo's cairo-script-interpreter feature */ /* Define to 1 to enable cairo's cairo-script-interpreter feature */
//#define CAIRO_HAS_INTERPRETER 1 //#define CAIRO_HAS_INTERPRETER 1
#define CAIRO_NO_MUTEX 1
/* Define to 1 to enable cairo's pthread feature */ /* Define to 1 to enable cairo's pthread feature */
//#define CAIRO_HAS_PTHREAD 1 /* #undef CAIRO_HAS_PTHREAD */
/* Define to 1 if we have full pthread support */ /* Define to 1 if we have full pthread support */
//#define CAIRO_HAS_REAL_PTHREAD 1 /* #undef CAIRO_HAS_REAL_PTHREAD */
/* Define to 1 if libspectre is available */ /* Define to 1 if libspectre is available */
/* #undef CAIRO_HAS_SPECTRE */ /* #undef CAIRO_HAS_SPECTRE */
@ -40,7 +42,7 @@
/* #undef CAIRO_HAS_TEST_SURFACES */ /* #undef CAIRO_HAS_TEST_SURFACES */
/* Define to 1 to enable cairo's cairo-trace feature */ /* Define to 1 to enable cairo's cairo-trace feature */
//#define CAIRO_HAS_TRACE 1 /* #undef CAIRO_HAS_TRACE */
/* Define to 1 to disable certain code paths that rely heavily on double /* Define to 1 to disable certain code paths that rely heavily on double
precision floating-point calculation */ precision floating-point calculation */
@ -73,7 +75,7 @@
#define HAVE_DLFCN_H 1 #define HAVE_DLFCN_H 1
/* Define to 1 if you have the `drand48' function. */ /* Define to 1 if you have the `drand48' function. */
//#define HAVE_DRAND48 1 #define HAVE_DRAND48 1
/* Define to 1 if you have the `FcFini' function. */ /* Define to 1 if you have the `FcFini' function. */
/* #undef HAVE_FCFINI */ /* #undef HAVE_FCFINI */
@ -173,7 +175,7 @@
//#define HAVE_SCHED_H 1 //#define HAVE_SCHED_H 1
/* Define to 1 if you have the <setjmp.h> header file. */ /* Define to 1 if you have the <setjmp.h> header file. */
//#define HAVE_SETJMP_H 1 #define HAVE_SETJMP_H 1
/* Define to 1 if you have the <signal.h> header file. */ /* Define to 1 if you have the <signal.h> header file. */
//#define HAVE_SIGNAL_H 1 //#define HAVE_SIGNAL_H 1
@ -342,7 +344,7 @@
#define X_DISPLAY_MISSING 1 #define X_DISPLAY_MISSING 1
/* Number of bits in a file offset, on hosts where this is settable. */ /* Number of bits in a file offset, on hosts where this is settable. */
#define _FILE_OFFSET_BITS 64 /* #undef _FILE_OFFSET_BITS */
/* Define for large files, on AIX-style hosts. */ /* Define for large files, on AIX-style hosts. */
/* #undef _LARGE_FILES */ /* #undef _LARGE_FILES */
@ -362,5 +364,3 @@
#ifndef __cplusplus #ifndef __cplusplus
/* #undef inline */ /* #undef inline */
#endif #endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,798 @@
/* cairo - a vector graphics library with display and print output
*
* Copyright © 2003 University of Southern California
*
* This library is free software; you can redistribute it and/or
* modify it either under the terms of the GNU Lesser General Public
* License version 2.1 as published by the Free Software Foundation
* (the "LGPL") or, at your option, under the terms of the Mozilla
* Public License Version 1.1 (the "MPL"). If you do not alter this
* notice, a recipient may use your version of this file under either
* the MPL or the LGPL.
*
* You should have received a copy of the LGPL along with this library
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
* You should have received a copy of the MPL along with this library
* in the file COPYING-MPL-1.1
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
* the specific language governing rights and limitations.
*
* The Original Code is the cairo graphics library.
*
* The Initial Developer of the Original Code is University of Southern
* California.
*
* Contributor(s):
* Carl D. Worth <cworth@cworth.org>
* Kristian Høgsberg <krh@redhat.com>
* Chris Wilson <chris@chris-wilson.co.uk>
*/
#include "cairoint.h"
#include "cairo-error-private.h"
#include "cairo-output-stream-private.h"
#include <stdio.h>
#include <errno.h>
#include <png.h>
/**
* SECTION:cairo-png
* @Title: PNG Support
* @Short_Description: Reading and writing PNG images
* @See_Also: #cairo_surface_t
*
* The PNG functions allow reading PNG images into image surfaces, and writing
* any surface to a PNG file.
*/
/**
* CAIRO_HAS_PNG_FUNCTIONS:
*
* Defined if the PNG functions are available.
* This macro can be used to conditionally compile code using the cairo
* PNG functions.
*/
struct png_read_closure_t {
cairo_read_func_t read_func;
void *closure;
cairo_output_stream_t *png_data;
};
/* Unpremultiplies data and converts native endian ARGB => RGBA bytes */
static void
unpremultiply_data (png_structp png, png_row_infop row_info, png_bytep data)
{
unsigned int i;
for (i = 0; i < row_info->rowbytes; i += 4) {
uint8_t *b = &data[i];
uint32_t pixel;
uint8_t alpha;
memcpy (&pixel, b, sizeof (uint32_t));
alpha = (pixel & 0xff000000) >> 24;
if (alpha == 0) {
b[0] = b[1] = b[2] = b[3] = 0;
} else {
b[0] = (((pixel & 0xff0000) >> 16) * 255 + alpha / 2) / alpha;
b[1] = (((pixel & 0x00ff00) >> 8) * 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)
{
unsigned 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;
}
}
/* Use a couple of simple error callbacks that do not print anything to
* stderr and rely on the user to check for errors via the #cairo_status_t
* return.
*/
static void
png_simple_error_callback (png_structp png,
png_const_charp error_msg)
{
cairo_status_t *error = png_get_error_ptr (png);
/* default to the most likely error */
if (*error == CAIRO_STATUS_SUCCESS)
*error = _cairo_error (CAIRO_STATUS_NO_MEMORY);
#ifdef PNG_SETJMP_SUPPORTED
longjmp (png_jmpbuf (png), 1);
#endif
/* if we get here, then we have to choice but to abort ... */
}
static void
png_simple_warning_callback (png_structp png,
png_const_charp error_msg)
{
cairo_status_t *error = png_get_error_ptr (png);
/* default to the most likely error */
if (*error == CAIRO_STATUS_SUCCESS)
*error = _cairo_error (CAIRO_STATUS_NO_MEMORY);
/* png does not expect to abort and will try to tidy up after a warning */
}
/* Starting with libpng-1.2.30, we must explicitly specify an output_flush_fn.
* Otherwise, we will segfault if we are writing to a stream. */
static void
png_simple_output_flush_fn (png_structp png_ptr)
{
}
static cairo_status_t
write_png (cairo_surface_t *surface,
png_rw_ptr write_func,
void *closure)
{
int i;
cairo_status_t status;
cairo_image_surface_t *image;
cairo_image_surface_t * volatile clone;
void *image_extra;
png_struct *png;
png_info *info;
png_byte **volatile rows = NULL;
png_color_16 white;
int png_color_type;
int depth;
status = _cairo_surface_acquire_source_image (surface,
&image,
&image_extra);
if (status == CAIRO_INT_STATUS_UNSUPPORTED)
return _cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
else if (unlikely (status))
return status;
/* PNG complains about "Image width or height is zero in IHDR" */
if (image->width == 0 || image->height == 0) {
status = _cairo_error (CAIRO_STATUS_WRITE_ERROR);
goto BAIL1;
}
/* Handle the various fallback formats (e.g. low bit-depth XServers)
* by coercing them to a simpler format using pixman.
*/
clone = _cairo_image_surface_coerce (image);
status = clone->base.status;
if (unlikely (status))
goto BAIL1;
rows = _cairo_malloc_ab (clone->height, sizeof (png_byte*));
if (unlikely (rows == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto BAIL2;
}
for (i = 0; i < clone->height; i++)
rows[i] = (png_byte *) clone->data + i * clone->stride;
png = png_create_write_struct (PNG_LIBPNG_VER_STRING, &status,
png_simple_error_callback,
png_simple_warning_callback);
if (unlikely (png == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto BAIL3;
}
info = png_create_info_struct (png);
if (unlikely (info == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto BAIL4;
}
#ifdef PNG_SETJMP_SUPPORTED
if (setjmp (png_jmpbuf (png)))
goto BAIL4;
#endif
png_set_write_fn (png, closure, write_func, png_simple_output_flush_fn);
switch (clone->format) {
case CAIRO_FORMAT_ARGB32:
depth = 8;
if (_cairo_image_analyze_transparency (clone) == CAIRO_IMAGE_IS_OPAQUE)
png_color_type = PNG_COLOR_TYPE_RGB;
else
png_color_type = PNG_COLOR_TYPE_RGB_ALPHA;
break;
case CAIRO_FORMAT_RGB24:
depth = 8;
png_color_type = PNG_COLOR_TYPE_RGB;
break;
case CAIRO_FORMAT_A8:
depth = 8;
png_color_type = PNG_COLOR_TYPE_GRAY;
break;
case CAIRO_FORMAT_A1:
depth = 1;
png_color_type = PNG_COLOR_TYPE_GRAY;
#ifndef WORDS_BIGENDIAN
png_set_packswap (png);
#endif
break;
case CAIRO_FORMAT_INVALID:
case CAIRO_FORMAT_RGB16_565:
default:
status = _cairo_error (CAIRO_STATUS_INVALID_FORMAT);
goto BAIL4;
}
png_set_IHDR (png, info,
clone->width,
clone->height, depth,
png_color_type,
PNG_INTERLACE_NONE,
PNG_COMPRESSION_TYPE_DEFAULT,
PNG_FILTER_TYPE_DEFAULT);
white.gray = (1 << depth) - 1;
white.red = white.blue = white.green = white.gray;
png_set_bKGD (png, info, &white);
if (0) { /* XXX extract meta-data from surface (i.e. creation date) */
png_time pt;
png_convert_from_time_t (&pt, time (NULL));
png_set_tIME (png, info, &pt);
}
/* 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 (png_color_type == PNG_COLOR_TYPE_RGB_ALPHA) {
png_set_write_user_transform_fn (png, unpremultiply_data);
} else if (png_color_type == PNG_COLOR_TYPE_RGB) {
png_set_write_user_transform_fn (png, convert_data_to_bytes);
png_set_filler (png, 0, PNG_FILLER_AFTER);
}
png_write_image (png, rows);
png_write_end (png, info);
BAIL4:
png_destroy_write_struct (&png, &info);
BAIL3:
free (rows);
BAIL2:
cairo_surface_destroy (&clone->base);
BAIL1:
_cairo_surface_release_source_image (surface, image, image_extra);
return status;
}
static void
stdio_write_func (png_structp png, png_bytep data, png_size_t size)
{
FILE *fp;
fp = png_get_io_ptr (png);
while (size) {
size_t ret = fwrite (data, 1, size, fp);
size -= ret;
data += ret;
if (size && ferror (fp)) {
cairo_status_t *error = png_get_error_ptr (png);
if (*error == CAIRO_STATUS_SUCCESS)
*error = _cairo_error (CAIRO_STATUS_WRITE_ERROR);
png_error (png, NULL);
}
}
}
/**
* cairo_surface_write_to_png:
* @surface: a #cairo_surface_t with pixel contents
* @filename: the name of a file to write to
*
* Writes the contents of @surface to a new file @filename as a PNG
* image.
*
* Return value: %CAIRO_STATUS_SUCCESS if the PNG file was written
* successfully. Otherwise, %CAIRO_STATUS_NO_MEMORY if memory could not
* be allocated for the operation or
* %CAIRO_STATUS_SURFACE_TYPE_MISMATCH if the surface does not have
* pixel contents, or %CAIRO_STATUS_WRITE_ERROR if an I/O error occurs
* while attempting to write the file.
**/
cairo_status_t
cairo_surface_write_to_png (cairo_surface_t *surface,
const char *filename)
{
FILE *fp;
cairo_status_t status;
if (surface->status)
return surface->status;
if (surface->finished)
return _cairo_error (CAIRO_STATUS_SURFACE_FINISHED);
fp = fopen (filename, "wb");
if (fp == NULL) {
switch (errno) {
case ENOMEM:
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
default:
return _cairo_error (CAIRO_STATUS_WRITE_ERROR);
}
}
status = write_png (surface, stdio_write_func, fp);
if (fclose (fp) && status == CAIRO_STATUS_SUCCESS)
status = _cairo_error (CAIRO_STATUS_WRITE_ERROR);
return status;
}
struct png_write_closure_t {
cairo_write_func_t write_func;
void *closure;
};
static void
stream_write_func (png_structp png, png_bytep data, png_size_t size)
{
cairo_status_t status;
struct png_write_closure_t *png_closure;
png_closure = png_get_io_ptr (png);
status = png_closure->write_func (png_closure->closure, data, size);
if (unlikely (status)) {
cairo_status_t *error = png_get_error_ptr (png);
if (*error == CAIRO_STATUS_SUCCESS)
*error = status;
png_error (png, NULL);
}
}
/**
* cairo_surface_write_to_png_stream:
* @surface: a #cairo_surface_t with pixel contents
* @write_func: a #cairo_write_func_t
* @closure: closure data for the write function
*
* Writes the image surface to the write function.
*
* Return value: %CAIRO_STATUS_SUCCESS if the PNG file was written
* successfully. Otherwise, %CAIRO_STATUS_NO_MEMORY is returned if
* memory could not be allocated for the operation,
* %CAIRO_STATUS_SURFACE_TYPE_MISMATCH if the surface does not have
* pixel contents.
**/
cairo_status_t
cairo_surface_write_to_png_stream (cairo_surface_t *surface,
cairo_write_func_t write_func,
void *closure)
{
struct png_write_closure_t png_closure;
if (surface->status)
return surface->status;
if (surface->finished)
return _cairo_error (CAIRO_STATUS_SURFACE_FINISHED);
png_closure.write_func = write_func;
png_closure.closure = closure;
return write_png (surface, stream_write_func, &png_closure);
}
slim_hidden_def (cairo_surface_write_to_png_stream);
static inline int
multiply_alpha (int alpha, int color)
{
int temp = (alpha * color) + 0x80;
return ((temp + (temp >> 8)) >> 8);
}
/* Premultiplies data and converts RGBA bytes => native endian */
static void
premultiply_data (png_structp png,
png_row_infop row_info,
png_bytep data)
{
unsigned int i;
for (i = 0; i < row_info->rowbytes; i += 4) {
uint8_t *base = &data[i];
uint8_t alpha = base[3];
uint32_t p;
if (alpha == 0) {
p = 0;
} else {
uint8_t red = base[0];
uint8_t green = base[1];
uint8_t blue = base[2];
if (alpha != 0xff) {
red = multiply_alpha (alpha, red);
green = multiply_alpha (alpha, green);
blue = multiply_alpha (alpha, blue);
}
p = (alpha << 24) | (red << 16) | (green << 8) | (blue << 0);
}
memcpy (base, &p, sizeof (uint32_t));
}
}
/* Converts RGBx bytes to native endian xRGB */
static void
convert_bytes_to_data (png_structp png, png_row_infop row_info, png_bytep data)
{
unsigned int i;
for (i = 0; i < row_info->rowbytes; i += 4) {
uint8_t *base = &data[i];
uint8_t red = base[0];
uint8_t green = base[1];
uint8_t blue = base[2];
uint32_t pixel;
pixel = (0xff << 24) | (red << 16) | (green << 8) | (blue << 0);
memcpy (base, &pixel, sizeof (uint32_t));
}
}
static cairo_status_t
stdio_read_func (void *closure, unsigned char *data, unsigned int size)
{
FILE *file = closure;
while (size) {
size_t ret;
ret = fread (data, 1, size, file);
size -= ret;
data += ret;
if (size && (feof (file) || ferror (file)))
return _cairo_error (CAIRO_STATUS_READ_ERROR);
}
return CAIRO_STATUS_SUCCESS;
}
static void
stream_read_func (png_structp png, png_bytep data, png_size_t size)
{
cairo_status_t status;
struct png_read_closure_t *png_closure;
png_closure = png_get_io_ptr (png);
status = png_closure->read_func (png_closure->closure, data, size);
if (unlikely (status)) {
cairo_status_t *error = png_get_error_ptr (png);
if (*error == CAIRO_STATUS_SUCCESS)
*error = status;
png_error (png, NULL);
}
_cairo_output_stream_write (png_closure->png_data, data, size);
}
static cairo_surface_t *
read_png (struct png_read_closure_t *png_closure)
{
cairo_surface_t *surface;
png_struct *png = NULL;
png_info *info;
png_byte *data = NULL;
png_byte **row_pointers = NULL;
png_uint_32 png_width, png_height;
int depth, color_type, interlace, stride;
unsigned int i;
cairo_format_t format;
cairo_status_t status;
unsigned char *mime_data;
unsigned long mime_data_length;
png_closure->png_data = _cairo_memory_stream_create ();
/* XXX: Perhaps we'll want some other error handlers? */
png = png_create_read_struct (PNG_LIBPNG_VER_STRING,
&status,
png_simple_error_callback,
png_simple_warning_callback);
if (unlikely (png == NULL)) {
surface = _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
goto BAIL;
}
info = png_create_info_struct (png);
if (unlikely (info == NULL)) {
surface = _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
goto BAIL;
}
png_set_read_fn (png, png_closure, stream_read_func);
status = CAIRO_STATUS_SUCCESS;
#ifdef PNG_SETJMP_SUPPORTED
if (setjmp (png_jmpbuf (png))) {
surface = _cairo_surface_create_in_error (status);
goto BAIL;
}
#endif
png_read_info (png, info);
png_get_IHDR (png, info,
&png_width, &png_height, &depth,
&color_type, &interlace, NULL, NULL);
if (unlikely (status)) { /* catch any early warnings */
surface = _cairo_surface_create_in_error (status);
goto BAIL;
}
/* 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) {
#if PNG_LIBPNG_VER >= 10209
png_set_expand_gray_1_2_4_to_8 (png);
#else
png_set_gray_1_2_4_to_8 (png);
#endif
}
/* 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_filler (png, 0xff, PNG_FILLER_AFTER);
/* recheck header after setting EXPAND options */
png_read_update_info (png, info);
png_get_IHDR (png, info,
&png_width, &png_height, &depth,
&color_type, &interlace, NULL, NULL);
if (depth != 8 ||
! (color_type == PNG_COLOR_TYPE_RGB ||
color_type == PNG_COLOR_TYPE_RGB_ALPHA))
{
surface = _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_READ_ERROR));
goto BAIL;
}
switch (color_type) {
default:
ASSERT_NOT_REACHED;
/* fall-through just in case ;-) */
case PNG_COLOR_TYPE_RGB_ALPHA:
format = CAIRO_FORMAT_ARGB32;
png_set_read_user_transform_fn (png, premultiply_data);
break;
case PNG_COLOR_TYPE_RGB:
format = CAIRO_FORMAT_RGB24;
png_set_read_user_transform_fn (png, convert_bytes_to_data);
break;
}
stride = cairo_format_stride_for_width (format, png_width);
if (stride < 0) {
surface = _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_STRIDE));
goto BAIL;
}
data = _cairo_malloc_ab (png_height, stride);
if (unlikely (data == NULL)) {
surface = _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
goto BAIL;
}
row_pointers = _cairo_malloc_ab (png_height, sizeof (char *));
if (unlikely (row_pointers == NULL)) {
surface = _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
goto BAIL;
}
for (i = 0; i < png_height; i++)
row_pointers[i] = &data[i * stride];
png_read_image (png, row_pointers);
png_read_end (png, info);
if (unlikely (status)) { /* catch any late warnings - probably hit an error already */
surface = _cairo_surface_create_in_error (status);
goto BAIL;
}
surface = cairo_image_surface_create_for_data (data, format,
png_width, png_height,
stride);
if (surface->status)
goto BAIL;
_cairo_image_surface_assume_ownership_of_data ((cairo_image_surface_t*)surface);
data = NULL;
_cairo_debug_check_image_surface_is_defined (surface);
status = _cairo_memory_stream_destroy (png_closure->png_data,
&mime_data,
&mime_data_length);
png_closure->png_data = NULL;
if (unlikely (status)) {
cairo_surface_destroy (surface);
surface = _cairo_surface_create_in_error (status);
goto BAIL;
}
status = cairo_surface_set_mime_data (surface,
CAIRO_MIME_TYPE_PNG,
mime_data,
mime_data_length,
free,
mime_data);
if (unlikely (status)) {
free (mime_data);
cairo_surface_destroy (surface);
surface = _cairo_surface_create_in_error (status);
goto BAIL;
}
BAIL:
if (row_pointers != NULL)
free (row_pointers);
if (data != NULL)
free (data);
if (png != NULL)
png_destroy_read_struct (&png, &info, NULL);
if (png_closure->png_data != NULL) {
cairo_status_t status_ignored;
status_ignored = _cairo_output_stream_destroy (png_closure->png_data);
}
return surface;
}
/**
* cairo_image_surface_create_from_png:
* @filename: name of PNG file to load
*
* Creates a new image surface and initializes the contents to the
* given PNG file.
*
* Return value: a new #cairo_surface_t initialized with the contents
* of the PNG file, or a "nil" surface if any error occurred. A nil
* surface can be checked for with cairo_surface_status(surface) which
* may return one of the following values:
*
* %CAIRO_STATUS_NO_MEMORY
* %CAIRO_STATUS_FILE_NOT_FOUND
* %CAIRO_STATUS_READ_ERROR
*
* Alternatively, you can allow errors to propagate through the drawing
* operations and check the status on the context upon completion
* using cairo_status().
**/
cairo_surface_t *
cairo_image_surface_create_from_png (const char *filename)
{
struct png_read_closure_t png_closure;
cairo_surface_t *surface;
png_closure.closure = fopen (filename, "rb");
if (png_closure.closure == NULL) {
cairo_status_t status;
switch (errno) {
case ENOMEM:
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
break;
case ENOENT:
status = _cairo_error (CAIRO_STATUS_FILE_NOT_FOUND);
break;
default:
status = _cairo_error (CAIRO_STATUS_READ_ERROR);
break;
}
return _cairo_surface_create_in_error (status);
}
png_closure.read_func = stdio_read_func;
surface = read_png (&png_closure);
fclose (png_closure.closure);
return surface;
}
/**
* cairo_image_surface_create_from_png_stream:
* @read_func: function called to read the data of the file
* @closure: data to pass to @read_func.
*
* Creates a new image surface from PNG data read incrementally
* via the @read_func function.
*
* Return value: a new #cairo_surface_t initialized with the contents
* of the PNG file or a "nil" surface if the data read is not a valid PNG image
* or memory could not be allocated for the operation. A nil
* surface can be checked for with cairo_surface_status(surface) which
* may return one of the following values:
*
* %CAIRO_STATUS_NO_MEMORY
* %CAIRO_STATUS_READ_ERROR
*
* Alternatively, you can allow errors to propagate through the drawing
* operations and check the status on the context upon completion
* using cairo_status().
**/
cairo_surface_t *
cairo_image_surface_create_from_png_stream (cairo_read_func_t read_func,
void *closure)
{
struct png_read_closure_t png_closure;
png_closure.read_func = read_func;
png_closure.closure = closure;
return read_png (&png_closure);
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,887 @@
/* cairo - a vector graphics library with display and print output
*
* Copyright © 2006 Red Hat, Inc
*
* This library is free software; you can redistribute it and/or
* modify it either under the terms of the GNU Lesser General Public
* License version 2.1 as published by the Free Software Foundation
* (the "LGPL") or, at your option, under the terms of the Mozilla
* Public License Version 1.1 (the "MPL"). If you do not alter this
* notice, a recipient may use your version of this file under either
* the MPL or the LGPL.
*
* You should have received a copy of the LGPL along with this library
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
* You should have received a copy of the MPL along with this library
* in the file COPYING-MPL-1.1
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
* the specific language governing rights and limitations.
*
* The Original Code is the cairo graphics library.
*
* The Initial Developer of the Original Code is Red Hat, Inc.
*
* Contributor(s):
* Adrian Johnson <ajohnson@redneon.com>
*/
#define _BSD_SOURCE /* for snprintf(), strdup() */
#include "cairoint.h"
#include "cairo-error-private.h"
#if CAIRO_HAS_FONT_SUBSET
#include "cairo-type1-private.h"
#include "cairo-scaled-font-subsets-private.h"
#include "cairo-path-fixed-private.h"
#include "cairo-output-stream-private.h"
typedef enum {
CAIRO_CHARSTRING_TYPE1,
CAIRO_CHARSTRING_TYPE2
} cairo_charstring_type_t;
typedef struct _cairo_type1_font {
int *widths;
cairo_scaled_font_subset_t *scaled_font_subset;
cairo_scaled_font_t *type1_scaled_font;
cairo_array_t contents;
double x_min, y_min, x_max, y_max;
const char *data;
unsigned long header_size;
unsigned long data_size;
unsigned long trailer_size;
int bbox_position;
int bbox_max_chars;
cairo_output_stream_t *output;
unsigned short eexec_key;
cairo_bool_t hex_encode;
int hex_column;
} cairo_type1_font_t;
static cairo_status_t
cairo_type1_font_create (cairo_scaled_font_subset_t *scaled_font_subset,
cairo_type1_font_t **subset_return,
cairo_bool_t hex_encode)
{
cairo_type1_font_t *font;
cairo_font_face_t *font_face;
cairo_matrix_t font_matrix;
cairo_matrix_t ctm;
cairo_font_options_t font_options;
cairo_status_t status;
font = calloc (1, sizeof (cairo_type1_font_t));
if (unlikely (font == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
font->widths = calloc (scaled_font_subset->num_glyphs, sizeof (int));
if (unlikely (font->widths == NULL)) {
free (font);
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
}
font->scaled_font_subset = scaled_font_subset;
font->hex_encode = hex_encode;
font_face = cairo_scaled_font_get_font_face (scaled_font_subset->scaled_font);
cairo_matrix_init_scale (&font_matrix, 1000, -1000);
cairo_matrix_init_identity (&ctm);
_cairo_font_options_init_default (&font_options);
cairo_font_options_set_hint_style (&font_options, CAIRO_HINT_STYLE_NONE);
cairo_font_options_set_hint_metrics (&font_options, CAIRO_HINT_METRICS_OFF);
font->type1_scaled_font = cairo_scaled_font_create (font_face,
&font_matrix,
&ctm,
&font_options);
status = font->type1_scaled_font->status;
if (unlikely (status))
goto fail;
_cairo_array_init (&font->contents, sizeof (unsigned char));
font->output = NULL;
*subset_return = font;
return CAIRO_STATUS_SUCCESS;
fail:
free (font->widths);
free (font);
return status;
}
/* Charstring commands. If the high byte is 0 the command is encoded
* with a single byte. */
#define CHARSTRING_sbw 0x0c07
#define CHARSTRING_rmoveto 0x0015
#define CHARSTRING_rlineto 0x0005
#define CHARSTRING_rcurveto 0x0008
#define CHARSTRING_closepath 0x0009
#define CHARSTRING_endchar 0x000e
/* Before calling this function, the caller must allocate sufficient
* space in data (see _cairo_array_grow_by). The maximum number of
* bytes that will be used is 2.
*/
static void
charstring_encode_command (cairo_array_t *data, int command)
{
cairo_status_t status;
int orig_size;
unsigned char buf[5];
unsigned char *p = buf;
if (command & 0xff00)
*p++ = command >> 8;
*p++ = command & 0x00ff;
/* Ensure the array doesn't grow, which allows this function to
* have no possibility of failure. */
orig_size = _cairo_array_size (data);
status = _cairo_array_append_multiple (data, buf, p - buf);
assert (status == CAIRO_STATUS_SUCCESS);
assert (_cairo_array_size (data) == orig_size);
}
/* Before calling this function, the caller must allocate sufficient
* space in data (see _cairo_array_grow_by). The maximum number of
* bytes that will be used is 5.
*/
static void
charstring_encode_integer (cairo_array_t *data,
int i,
cairo_charstring_type_t type)
{
cairo_status_t status;
int orig_size;
unsigned char buf[10];
unsigned char *p = buf;
if (i >= -107 && i <= 107) {
*p++ = i + 139;
} else if (i >= 108 && i <= 1131) {
i -= 108;
*p++ = (i >> 8)+ 247;
*p++ = i & 0xff;
} else if (i >= -1131 && i <= -108) {
i = -i - 108;
*p++ = (i >> 8)+ 251;
*p++ = i & 0xff;
} else {
if (type == CAIRO_CHARSTRING_TYPE1) {
*p++ = 0xff;
*p++ = i >> 24;
*p++ = (i >> 16) & 0xff;
*p++ = (i >> 8) & 0xff;
*p++ = i & 0xff;
} else {
*p++ = 0xff;
*p++ = (i >> 8) & 0xff;
*p++ = i & 0xff;
*p++ = 0;
*p++ = 0;
}
}
/* Ensure the array doesn't grow, which allows this function to
* have no possibility of failure. */
orig_size = _cairo_array_size (data);
status = _cairo_array_append_multiple (data, buf, p - buf);
assert (status == CAIRO_STATUS_SUCCESS);
assert (_cairo_array_size (data) == orig_size);
}
typedef struct _ps_path_info {
cairo_array_t *data;
int current_x, current_y;
cairo_charstring_type_t type;
} t1_path_info_t;
static cairo_status_t
_charstring_move_to (void *closure,
const cairo_point_t *point)
{
t1_path_info_t *path_info = (t1_path_info_t *) closure;
int dx, dy;
cairo_status_t status;
status = _cairo_array_grow_by (path_info->data, 12);
if (unlikely (status))
return status;
dx = _cairo_fixed_integer_part (point->x) - path_info->current_x;
dy = _cairo_fixed_integer_part (point->y) - path_info->current_y;
charstring_encode_integer (path_info->data, dx, path_info->type);
charstring_encode_integer (path_info->data, dy, path_info->type);
path_info->current_x += dx;
path_info->current_y += dy;
charstring_encode_command (path_info->data, CHARSTRING_rmoveto);
return CAIRO_STATUS_SUCCESS;
}
static cairo_status_t
_charstring_line_to (void *closure,
const cairo_point_t *point)
{
t1_path_info_t *path_info = (t1_path_info_t *) closure;
int dx, dy;
cairo_status_t status;
status = _cairo_array_grow_by (path_info->data, 12);
if (unlikely (status))
return status;
dx = _cairo_fixed_integer_part (point->x) - path_info->current_x;
dy = _cairo_fixed_integer_part (point->y) - path_info->current_y;
charstring_encode_integer (path_info->data, dx, path_info->type);
charstring_encode_integer (path_info->data, dy, path_info->type);
path_info->current_x += dx;
path_info->current_y += dy;
charstring_encode_command (path_info->data, CHARSTRING_rlineto);
return CAIRO_STATUS_SUCCESS;
}
static cairo_status_t
_charstring_curve_to (void *closure,
const cairo_point_t *point1,
const cairo_point_t *point2,
const cairo_point_t *point3)
{
t1_path_info_t *path_info = (t1_path_info_t *) closure;
int dx1, dy1, dx2, dy2, dx3, dy3;
cairo_status_t status;
status = _cairo_array_grow_by (path_info->data, 32);
if (unlikely (status))
return status;
dx1 = _cairo_fixed_integer_part (point1->x) - path_info->current_x;
dy1 = _cairo_fixed_integer_part (point1->y) - path_info->current_y;
dx2 = _cairo_fixed_integer_part (point2->x) - path_info->current_x - dx1;
dy2 = _cairo_fixed_integer_part (point2->y) - path_info->current_y - dy1;
dx3 = _cairo_fixed_integer_part (point3->x) - path_info->current_x - dx1 - dx2;
dy3 = _cairo_fixed_integer_part (point3->y) - path_info->current_y - dy1 - dy2;
charstring_encode_integer (path_info->data, dx1, path_info->type);
charstring_encode_integer (path_info->data, dy1, path_info->type);
charstring_encode_integer (path_info->data, dx2, path_info->type);
charstring_encode_integer (path_info->data, dy2, path_info->type);
charstring_encode_integer (path_info->data, dx3, path_info->type);
charstring_encode_integer (path_info->data, dy3, path_info->type);
path_info->current_x += dx1 + dx2 + dx3;
path_info->current_y += dy1 + dy2 + dy3;
charstring_encode_command (path_info->data, CHARSTRING_rcurveto);
return CAIRO_STATUS_SUCCESS;
}
static cairo_status_t
_charstring_close_path (void *closure)
{
cairo_status_t status;
t1_path_info_t *path_info = (t1_path_info_t *) closure;
if (path_info->type == CAIRO_CHARSTRING_TYPE2)
return CAIRO_STATUS_SUCCESS;
status = _cairo_array_grow_by (path_info->data, 2);
if (unlikely (status))
return status;
charstring_encode_command (path_info->data, CHARSTRING_closepath);
return CAIRO_STATUS_SUCCESS;
}
static void
charstring_encrypt (cairo_array_t *data)
{
unsigned char *d, *end;
uint16_t c, p, r;
r = CAIRO_TYPE1_CHARSTRING_KEY;
d = (unsigned char *) _cairo_array_index (data, 0);
end = d + _cairo_array_num_elements (data);
while (d < end) {
p = *d;
c = p ^ (r >> 8);
r = (c + r) * CAIRO_TYPE1_ENCRYPT_C1 + CAIRO_TYPE1_ENCRYPT_C2;
*d++ = c;
}
}
static cairo_int_status_t
cairo_type1_font_create_charstring (cairo_type1_font_t *font,
int subset_index,
int glyph_index,
cairo_charstring_type_t type,
cairo_array_t *data)
{
cairo_int_status_t status;
cairo_scaled_glyph_t *scaled_glyph;
t1_path_info_t path_info;
cairo_text_extents_t *metrics;
cairo_bool_t emit_path = TRUE;
/* This call may return CAIRO_INT_STATUS_UNSUPPORTED for bitmap fonts. */
status = _cairo_scaled_glyph_lookup (font->type1_scaled_font,
glyph_index,
CAIRO_SCALED_GLYPH_INFO_METRICS|
CAIRO_SCALED_GLYPH_INFO_PATH,
&scaled_glyph);
/* It is ok for the .notdef glyph to not have a path available. We
* just need the metrics to emit an empty glyph. */
if (glyph_index == 0 && status == CAIRO_INT_STATUS_UNSUPPORTED) {
emit_path = FALSE;
status = _cairo_scaled_glyph_lookup (font->type1_scaled_font,
glyph_index,
CAIRO_SCALED_GLYPH_INFO_METRICS,
&scaled_glyph);
}
if (unlikely (status))
return status;
metrics = &scaled_glyph->metrics;
if (subset_index == 0) {
font->x_min = metrics->x_bearing;
font->y_min = metrics->y_bearing;
font->x_max = metrics->x_bearing + metrics->width;
font->y_max = metrics->y_bearing + metrics->height;
} else {
if (metrics->x_bearing < font->x_min)
font->x_min = metrics->x_bearing;
if (metrics->y_bearing < font->y_min)
font->y_min = metrics->y_bearing;
if (metrics->x_bearing + metrics->width > font->x_max)
font->x_max = metrics->x_bearing + metrics->width;
if (metrics->y_bearing + metrics->height > font->y_max)
font->y_max = metrics->y_bearing + metrics->height;
}
font->widths[subset_index] = metrics->x_advance;
status = _cairo_array_grow_by (data, 30);
if (unlikely (status))
return status;
if (type == CAIRO_CHARSTRING_TYPE1) {
charstring_encode_integer (data, (int) scaled_glyph->metrics.x_bearing, type);
charstring_encode_integer (data, (int) scaled_glyph->metrics.y_bearing, type);
charstring_encode_integer (data, (int) scaled_glyph->metrics.x_advance, type);
charstring_encode_integer (data, (int) scaled_glyph->metrics.y_advance, type);
charstring_encode_command (data, CHARSTRING_sbw);
path_info.current_x = (int) scaled_glyph->metrics.x_bearing;
path_info.current_y = (int) scaled_glyph->metrics.y_bearing;
} else {
charstring_encode_integer (data, (int) scaled_glyph->metrics.x_advance, type);
path_info.current_x = 0;
path_info.current_y = 0;
}
path_info.data = data;
path_info.type = type;
if (emit_path) {
status = _cairo_path_fixed_interpret (scaled_glyph->path,
CAIRO_DIRECTION_FORWARD,
_charstring_move_to,
_charstring_line_to,
_charstring_curve_to,
_charstring_close_path,
&path_info);
if (unlikely (status))
return status;
}
status = _cairo_array_grow_by (data, 1);
if (unlikely (status))
return status;
charstring_encode_command (path_info.data, CHARSTRING_endchar);
return CAIRO_STATUS_SUCCESS;
}
static cairo_int_status_t
cairo_type1_font_write_charstrings (cairo_type1_font_t *font,
cairo_output_stream_t *encrypted_output)
{
cairo_status_t status;
unsigned char zeros[] = { 0, 0, 0, 0 };
cairo_array_t data;
unsigned int i;
int length;
_cairo_array_init (&data, sizeof (unsigned char));
status = _cairo_array_grow_by (&data, 1024);
if (unlikely (status))
goto fail;
_cairo_output_stream_printf (encrypted_output,
"2 index /CharStrings %d dict dup begin\n",
font->scaled_font_subset->num_glyphs + 1);
_cairo_scaled_font_freeze_cache (font->type1_scaled_font);
for (i = 0; i < font->scaled_font_subset->num_glyphs; i++) {
_cairo_array_truncate (&data, 0);
/* four "random" bytes required by encryption algorithm */
status = _cairo_array_append_multiple (&data, zeros, 4);
if (unlikely (status))
break;
status = cairo_type1_font_create_charstring (font, i,
font->scaled_font_subset->glyphs[i],
CAIRO_CHARSTRING_TYPE1,
&data);
if (unlikely (status))
break;
charstring_encrypt (&data);
length = _cairo_array_num_elements (&data);
if (font->scaled_font_subset->glyph_names != NULL) {
_cairo_output_stream_printf (encrypted_output, "/%s %d RD ",
font->scaled_font_subset->glyph_names[i],
length);
} else if (i == 0) {
_cairo_output_stream_printf (encrypted_output, "/.notdef %d RD ", length);
} else {
_cairo_output_stream_printf (encrypted_output, "/g%d %d RD ", i, length);
}
_cairo_output_stream_write (encrypted_output,
_cairo_array_index (&data, 0),
length);
_cairo_output_stream_printf (encrypted_output, " ND\n");
}
_cairo_scaled_font_thaw_cache (font->type1_scaled_font);
fail:
_cairo_array_fini (&data);
return status;
}
static void
cairo_type1_font_write_header (cairo_type1_font_t *font,
const char *name)
{
unsigned int i;
const char spaces[50] = " ";
_cairo_output_stream_printf (font->output,
"%%!FontType1-1.1 %s 1.0\n"
"11 dict begin\n"
"/FontName /%s def\n"
"/PaintType 0 def\n"
"/FontType 1 def\n"
"/FontMatrix [0.001 0 0 0.001 0 0] readonly def\n",
name,
name);
/* We don't know the bbox values until after the charstrings have
* been generated. Reserve some space and fill in the bbox
* later. */
/* Worst case for four signed ints with spaces between each number */
font->bbox_max_chars = 50;
_cairo_output_stream_printf (font->output, "/FontBBox {");
font->bbox_position = _cairo_output_stream_get_position (font->output);
_cairo_output_stream_write (font->output, spaces, font->bbox_max_chars);
_cairo_output_stream_printf (font->output,
"} readonly def\n"
"/Encoding 256 array\n"
"0 1 255 {1 index exch /.notdef put} for\n");
for (i = 1; i < font->scaled_font_subset->num_glyphs; i++) {
if (font->scaled_font_subset->glyph_names != NULL) {
_cairo_output_stream_printf (font->output, "dup %d /%s put\n",
i, font->scaled_font_subset->glyph_names[i]);
} else {
_cairo_output_stream_printf (font->output, "dup %d /g%d put\n", i, i);
}
}
_cairo_output_stream_printf (font->output,
"readonly def\n"
"currentdict end\n"
"currentfile eexec\n");
}
static cairo_status_t
cairo_type1_write_stream_encrypted (void *closure,
const unsigned char *data,
unsigned int length)
{
const unsigned char *in, *end;
uint16_t c, p;
static const char hex_digits[16] = "0123456789abcdef";
char digits[3];
cairo_type1_font_t *font = closure;
in = (const unsigned char *) data;
end = (const unsigned char *) data + length;
while (in < end) {
p = *in++;
c = p ^ (font->eexec_key >> 8);
font->eexec_key = (c + font->eexec_key) * CAIRO_TYPE1_ENCRYPT_C1 + CAIRO_TYPE1_ENCRYPT_C2;
if (font->hex_encode) {
digits[0] = hex_digits[c >> 4];
digits[1] = hex_digits[c & 0x0f];
digits[2] = '\n';
font->hex_column += 2;
if (font->hex_column == 78) {
_cairo_output_stream_write (font->output, digits, 3);
font->hex_column = 0;
} else {
_cairo_output_stream_write (font->output, digits, 2);
}
} else {
digits[0] = c;
_cairo_output_stream_write (font->output, digits, 1);
}
}
return CAIRO_STATUS_SUCCESS;
}
static cairo_int_status_t
cairo_type1_font_write_private_dict (cairo_type1_font_t *font,
const char *name)
{
cairo_int_status_t status;
cairo_status_t status2;
cairo_output_stream_t *encrypted_output;
font->eexec_key = CAIRO_TYPE1_PRIVATE_DICT_KEY;
font->hex_column = 0;
encrypted_output = _cairo_output_stream_create (
cairo_type1_write_stream_encrypted,
NULL,
font);
if (_cairo_output_stream_get_status (encrypted_output))
return _cairo_output_stream_destroy (encrypted_output);
/* Note: the first four spaces at the start of this private dict
* are the four "random" bytes of plaintext required by the
* encryption algorithm */
_cairo_output_stream_printf (encrypted_output,
" dup /Private 9 dict dup begin\n"
"/RD {string currentfile exch readstring pop}"
" bind executeonly def\n"
"/ND {noaccess def} executeonly def\n"
"/NP {noaccess put} executeonly def\n"
"/BlueValues [] def\n"
"/MinFeature {16 16} def\n"
"/lenIV 4 def\n"
"/password 5839 def\n");
status = cairo_type1_font_write_charstrings (font, encrypted_output);
if (unlikely (status))
goto fail;
_cairo_output_stream_printf (encrypted_output,
"end\n"
"end\n"
"readonly put\n"
"noaccess put\n"
"dup /FontName get exch definefont pop\n"
"mark currentfile closefile\n");
fail:
status2 = _cairo_output_stream_destroy (encrypted_output);
if (status == CAIRO_STATUS_SUCCESS)
status = status2;
return status;
}
static void
cairo_type1_font_write_trailer(cairo_type1_font_t *font)
{
int i;
static const char zeros[65] =
"0000000000000000000000000000000000000000000000000000000000000000\n";
for (i = 0; i < 8; i++)
_cairo_output_stream_write (font->output, zeros, sizeof zeros);
_cairo_output_stream_printf (font->output, "cleartomark\n");
}
static cairo_status_t
cairo_type1_write_stream (void *closure,
const unsigned char *data,
unsigned int length)
{
cairo_type1_font_t *font = closure;
return _cairo_array_append_multiple (&font->contents, data, length);
}
static cairo_int_status_t
cairo_type1_font_write (cairo_type1_font_t *font,
const char *name)
{
cairo_int_status_t status;
cairo_type1_font_write_header (font, name);
font->header_size = _cairo_output_stream_get_position (font->output);
status = cairo_type1_font_write_private_dict (font, name);
if (unlikely (status))
return status;
font->data_size = _cairo_output_stream_get_position (font->output) -
font->header_size;
cairo_type1_font_write_trailer (font);
font->trailer_size =
_cairo_output_stream_get_position (font->output) -
font->header_size - font->data_size;
return CAIRO_STATUS_SUCCESS;
}
static cairo_int_status_t
cairo_type1_font_generate (cairo_type1_font_t *font, const char *name)
{
cairo_int_status_t status;
status = _cairo_array_grow_by (&font->contents, 4096);
if (unlikely (status))
return status;
font->output = _cairo_output_stream_create (cairo_type1_write_stream, NULL, font);
if (_cairo_output_stream_get_status (font->output))
return _cairo_output_stream_destroy (font->output);
status = cairo_type1_font_write (font, name);
if (unlikely (status))
return status;
font->data = _cairo_array_index (&font->contents, 0);
return CAIRO_STATUS_SUCCESS;
}
static cairo_status_t
cairo_type1_font_destroy (cairo_type1_font_t *font)
{
cairo_status_t status = CAIRO_STATUS_SUCCESS;
free (font->widths);
cairo_scaled_font_destroy (font->type1_scaled_font);
_cairo_array_fini (&font->contents);
if (font->output)
status = _cairo_output_stream_destroy (font->output);
free (font);
return status;
}
static cairo_status_t
_cairo_type1_fallback_init_internal (cairo_type1_subset_t *type1_subset,
const char *name,
cairo_scaled_font_subset_t *scaled_font_subset,
cairo_bool_t hex_encode)
{
cairo_type1_font_t *font;
cairo_status_t status;
unsigned long length;
unsigned int i, len;
status = cairo_type1_font_create (scaled_font_subset, &font, hex_encode);
if (unlikely (status))
return status;
status = cairo_type1_font_generate (font, name);
if (unlikely (status))
goto fail1;
type1_subset->base_font = strdup (name);
if (unlikely (type1_subset->base_font == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto fail1;
}
type1_subset->widths = calloc (sizeof (double), font->scaled_font_subset->num_glyphs);
if (unlikely (type1_subset->widths == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto fail2;
}
for (i = 0; i < font->scaled_font_subset->num_glyphs; i++)
type1_subset->widths[i] = (double)font->widths[i]/1000;
type1_subset->x_min = (double)font->x_min/1000;
type1_subset->y_min = (double)font->y_min/1000;
type1_subset->x_max = (double)font->x_max/1000;
type1_subset->y_max = (double)font->y_max/1000;
type1_subset->ascent = (double)font->y_max/1000;
type1_subset->descent = (double)font->y_min/1000;
length = font->header_size + font->data_size +
font->trailer_size;
type1_subset->data = malloc (length);
if (unlikely (type1_subset->data == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto fail3;
}
memcpy (type1_subset->data,
_cairo_array_index (&font->contents, 0), length);
len = snprintf(type1_subset->data + font->bbox_position,
font->bbox_max_chars,
"%d %d %d %d",
(int)font->x_min,
(int)font->y_min,
(int)font->x_max,
(int)font->y_max);
type1_subset->data[font->bbox_position + len] = ' ';
type1_subset->header_length = font->header_size;
type1_subset->data_length = font->data_size;
type1_subset->trailer_length = font->trailer_size;
return cairo_type1_font_destroy (font);
fail3:
free (type1_subset->widths);
fail2:
free (type1_subset->base_font);
fail1:
/* status is already set, ignore further errors */
cairo_type1_font_destroy (font);
return status;
}
cairo_status_t
_cairo_type1_fallback_init_binary (cairo_type1_subset_t *type1_subset,
const char *name,
cairo_scaled_font_subset_t *scaled_font_subset)
{
return _cairo_type1_fallback_init_internal (type1_subset,
name,
scaled_font_subset, FALSE);
}
cairo_status_t
_cairo_type1_fallback_init_hex (cairo_type1_subset_t *type1_subset,
const char *name,
cairo_scaled_font_subset_t *scaled_font_subset)
{
return _cairo_type1_fallback_init_internal (type1_subset,
name,
scaled_font_subset, TRUE);
}
void
_cairo_type1_fallback_fini (cairo_type1_subset_t *subset)
{
free (subset->base_font);
free (subset->widths);
free (subset->data);
}
cairo_status_t
_cairo_type2_charstrings_init (cairo_type2_charstrings_t *type2_subset,
cairo_scaled_font_subset_t *scaled_font_subset)
{
cairo_type1_font_t *font;
cairo_status_t status;
unsigned int i;
cairo_array_t charstring;
status = cairo_type1_font_create (scaled_font_subset, &font, FALSE);
if (unlikely (status))
return status;
_cairo_array_init (&type2_subset->charstrings, sizeof (cairo_array_t));
type2_subset->widths = calloc (sizeof (int), font->scaled_font_subset->num_glyphs);
if (unlikely (type2_subset->widths == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto fail1;
}
_cairo_scaled_font_freeze_cache (font->type1_scaled_font);
for (i = 0; i < font->scaled_font_subset->num_glyphs; i++) {
_cairo_array_init (&charstring, sizeof (unsigned char));
status = _cairo_array_grow_by (&charstring, 32);
if (unlikely (status))
goto fail2;
status = cairo_type1_font_create_charstring (font, i,
font->scaled_font_subset->glyphs[i],
CAIRO_CHARSTRING_TYPE2,
&charstring);
if (unlikely (status))
goto fail2;
status = _cairo_array_append (&type2_subset->charstrings, &charstring);
if (unlikely (status))
goto fail2;
}
_cairo_scaled_font_thaw_cache (font->type1_scaled_font);
for (i = 0; i < font->scaled_font_subset->num_glyphs; i++)
type2_subset->widths[i] = font->widths[i];
type2_subset->x_min = (int) font->x_min;
type2_subset->y_min = (int) font->y_min;
type2_subset->x_max = (int) font->x_max;
type2_subset->y_max = (int) font->y_max;
type2_subset->ascent = (int) font->y_max;
type2_subset->descent = (int) font->y_min;
return cairo_type1_font_destroy (font);
fail2:
_cairo_scaled_font_thaw_cache (font->type1_scaled_font);
_cairo_array_fini (&charstring);
_cairo_type2_charstrings_fini (type2_subset);
fail1:
cairo_type1_font_destroy (font);
return status;
}
void
_cairo_type2_charstrings_fini (cairo_type2_charstrings_t *type2_subset)
{
unsigned int i, num_charstrings;
cairo_array_t *charstring;
num_charstrings = _cairo_array_num_elements (&type2_subset->charstrings);
for (i = 0; i < num_charstrings; i++) {
charstring = _cairo_array_index (&type2_subset->charstrings, i);
_cairo_array_fini (charstring);
}
_cairo_array_fini (&type2_subset->charstrings);
free (type2_subset->widths);
}
#endif /* CAIRO_HAS_FONT_SUBSET */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,563 @@
/* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */
/* cairo - a vector graphics library with display and print output
*
* Copyright © 2008 Adrian Johnson
*
* This library is free software; you can redistribute it and/or
* modify it either under the terms of the GNU Lesser General Public
* License version 2.1 as published by the Free Software Foundation
* (the "LGPL") or, at your option, under the terms of the Mozilla
* Public License Version 1.1 (the "MPL"). If you do not alter this
* notice, a recipient may use your version of this file under either
* the MPL or the LGPL.
*
* You should have received a copy of the LGPL along with this library
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
* You should have received a copy of the MPL along with this library
* in the file COPYING-MPL-1.1
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
* the specific language governing rights and limitations.
*
* The Original Code is the cairo graphics library.
*
* The Initial Developer of the Original Code is Adrian Johnson.
*
* Contributor(s):
* Adrian Johnson <ajohnson@redneon.com>
*/
#include "cairoint.h"
#if CAIRO_HAS_FONT_SUBSET
#include "cairo-type3-glyph-surface-private.h"
#include "cairo-output-stream-private.h"
#include "cairo-recording-surface-private.h"
#include "cairo-analysis-surface-private.h"
#include "cairo-error-private.h"
#include "cairo-surface-clipper-private.h"
static const cairo_surface_backend_t cairo_type3_glyph_surface_backend;
static cairo_status_t
_cairo_type3_glyph_surface_clipper_intersect_clip_path (cairo_surface_clipper_t *clipper,
cairo_path_fixed_t *path,
cairo_fill_rule_t fill_rule,
double tolerance,
cairo_antialias_t antialias)
{
cairo_type3_glyph_surface_t *surface = cairo_container_of (clipper,
cairo_type3_glyph_surface_t,
clipper);
if (path == NULL) {
_cairo_output_stream_printf (surface->stream, "Q q\n");
return CAIRO_STATUS_SUCCESS;
}
return _cairo_pdf_operators_clip (&surface->pdf_operators,
path,
fill_rule);
}
cairo_surface_t *
_cairo_type3_glyph_surface_create (cairo_scaled_font_t *scaled_font,
cairo_output_stream_t *stream,
cairo_type3_glyph_surface_emit_image_t emit_image,
cairo_scaled_font_subsets_t *font_subsets)
{
cairo_type3_glyph_surface_t *surface;
cairo_matrix_t invert_y_axis;
if (unlikely (stream != NULL && stream->status))
return _cairo_surface_create_in_error (stream->status);
surface = malloc (sizeof (cairo_type3_glyph_surface_t));
if (unlikely (surface == NULL))
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
_cairo_surface_init (&surface->base,
&cairo_type3_glyph_surface_backend,
NULL, /* device */
CAIRO_CONTENT_COLOR_ALPHA);
surface->scaled_font = scaled_font;
surface->stream = stream;
surface->emit_image = emit_image;
/* Setup the transform from the user-font device space to Type 3
* font space. The Type 3 font space is defined by the FontMatrix
* entry in the Type 3 dictionary. In the PDF backend this is an
* identity matrix. */
surface->cairo_to_pdf = scaled_font->scale_inverse;
cairo_matrix_init_scale (&invert_y_axis, 1, -1);
cairo_matrix_multiply (&surface->cairo_to_pdf, &surface->cairo_to_pdf, &invert_y_axis);
_cairo_pdf_operators_init (&surface->pdf_operators,
surface->stream,
&surface->cairo_to_pdf,
font_subsets);
_cairo_surface_clipper_init (&surface->clipper,
_cairo_type3_glyph_surface_clipper_intersect_clip_path);
return &surface->base;
}
static cairo_status_t
_cairo_type3_glyph_surface_emit_image (cairo_type3_glyph_surface_t *surface,
cairo_image_surface_t *image,
cairo_matrix_t *image_matrix)
{
cairo_status_t status;
/* The only image type supported by Type 3 fonts are 1-bit masks */
image = _cairo_image_surface_coerce_to_format (image, CAIRO_FORMAT_A1);
status = image->base.status;
if (unlikely (status))
return status;
_cairo_output_stream_printf (surface->stream,
"q %f %f %f %f %f %f cm\n",
image_matrix->xx,
image_matrix->xy,
image_matrix->yx,
image_matrix->yy,
image_matrix->x0,
image_matrix->y0);
status = surface->emit_image (image, surface->stream);
cairo_surface_destroy (&image->base);
_cairo_output_stream_printf (surface->stream,
"Q\n");
return status;
}
static cairo_status_t
_cairo_type3_glyph_surface_emit_image_pattern (cairo_type3_glyph_surface_t *surface,
cairo_image_surface_t *image,
const cairo_matrix_t *pattern_matrix)
{
cairo_matrix_t mat, upside_down;
cairo_status_t status;
if (image->width == 0 || image->height == 0)
return CAIRO_STATUS_SUCCESS;
mat = *pattern_matrix;
/* Get the pattern space to user space matrix */
status = cairo_matrix_invert (&mat);
/* cairo_pattern_set_matrix ensures the matrix is invertible */
assert (status == CAIRO_STATUS_SUCCESS);
/* Make this a pattern space to Type 3 font space matrix */
cairo_matrix_multiply (&mat, &mat, &surface->cairo_to_pdf);
/* PDF images are in a 1 unit by 1 unit image space. Turn the 1 by
* 1 image upside down to convert to flip the Y-axis going from
* cairo to PDF. Then scale the image up to the required size. */
cairo_matrix_scale (&mat, image->width, image->height);
cairo_matrix_init (&upside_down, 1, 0, 0, -1, 0, 1);
cairo_matrix_multiply (&mat, &upside_down, &mat);
return _cairo_type3_glyph_surface_emit_image (surface, image, &mat);
}
static cairo_status_t
_cairo_type3_glyph_surface_finish (void *abstract_surface)
{
cairo_type3_glyph_surface_t *surface = abstract_surface;
return _cairo_pdf_operators_fini (&surface->pdf_operators);
}
static cairo_int_status_t
_cairo_type3_glyph_surface_paint (void *abstract_surface,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_clip_t *clip)
{
cairo_type3_glyph_surface_t *surface = abstract_surface;
const cairo_surface_pattern_t *pattern;
cairo_image_surface_t *image;
void *image_extra;
cairo_status_t status;
if (source->type != CAIRO_PATTERN_TYPE_SURFACE)
return CAIRO_INT_STATUS_IMAGE_FALLBACK;
status = _cairo_surface_clipper_set_clip (&surface->clipper, clip);
if (unlikely (status))
return status;
pattern = (const cairo_surface_pattern_t *) source;
status = _cairo_surface_acquire_source_image (pattern->surface,
&image, &image_extra);
if (unlikely (status))
goto fail;
status = _cairo_type3_glyph_surface_emit_image_pattern (surface,
image,
&pattern->base.matrix);
fail:
_cairo_surface_release_source_image (pattern->surface, image, image_extra);
return status;
}
static cairo_int_status_t
_cairo_type3_glyph_surface_mask (void *abstract_surface,
cairo_operator_t op,
const cairo_pattern_t *source,
const cairo_pattern_t *mask,
cairo_clip_t *clip)
{
return _cairo_type3_glyph_surface_paint (abstract_surface,
op, mask,
clip);
}
static cairo_int_status_t
_cairo_type3_glyph_surface_stroke (void *abstract_surface,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_path_fixed_t *path,
const cairo_stroke_style_t *style,
const cairo_matrix_t *ctm,
const cairo_matrix_t *ctm_inverse,
double tolerance,
cairo_antialias_t antialias,
cairo_clip_t *clip)
{
cairo_type3_glyph_surface_t *surface = abstract_surface;
cairo_int_status_t status;
status = _cairo_surface_clipper_set_clip (&surface->clipper, clip);
if (unlikely (status))
return status;
return _cairo_pdf_operators_stroke (&surface->pdf_operators,
path,
style,
ctm,
ctm_inverse);
}
static cairo_int_status_t
_cairo_type3_glyph_surface_fill (void *abstract_surface,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_path_fixed_t *path,
cairo_fill_rule_t fill_rule,
double tolerance,
cairo_antialias_t antialias,
cairo_clip_t *clip)
{
cairo_type3_glyph_surface_t *surface = abstract_surface;
cairo_int_status_t status;
status = _cairo_surface_clipper_set_clip (&surface->clipper, clip);
if (unlikely (status))
return status;
return _cairo_pdf_operators_fill (&surface->pdf_operators,
path,
fill_rule);
}
static cairo_int_status_t
_cairo_type3_glyph_surface_show_glyphs (void *abstract_surface,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_glyph_t *glyphs,
int num_glyphs,
cairo_scaled_font_t *scaled_font,
cairo_clip_t *clip,
int *remaining_glyphs)
{
cairo_type3_glyph_surface_t *surface = abstract_surface;
cairo_int_status_t status;
cairo_scaled_font_t *font;
cairo_matrix_t new_ctm, invert_y_axis;
status = _cairo_surface_clipper_set_clip (&surface->clipper, clip);
if (unlikely (status))
return status;
cairo_matrix_init_scale (&invert_y_axis, 1, -1);
cairo_matrix_multiply (&new_ctm, &invert_y_axis, &scaled_font->ctm);
cairo_matrix_multiply (&new_ctm, &surface->cairo_to_pdf, &new_ctm);
font = cairo_scaled_font_create (scaled_font->font_face,
&scaled_font->font_matrix,
&new_ctm,
&scaled_font->options);
if (unlikely (font->status))
return font->status;
status = _cairo_pdf_operators_show_text_glyphs (&surface->pdf_operators,
NULL, 0,
glyphs, num_glyphs,
NULL, 0,
FALSE,
font);
cairo_scaled_font_destroy (font);
return status;
}
static const cairo_surface_backend_t cairo_type3_glyph_surface_backend = {
CAIRO_INTERNAL_SURFACE_TYPE_TYPE3_GLYPH,
NULL, /* _cairo_type3_glyph_surface_create_similar */
_cairo_type3_glyph_surface_finish,
NULL, /* acquire_source_image */
NULL, /* release_source_image */
NULL, /* acquire_dest_image */
NULL, /* release_dest_image */
NULL, /* clone_similar */
NULL, /* composite */
NULL, /* fill_rectangles */
NULL, /* composite_trapezoids */
NULL, /* create_span_renderer */
NULL, /* check_span_renderer */
NULL, /* cairo_type3_glyph_surface_copy_page */
NULL, /* _cairo_type3_glyph_surface_show_page */
NULL, /* _cairo_type3_glyph_surface_get_extents */
NULL, /* old_show_glyphs */
NULL, /* _cairo_type3_glyph_surface_get_font_options */
NULL, /* flush */
NULL, /* mark_dirty_rectangle */
NULL, /* scaled_font_fini */
NULL, /* scaled_glyph_fini */
_cairo_type3_glyph_surface_paint,
_cairo_type3_glyph_surface_mask,
_cairo_type3_glyph_surface_stroke,
_cairo_type3_glyph_surface_fill,
_cairo_type3_glyph_surface_show_glyphs,
NULL, /* snapshot */
};
static void
_cairo_type3_glyph_surface_set_stream (cairo_type3_glyph_surface_t *surface,
cairo_output_stream_t *stream)
{
surface->stream = stream;
_cairo_pdf_operators_set_stream (&surface->pdf_operators, stream);
}
static cairo_status_t
_cairo_type3_glyph_surface_emit_fallback_image (cairo_type3_glyph_surface_t *surface,
unsigned long glyph_index)
{
cairo_scaled_glyph_t *scaled_glyph;
cairo_status_t status;
cairo_image_surface_t *image;
cairo_matrix_t mat;
double x, y;
status = _cairo_scaled_glyph_lookup (surface->scaled_font,
glyph_index,
CAIRO_SCALED_GLYPH_INFO_METRICS |
CAIRO_SCALED_GLYPH_INFO_SURFACE,
&scaled_glyph);
if (unlikely (status))
return status;
image = scaled_glyph->surface;
if (image->width == 0 || image->height == 0)
return CAIRO_STATUS_SUCCESS;
x = _cairo_fixed_to_double (scaled_glyph->bbox.p1.x);
y = _cairo_fixed_to_double (scaled_glyph->bbox.p2.y);
mat.xx = image->width;
mat.xy = 0;
mat.yx = 0;
mat.yy = image->height;
mat.x0 = x;
mat.y0 = y;
cairo_matrix_multiply (&mat, &mat, &surface->scaled_font->scale_inverse);
mat.y0 *= -1;
return _cairo_type3_glyph_surface_emit_image (surface, image, &mat);
}
void
_cairo_type3_glyph_surface_set_font_subsets_callback (void *abstract_surface,
cairo_pdf_operators_use_font_subset_t use_font_subset,
void *closure)
{
cairo_type3_glyph_surface_t *surface = abstract_surface;
if (unlikely (surface->base.status))
return;
_cairo_pdf_operators_set_font_subsets_callback (&surface->pdf_operators,
use_font_subset,
closure);
}
cairo_status_t
_cairo_type3_glyph_surface_analyze_glyph (void *abstract_surface,
unsigned long glyph_index)
{
cairo_type3_glyph_surface_t *surface = abstract_surface;
cairo_scaled_glyph_t *scaled_glyph;
cairo_status_t status, status2;
cairo_output_stream_t *null_stream;
if (unlikely (surface->base.status))
return surface->base.status;
null_stream = _cairo_null_stream_create ();
if (unlikely (null_stream->status))
return null_stream->status;
_cairo_type3_glyph_surface_set_stream (surface, null_stream);
_cairo_scaled_font_freeze_cache (surface->scaled_font);
status = _cairo_scaled_glyph_lookup (surface->scaled_font,
glyph_index,
CAIRO_SCALED_GLYPH_INFO_RECORDING_SURFACE,
&scaled_glyph);
if (_cairo_status_is_error (status))
goto cleanup;
if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
status = CAIRO_STATUS_SUCCESS;
goto cleanup;
}
status = _cairo_recording_surface_replay (scaled_glyph->recording_surface,
&surface->base);
if (unlikely (status))
goto cleanup;
status = _cairo_pdf_operators_flush (&surface->pdf_operators);
if (status == CAIRO_INT_STATUS_IMAGE_FALLBACK)
status = CAIRO_STATUS_SUCCESS;
cleanup:
_cairo_scaled_font_thaw_cache (surface->scaled_font);
status2 = _cairo_output_stream_destroy (null_stream);
if (status == CAIRO_STATUS_SUCCESS)
status = status2;
return status;
}
cairo_status_t
_cairo_type3_glyph_surface_emit_glyph (void *abstract_surface,
cairo_output_stream_t *stream,
unsigned long glyph_index,
cairo_box_t *bbox,
double *width)
{
cairo_type3_glyph_surface_t *surface = abstract_surface;
cairo_scaled_glyph_t *scaled_glyph;
cairo_status_t status, status2;
double x_advance, y_advance;
cairo_matrix_t font_matrix_inverse;
if (unlikely (surface->base.status))
return surface->base.status;
_cairo_type3_glyph_surface_set_stream (surface, stream);
_cairo_scaled_font_freeze_cache (surface->scaled_font);
status = _cairo_scaled_glyph_lookup (surface->scaled_font,
glyph_index,
CAIRO_SCALED_GLYPH_INFO_METRICS |
CAIRO_SCALED_GLYPH_INFO_RECORDING_SURFACE,
&scaled_glyph);
if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
status = _cairo_scaled_glyph_lookup (surface->scaled_font,
glyph_index,
CAIRO_SCALED_GLYPH_INFO_METRICS,
&scaled_glyph);
if (status == CAIRO_STATUS_SUCCESS)
status = CAIRO_INT_STATUS_IMAGE_FALLBACK;
}
if (_cairo_status_is_error (status)) {
_cairo_scaled_font_thaw_cache (surface->scaled_font);
return status;
}
x_advance = scaled_glyph->metrics.x_advance;
y_advance = scaled_glyph->metrics.y_advance;
font_matrix_inverse = surface->scaled_font->font_matrix;
status2 = cairo_matrix_invert (&font_matrix_inverse);
/* The invertability of font_matrix is tested in
* pdf_operators_show_glyphs before any glyphs are mapped to the
* subset. */
assert (status2 == CAIRO_STATUS_SUCCESS);
cairo_matrix_transform_distance (&font_matrix_inverse, &x_advance, &y_advance);
*width = x_advance;
*bbox = scaled_glyph->bbox;
_cairo_matrix_transform_bounding_box_fixed (&surface->scaled_font->scale_inverse,
bbox, NULL);
_cairo_output_stream_printf (surface->stream,
"%f 0 %f %f %f %f d1\n",
x_advance,
_cairo_fixed_to_double (bbox->p1.x),
- _cairo_fixed_to_double (bbox->p2.y),
_cairo_fixed_to_double (bbox->p2.x),
- _cairo_fixed_to_double (bbox->p1.y));
if (status == CAIRO_STATUS_SUCCESS) {
cairo_output_stream_t *mem_stream;
mem_stream = _cairo_memory_stream_create ();
status = mem_stream->status;
if (unlikely (status))
goto FAIL;
_cairo_type3_glyph_surface_set_stream (surface, mem_stream);
_cairo_output_stream_printf (surface->stream, "q\n");
status = _cairo_recording_surface_replay (scaled_glyph->recording_surface,
&surface->base);
status2 = _cairo_pdf_operators_flush (&surface->pdf_operators);
if (status == CAIRO_STATUS_SUCCESS)
status = status2;
_cairo_output_stream_printf (surface->stream, "Q\n");
_cairo_type3_glyph_surface_set_stream (surface, stream);
if (status == CAIRO_STATUS_SUCCESS)
_cairo_memory_stream_copy (mem_stream, stream);
status2 = _cairo_output_stream_destroy (mem_stream);
if (status == CAIRO_STATUS_SUCCESS)
status = status2;
}
if (status == CAIRO_INT_STATUS_IMAGE_FALLBACK)
status = _cairo_type3_glyph_surface_emit_fallback_image (surface, glyph_index);
FAIL:
_cairo_scaled_font_thaw_cache (surface->scaled_font);
return status;
}
#endif /* CAIRO_HAS_FONT_SUBSET */

View File

@ -0,0 +1,111 @@
This copy of the libpng notices is provided for your convenience. In case of
any discrepancy between this copy and the notices in the file png.h that is
included in the libpng distribution, the latter shall prevail.
COPYRIGHT NOTICE, DISCLAIMER, and LICENSE:
If you modify libpng you may insert additional notices immediately following
this sentence.
This code is released under the libpng license.
libpng versions 1.2.6, August 15, 2004, through 1.5.1, February 3, 2011, are
Copyright (c) 2004, 2006-2011 Glenn Randers-Pehrson, and are
distributed according to the same disclaimer and license as libpng-1.2.5
with the following individual added to the list of Contributing Authors
Cosmin Truta
libpng versions 1.0.7, July 1, 2000, through 1.2.5 - October 3, 2002, are
Copyright (c) 2000-2002 Glenn Randers-Pehrson, and are
distributed according to the same disclaimer and license as libpng-1.0.6
with the following individuals added to the list of Contributing Authors
Simon-Pierre Cadieux
Eric S. Raymond
Gilles Vollant
and with the following additions to the disclaimer:
There is no warranty against interference with your enjoyment of the
library or against infringement. There is no warranty that our
efforts or the library will fulfill any of your particular purposes
or needs. This library is provided with all faults, and the entire
risk of satisfactory quality, performance, accuracy, and effort is with
the user.
libpng versions 0.97, January 1998, through 1.0.6, March 20, 2000, are
Copyright (c) 1998, 1999 Glenn Randers-Pehrson, and are
distributed according to the same disclaimer and license as libpng-0.96,
with the following individuals added to the list of Contributing Authors:
Tom Lane
Glenn Randers-Pehrson
Willem van Schaik
libpng versions 0.89, June 1996, through 0.96, May 1997, are
Copyright (c) 1996, 1997 Andreas Dilger
Distributed according to the same disclaimer and license as libpng-0.88,
with the following individuals added to the list of Contributing Authors:
John Bowler
Kevin Bracey
Sam Bushell
Magnus Holmgren
Greg Roelofs
Tom Tanner
libpng versions 0.5, May 1995, through 0.88, January 1996, are
Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
For the purposes of this copyright and license, "Contributing Authors"
is defined as the following set of individuals:
Andreas Dilger
Dave Martindale
Guy Eric Schalnat
Paul Schmidt
Tim Wegner
The PNG Reference Library is supplied "AS IS". The Contributing Authors
and Group 42, Inc. disclaim all warranties, expressed or implied,
including, without limitation, the warranties of merchantability and of
fitness for any purpose. The Contributing Authors and Group 42, Inc.
assume no liability for direct, indirect, incidental, special, exemplary,
or consequential damages, which may result from the use of the PNG
Reference Library, even if advised of the possibility of such damage.
Permission is hereby granted to use, copy, modify, and distribute this
source code, or portions hereof, for any purpose, without fee, subject
to the following restrictions:
1. The origin of this source code must not be misrepresented.
2. Altered versions must be plainly marked as such and must not
be misrepresented as being the original source.
3. This Copyright notice may not be removed or altered from any
source or altered source distribution.
The Contributing Authors and Group 42, Inc. specifically permit, without
fee, and encourage the use of this source code as a component to
supporting the PNG file format in commercial products. If you use this
source code in a product, acknowledgment is not required but would be
appreciated.
A "png_get_copyright" function is available, for convenient use in "about"
boxes and the like:
printf("%s",png_get_copyright(NULL));
Also, the PNG logo (in PNG format, of course) is supplied in the
files "pngbar.png" and "pngbar.jpg (88x31) and "pngnow.png" (98x31).
Libpng is OSI Certified Open Source Software. OSI Certified Open Source is a
certification mark of the Open Source Initiative.
Glenn Randers-Pehrson
glennrp at users.sourceforge.net
February 3, 2011

View File

@ -0,0 +1,44 @@
LIBRARY= libpng
CC=gcc
CPP=gcc -E
AR= ar rc
CFLAGS = -c -O2 -fomit-frame-pointer
DEFS = -DHAVE_CONFIG_H
LIBPNG_DEFINES = -DPNG_CONFIGURE_LIBPNG
DEFINES= $(DEFS) $(LIBPNG_DEFINES)
INCLUDES= -I../newlib/include -I../zlib
SOURCES = png.c pngerror.c pngget.c pngmem.c pngpread.c \
pngread.c pngrio.c pngrtran.c pngrutil.c \
pngset.c pngtrans.c pngwio.c pngwrite.c \
pngwtran.c pngwutil.c png.h pngconf.h \
pngdebug.h pnginfo.h pngpriv.h pngstruct.h
OBJECTS = $(patsubst %.c, %.o, $(SOURCES))
# targets
all:$(LIBRARY).a
$(LIBRARY).a: $(OBJECTS) Makefile
ar cvrs $(LIBRARY).a $(OBJECTS)
%.o : %.c Makefile
$(CC) $(CFLAGS) $(DEFINES) $(INCLUDES) -o $@ $<

View File

@ -0,0 +1,87 @@
/* config.h. Generated from config.h.in by configure. */
/* config.h.in. Generated from configure.ac by autoheader. */
/* Define to 1 if you have the <dlfcn.h> header file. */
#define HAVE_DLFCN_H 1
/* Define to 1 if you have the <inttypes.h> header file. */
#define HAVE_INTTYPES_H 1
/* Define to 1 if you have the `m' library (-lm). */
#define HAVE_LIBM 1
/* Define to 1 if you have the `z' library (-lz). */
#define HAVE_LIBZ 1
/* Define to 1 if you have the <malloc.h> header file. */
#define HAVE_MALLOC_H 1
/* Define to 1 if you have the <memory.h> header file. */
#define HAVE_MEMORY_H 1
/* Define to 1 if you have the `memset' function. */
#define HAVE_MEMSET 1
/* Define to 1 if you have the `pow' function. */
/* #undef HAVE_POW */
/* Define to 1 if you have the <stdint.h> header file. */
#define HAVE_STDINT_H 1
/* Define to 1 if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H 1
/* Define to 1 if you have the <strings.h> header file. */
#define HAVE_STRINGS_H 1
/* Define to 1 if you have the <string.h> header file. */
#define HAVE_STRING_H 1
/* Define to 1 if you have the <sys/stat.h> header file. */
#define HAVE_SYS_STAT_H 1
/* Define to 1 if you have the <sys/types.h> header file. */
#define HAVE_SYS_TYPES_H 1
/* Define to 1 if you have the <unistd.h> header file. */
#define HAVE_UNISTD_H 1
/* Define to the sub-directory in which libtool stores uninstalled libraries.
*/
#define LT_OBJDIR ".libs/"
/* Name of package */
#define PACKAGE "libpng"
/* Define to the address where bug reports for this package should be sent. */
#define PACKAGE_BUGREPORT "png-mng-implement@lists.sourceforge.net"
/* Define to the full name of this package. */
#define PACKAGE_NAME "libpng"
/* Define to the full name and version of this package. */
#define PACKAGE_STRING "libpng 1.5.1"
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "libpng"
/* Define to the home page for this package. */
#define PACKAGE_URL ""
/* Define to the version of this package. */
#define PACKAGE_VERSION "1.5.1"
/* Define to 1 if you have the ANSI C header files. */
#define STDC_HEADERS 1
/* Define to 1 if your <sys/time.h> declares `struct tm'. */
/* #undef TM_IN_SYS_TIME */
/* Version number of package */
#define VERSION "1.5.1"
/* Define to empty if `const' does not conform to ANSI C. */
/* #undef const */
/* Define to `unsigned int' if <sys/types.h> does not define. */
/* #undef size_t */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,632 @@
/* pngconf.h - machine configurable file for libpng
*
* libpng version 1.5.1 - February 3, 2011
*
* Copyright (c) 1998-2011 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
*
* This code is released under the libpng license.
* For conditions of distribution and use, see the disclaimer
* and license in png.h
*
*/
/* Any machine specific code is near the front of this file, so if you
* are configuring libpng for a machine, you may want to read the section
* starting here down to where it starts to typedef png_color, png_text,
* and png_info.
*/
#ifndef PNGCONF_H
#define PNGCONF_H
/* PNG_NO_LIMITS_H may be used to turn off the use of the standard C
* definition file for machine specific limits, this may impact the
* correctness of the definitons below (see uses of INT_MAX).
*/
#ifndef PNG_NO_LIMITS_H
# include <limits.h>
#endif
/* For the memory copy APIs (i.e. the standard definitions of these),
* because this file defines png_memcpy and so on the base APIs must
* be defined here.
*/
#ifdef BSD
# include <strings.h>
#else
# include <string.h>
#endif
/* For png_FILE_p - this provides the standard definition of a
* FILE
*/
#ifdef PNG_STDIO_SUPPORTED
# include <stdio.h>
#endif
/* This controls optimization of the reading of 16 and 32 bit values
* from PNG files. It can be set on a per-app-file basis - it
* just changes whether a macro is used to the function is called.
* The library builder sets the default, if read functions are not
* built into the library the macro implementation is forced on.
*/
#ifndef PNG_READ_INT_FUNCTIONS_SUPPORTED
# define PNG_USE_READ_MACROS
#endif
#if !defined(PNG_NO_USE_READ_MACROS) && !defined(PNG_USE_READ_MACROS)
# if PNG_DEFAULT_READ_MACROS
# define PNG_USE_READ_MACROS
# endif
#endif
/* COMPILER SPECIFIC OPTIONS.
*
* These options are provided so that a variety of difficult compilers
* can be used. Some are fixed at build time (e.g. PNG_API_RULE
* below) but still have compiler specific implementations, others
* may be changed on a per-file basis when compiling against libpng.
*/
/* The PNGARG macro protects us against machines that don't have function
* prototypes (ie K&R style headers). If your compiler does not handle
* function prototypes, define this macro and use the included ansi2knr.
* I've always been able to use _NO_PROTO as the indicator, but you may
* need to drag the empty declaration out in front of here, or change the
* ifdef to suit your own needs.
*/
#ifndef PNGARG
# ifdef OF /* zlib prototype munger */
# define PNGARG(arglist) OF(arglist)
# else
# ifdef _NO_PROTO
# define PNGARG(arglist) ()
# else
# define PNGARG(arglist) arglist
# endif /* _NO_PROTO */
# endif /* OF */
#endif /* PNGARG */
/* Function calling conventions.
* =============================
* Normally it is not necessary to specify to the compiler how to call
* a function - it just does it - however on x86 systems derived from
* Microsoft and Borland C compilers ('IBM PC', 'DOS', 'Windows' systems
* and some others) there are multiple ways to call a function and the
* default can be changed on the compiler command line. For this reason
* libpng specifies the calling convention of every exported function and
* every function called via a user supplied function pointer. This is
* done in this file by defining the following macros:
*
* PNGAPI Calling convention for exported functions.
* PNGCBAPI Calling convention for user provided (callback) functions.
* PNGCAPI Calling convention used by the ANSI-C library (required
* for longjmp callbacks and sometimes used internally to
* specify the calling convention for zlib).
*
* These macros should never be overridden. If it is necessary to
* change calling convention in a private build this can be done
* by setting PNG_API_RULE (which defaults to 0) to one of the values
* below to select the correct 'API' variants.
*
* PNG_API_RULE=0 Use PNGCAPI - the 'C' calling convention - throughout.
* This is correct in every known environment.
* PNG_API_RULE=1 Use the operating system convention for PNGAPI and
* the 'C' calling convention (from PNGCAPI) for
* callbacks (PNGCBAPI). This is no longer required
* in any known environment - if it has to be used
* please post an explanation of the problem to the
* libpng mailing list.
*
* These cases only differ if the operating system does not use the C
* calling convention, at present this just means the above cases
* (x86 DOS/Windows sytems) and, even then, this does not apply to
* Cygwin running on those systems.
*
* Note that the value must be defined in pnglibconf.h so that what
* the application uses to call the library matches the conventions
* set when building the library.
*/
/* Symbol export
* =============
* When building a shared library it is almost always necessary to tell
* the compiler which symbols to export. The png.h macro 'PNG_EXPORT'
* is used to mark the symbols. On some systems these symbols can be
* extracted at link time and need no special processing by the compiler,
* on other systems the symbols are flagged by the compiler and just
* the declaration requires a special tag applied (unfortunately) in a
* compiler dependent way. Some systems can do either.
*
* A small number of older systems also require a symbol from a DLL to
* be flagged to the program that calls it. This is a problem because
* we do not know in the header file included by application code that
* the symbol will come from a shared library, as opposed to a statically
* linked one. For this reason the application must tell us by setting
* the magic flag PNG_USE_DLL to turn on the special processing before
* it includes png.h.
*
* Four additional macros are used to make this happen:
*
* PNG_IMPEXP The magic (if any) to cause a symbol to be exported from
* the build or imported if PNG_USE_DLL is set - compiler
* and system specific.
*
* PNG_EXPORT_TYPE(type) A macro that pre or appends PNG_IMPEXP to
* 'type', compiler specific.
*
* PNG_DLL_EXPORT Set to the magic to use during a libpng build to
* make a symbol exported from the DLL.
*
* PNG_DLL_IMPORT Set to the magic to force the libpng symbols to come
* from a DLL - used to define PNG_IMPEXP when
* PNG_USE_DLL is set.
*/
/* System specific discovery.
* ==========================
* This code is used at build time to find PNG_IMPEXP, the API settings
* and PNG_EXPORT_TYPE(), it may also set a macro to indicate the DLL
* import processing is possible. On Windows/x86 systems it also sets
* compiler-specific macros to the values required to change the calling
* conventions of the various functions.
*/
#if ( defined(_Windows) || defined(_WINDOWS) || defined(WIN32) ||\
defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) ) &&\
( defined(_X86_) || defined(_X64_) || defined(_M_IX86) ||\
defined(_M_X64) || defined(_M_IA64) )
/* Windows system (DOS doesn't support DLLs) running on x86/x64. Includes
* builds under Cygwin or MinGW. Also includes Watcom builds but these need
* special treatment because they are not compatible with GCC or Visual C
* because of different calling conventions.
*/
# if PNG_API_RULE == 2
/* If this line results in an error, either because __watcall is not
* understood or because of a redefine just below you cannot use *this*
* build of the library with the compiler you are using. *This* build was
* build using Watcom and applications must also be built using Watcom!
*/
# define PNGCAPI __watcall
# endif
# if defined(__GNUC__) || (defined (_MSC_VER) && (_MSC_VER >= 800))
# define PNGCAPI __cdecl
# if PNG_API_RULE == 1
# define PNGAPI __stdcall
# endif
# else
/* An older compiler, or one not detected (erroneously) above,
* if necessary override on the command line to get the correct
* variants for the compiler.
*/
# ifndef PNGCAPI
# define PNGCAPI _cdecl
# endif
# if PNG_API_RULE == 1 && !defined(PNGAPI)
# define PNGAPI _stdcall
# endif
# endif /* compiler/api */
/* NOTE: PNGCBAPI always defaults to PNGCAPI. */
# if defined(PNGAPI) && !defined(PNG_USER_PRIVATEBUILD)
ERROR: PNG_USER_PRIVATEBUILD must be defined if PNGAPI is changed
# endif
# if (defined(_MSC_VER) && _MSC_VER < 800) ||\
(defined(__BORLANDC__) && __BORLANDC__ < 0x500)
/* older Borland and MSC
* compilers used '__export' and required this to be after
* the type.
*/
# ifndef PNG_EXPORT_TYPE
# define PNG_EXPORT_TYPE(type) type PNG_IMPEXP
# endif
# define PNG_DLL_EXPORT __export
# else /* newer compiler */
# define PNG_DLL_EXPORT __declspec(dllexport)
# ifndef PNG_DLL_IMPORT
# define PNG_DLL_IMPORT __declspec(dllimport)
# endif
# endif /* compiler */
#else /* !Windows/x86 */
# if (defined(__IBMC__) || defined(__IBMCPP__)) && defined(__OS2__)
# define PNGAPI _System
# else /* !Windows/x86 && !OS/2 */
/* Use the defaults, or define PNG*API on the command line (but
* this will have to be done for every compile!)
*/
# endif /* other system, !OS/2 */
#endif /* !Windows/x86 */
/* Now do all the defaulting . */
#ifndef PNGCAPI
# define PNGCAPI
#endif
#ifndef PNGCBAPI
# define PNGCBAPI PNGCAPI
#endif
#ifndef PNGAPI
# define PNGAPI PNGCAPI
#endif
/* The default for PNG_IMPEXP depends on whether the library is
* being built or used.
*/
#ifndef PNG_IMPEXP
# ifdef PNGLIB_BUILD
/* Building the library */
# if (defined(DLL_EXPORT)/*from libtool*/ ||\
defined(_WINDLL) || defined(_DLL) || defined(__DLL__) ||\
defined(_USRDLL) ||\
defined(PNG_BUILD_DLL)) && defined(PNG_DLL_EXPORT)
/* Building a DLL. */
# define PNG_IMPEXP PNG_DLL_EXPORT
# endif /* DLL */
# else
/* Using the library */
# if defined(PNG_USE_DLL) && defined(PNG_DLL_IMPORT)
/* This forces use of a DLL, disallowing static linking */
# define PNG_IMPEXP PNG_DLL_IMPORT
# endif
# endif
# ifndef PNG_IMPEXP
# define PNG_IMPEXP
# endif
#endif
/* THe following complexity is concerned with getting the 'attributes' of the
* declared function in the correct place. This potentially requires a separate
* PNG_EXPORT function for every compiler.
*/
#ifndef PNG_FUNCTION
# ifdef __GNUC__
# define PNG_FUNCTION(type, name, args, attributes)\
attributes type name args
# else /* !GNUC */
# ifdef _MSC_VER
# define PNG_FUNCTION(type, name, args, attributes)\
attributes type name args
# else /* !MSC */
# define PNG_FUNCTION(type, name, args, attributes)\
type name args
# endif
# endif
#endif
#ifndef PNG_EXPORT_TYPE
# define PNG_EXPORT_TYPE(type) PNG_IMPEXP type
#endif
/* The ordinal value is only relevant when preprocessing png.h for symbol
* table entries, so we discard it here. See the .dfn files in the
* scripts directory.
*/
#ifndef PNG_EXPORTA
# define PNG_EXPORTA(ordinal, type, name, args, attributes)\
extern PNG_FUNCTION(PNG_EXPORT_TYPE(type),(PNGAPI name),PNGARG(args),\
attributes)
#endif
#define PNG_EXPORT(ordinal, type, name, args)\
PNG_EXPORTA(ordinal, type, name, args, )
/* Use PNG_REMOVED to comment out a removed interface. */
#ifndef PNG_REMOVED
# define PNG_REMOVED(ordinal, type, name, args, attributes)
#endif
#ifndef PNG_CALLBACK
# define PNG_CALLBACK(type, name, args, attributes)\
type (PNGCBAPI name) PNGARG(args) attributes
#endif
/* Support for compiler specific function attributes. These are used
* so that where compiler support is available incorrect use of API
* functions in png.h will generate compiler warnings.
*
* Added at libpng-1.2.41.
*/
#ifndef PNG_NO_PEDANTIC_WARNINGS
# ifndef PNG_PEDANTIC_WARNINGS_SUPPORTED
# define PNG_PEDANTIC_WARNINGS_SUPPORTED
# endif
#endif
#ifdef PNG_PEDANTIC_WARNINGS_SUPPORTED
/* Support for compiler specific function attributes. These are used
* so that where compiler support is available incorrect use of API
* functions in png.h will generate compiler warnings. Added at libpng
* version 1.2.41.
*/
# ifdef __GNUC__
# ifndef PNG_USE_RESULT
# define PNG_USE_RESULT __attribute__((__warn_unused_result__))
# endif
# ifndef PNG_NORETURN
# define PNG_NORETURN __attribute__((__noreturn__))
# endif
# ifndef PNG_PTR_NORETURN
# define PNG_PTR_NORETURN __attribute__((__noreturn__))
# endif
# ifndef PNG_ALLOCATED
# define PNG_ALLOCATED __attribute__((__malloc__))
# endif
/* This specifically protects structure members that should only be
* accessed from within the library, therefore should be empty during
* a library build.
*/
# ifndef PNGLIB_BUILD
# ifndef PNG_DEPRECATED
# define PNG_DEPRECATED __attribute__((__deprecated__))
# endif
# ifndef PNG_DEPSTRUCT
# define PNG_DEPSTRUCT __attribute__((__deprecated__))
# endif
# ifndef PNG_PRIVATE
# if 0 /* Doesn't work so we use deprecated instead*/
# define PNG_PRIVATE \
__attribute__((warning("This function is not exported by libpng.")))
# else
# define PNG_PRIVATE \
__attribute__((__deprecated__))
# endif
# endif /* PNG_PRIVATE */
# endif /* PNGLIB_BUILD */
# endif /* __GNUC__ */
# ifdef _MSC_VER /* may need to check value */
# ifndef PNG_USE_RESULT
# define PNG_USE_RESULT /*not supported*/
# endif
# ifndef PNG_NORETURN
# define PNG_NORETURN __declspec(noreturn)
# endif
# ifndef PNG_PTR_NORETURN
# define PNG_PTR_NORETURN /*not supported*/
# endif
# ifndef PNG_ALLOCATED
# define PNG_ALLOCATED __declspec(restrict)
# endif
/* This specifically protects structure members that should only be
* accessed from within the library, therefore should be empty during
* a library build.
*/
# ifndef PNGLIB_BUILD
# ifndef PNG_DEPRECATED
# define PNG_DEPRECATED __declspec(deprecated)
# endif
# ifndef PNG_DEPSTRUCT
# define PNG_DEPSTRUCT __declspec(deprecated)
# endif
# ifndef PNG_PRIVATE
# define PNG_PRIVATE __declspec(deprecated)
# endif /* PNG_PRIVATE */
# endif /* PNGLIB_BUILD */
# endif /* __GNUC__ */
#endif /* PNG_PEDANTIC_WARNINGS */
#ifndef PNG_DEPRECATED
# define PNG_DEPRECATED /* Use of this function is deprecated */
#endif
#ifndef PNG_USE_RESULT
# define PNG_USE_RESULT /* The result of this function must be checked */
#endif
#ifndef PNG_NORETURN
# define PNG_NORETURN /* This function does not return */
#endif
#ifndef PNG_ALLOCATED
# define PNG_ALLOCATED /* The result of the function is new memory */
#endif
#ifndef PNG_DEPSTRUCT
# define PNG_DEPSTRUCT /* Access to this struct member is deprecated */
#endif
#ifndef PNG_PRIVATE
# define PNG_PRIVATE /* This is a private libpng function */
#endif
#ifndef PNG_FP_EXPORT /* A floating point API. */
# ifdef PNG_FLOATING_POINT_SUPPORTED
# define PNG_FP_EXPORT(ordinal, type, name, args)\
PNG_EXPORT(ordinal, type, name, args)
# else /* No floating point APIs */
# define PNG_FP_EXPORT(ordinal, type, name, args)
# endif
#endif
#ifndef PNG_FIXED_EXPORT /* A fixed point API. */
# ifdef PNG_FIXED_POINT_SUPPORTED
# define PNG_FIXED_EXPORT(ordinal, type, name, args)\
PNG_EXPORT(ordinal, type, name, args)
# else /* No fixed point APIs */
# define PNG_FIXED_EXPORT(ordinal, type, name, args)
# endif
#endif
/* The following uses const char * instead of char * for error
* and warning message functions, so some compilers won't complain.
* If you do not want to use const, define PNG_NO_CONST here.
*
* This should not change how the APIs are called, so it can be done
* on a per-file basis in the application.
*/
#ifndef PNG_CONST
# ifndef PNG_NO_CONST
# define PNG_CONST const
# else
# define PNG_CONST
# endif
#endif
/* Some typedefs to get us started. These should be safe on most of the
* common platforms. The typedefs should be at least as large as the
* numbers suggest (a png_uint_32 must be at least 32 bits long), but they
* don't have to be exactly that size. Some compilers dislike passing
* unsigned shorts as function parameters, so you may be better off using
* unsigned int for png_uint_16.
*/
#if defined(INT_MAX) && (INT_MAX > 0x7ffffffeL)
typedef unsigned int png_uint_32;
typedef int png_int_32;
#else
typedef unsigned long png_uint_32;
typedef long png_int_32;
#endif
typedef unsigned short png_uint_16;
typedef short png_int_16;
typedef unsigned char png_byte;
#ifdef PNG_NO_SIZE_T
typedef unsigned int png_size_t;
#else
typedef size_t png_size_t;
#endif
#define png_sizeof(x) (sizeof (x))
/* The following is needed for medium model support. It cannot be in the
* pngpriv.h header. Needs modification for other compilers besides
* MSC. Model independent support declares all arrays and pointers to be
* large using the far keyword. The zlib version used must also support
* model independent data. As of version zlib 1.0.4, the necessary changes
* have been made in zlib. The USE_FAR_KEYWORD define triggers other
* changes that are needed. (Tim Wegner)
*/
/* Separate compiler dependencies (problem here is that zlib.h always
* defines FAR. (SJT)
*/
#ifdef __BORLANDC__
# if defined(__LARGE__) || defined(__HUGE__) || defined(__COMPACT__)
# define LDATA 1
# else
# define LDATA 0
# endif
/* GRR: why is Cygwin in here? Cygwin is not Borland C... */
# if !defined(__WIN32__) && !defined(__FLAT__) && !defined(__CYGWIN__)
# define PNG_MAX_MALLOC_64K /* only used in build */
# if (LDATA != 1)
# ifndef FAR
# define FAR __far
# endif
# define USE_FAR_KEYWORD
# endif /* LDATA != 1 */
/* Possibly useful for moving data out of default segment.
* Uncomment it if you want. Could also define FARDATA as
* const if your compiler supports it. (SJT)
# define FARDATA FAR
*/
# endif /* __WIN32__, __FLAT__, __CYGWIN__ */
#endif /* __BORLANDC__ */
/* Suggest testing for specific compiler first before testing for
* FAR. The Watcom compiler defines both __MEDIUM__ and M_I86MM,
* making reliance oncertain keywords suspect. (SJT)
*/
/* MSC Medium model */
#ifdef FAR
# ifdef M_I86MM
# define USE_FAR_KEYWORD
# define FARDATA FAR
# include <dos.h>
# endif
#endif
/* SJT: default case */
#ifndef FAR
# define FAR
#endif
/* At this point FAR is always defined */
#ifndef FARDATA
# define FARDATA
#endif
/* Typedef for floating-point numbers that are converted
* to fixed-point with a multiple of 100,000, e.g., gamma
*/
typedef png_int_32 png_fixed_point;
/* Add typedefs for pointers */
typedef void FAR * png_voidp;
typedef PNG_CONST void FAR * png_const_voidp;
typedef png_byte FAR * png_bytep;
typedef PNG_CONST png_byte FAR * png_const_bytep;
typedef png_uint_32 FAR * png_uint_32p;
typedef PNG_CONST png_uint_32 FAR * png_const_uint_32p;
typedef png_int_32 FAR * png_int_32p;
typedef PNG_CONST png_int_32 FAR * png_const_int_32p;
typedef png_uint_16 FAR * png_uint_16p;
typedef PNG_CONST png_uint_16 FAR * png_const_uint_16p;
typedef png_int_16 FAR * png_int_16p;
typedef PNG_CONST png_int_16 FAR * png_const_int_16p;
typedef char FAR * png_charp;
typedef PNG_CONST char FAR * png_const_charp;
typedef png_fixed_point FAR * png_fixed_point_p;
typedef PNG_CONST png_fixed_point FAR * png_const_fixed_point_p;
typedef png_size_t FAR * png_size_tp;
typedef PNG_CONST png_size_t FAR * png_const_size_tp;
#ifdef PNG_STDIO_SUPPORTED
typedef FILE * png_FILE_p;
#endif
#ifdef PNG_FLOATING_POINT_SUPPORTED
typedef double FAR * png_doublep;
typedef PNG_CONST double FAR * png_const_doublep;
#endif
/* Pointers to pointers; i.e. arrays */
typedef png_byte FAR * FAR * png_bytepp;
typedef png_uint_32 FAR * FAR * png_uint_32pp;
typedef png_int_32 FAR * FAR * png_int_32pp;
typedef png_uint_16 FAR * FAR * png_uint_16pp;
typedef png_int_16 FAR * FAR * png_int_16pp;
typedef PNG_CONST char FAR * FAR * png_const_charpp;
typedef char FAR * FAR * png_charpp;
typedef png_fixed_point FAR * FAR * png_fixed_point_pp;
#ifdef PNG_FLOATING_POINT_SUPPORTED
typedef double FAR * FAR * png_doublepp;
#endif
/* Pointers to pointers to pointers; i.e., pointer to array */
typedef char FAR * FAR * FAR * png_charppp;
/* png_alloc_size_t is guaranteed to be no smaller than png_size_t,
* and no smaller than png_uint_32. Casts from png_size_t or png_uint_32
* to png_alloc_size_t are not necessary; in fact, it is recommended
* not to use them at all so that the compiler can complain when something
* turns out to be problematic.
* Casts in the other direction (from png_alloc_size_t to png_size_t or
* png_uint_32) should be explicitly applied; however, we do not expect
* to encounter practical situations that require such conversions.
*/
#if defined(__TURBOC__) && !defined(__FLAT__)
typedef unsigned long png_alloc_size_t;
#else
# if defined(_MSC_VER) && defined(MAXSEG_64K)
typedef unsigned long png_alloc_size_t;
# else
/* This is an attempt to detect an old Windows system where (int) is
* actually 16 bits, in that case png_malloc must have an argument with a
* bigger size to accomodate the requirements of the library.
*/
# if (defined(_Windows) || defined(_WINDOWS) || defined(_WINDOWS_)) && \
(!defined(INT_MAX) || INT_MAX <= 0x7ffffffeL)
typedef DWORD png_alloc_size_t;
# else
typedef png_size_t png_alloc_size_t;
# endif
# endif
#endif
#endif /* PNGCONF_H */

View File

@ -0,0 +1,157 @@
/* pngdebug.h - Debugging macros for libpng, also used in pngtest.c
*
* Copyright (c) 1998-2011 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
*
* Last changed in libpng 1.5.0 [January 6, 2011]
*
* This code is released under the libpng license.
* For conditions of distribution and use, see the disclaimer
* and license in png.h
*/
/* Define PNG_DEBUG at compile time for debugging information. Higher
* numbers for PNG_DEBUG mean more debugging information. This has
* only been added since version 0.95 so it is not implemented throughout
* libpng yet, but more support will be added as needed.
*
* png_debug[1-2]?(level, message ,arg{0-2})
* Expands to a statement (either a simple expression or a compound
* do..while(0) statement) that outputs a message with parameter
* substitution if PNG_DEBUG is defined to 2 or more. If PNG_DEBUG
* is undefined, 0 or 1 every png_debug expands to a simple expression
* (actually ((void)0)).
*
* level: level of detail of message, starting at 0. A level 'n'
* message is preceded by 'n' tab characters (not implemented
* on Microsoft compilers unless PNG_DEBUG_FILE is also
* defined, to allow debug DLL compilation with no standard IO).
* message: a printf(3) style text string. A trailing '\n' is added
* to the message.
* arg: 0 to 2 arguments for printf(3) style substitution in message.
*/
#ifndef PNGDEBUG_H
#define PNGDEBUG_H
/* These settings control the formatting of messages in png.c and pngerror.c */
/* Moved to pngdebug.h at 1.5.0 */
# ifndef PNG_LITERAL_SHARP
# define PNG_LITERAL_SHARP 0x23
# endif
# ifndef PNG_LITERAL_LEFT_SQUARE_BRACKET
# define PNG_LITERAL_LEFT_SQUARE_BRACKET 0x5b
# endif
# ifndef PNG_LITERAL_RIGHT_SQUARE_BRACKET
# define PNG_LITERAL_RIGHT_SQUARE_BRACKET 0x5d
# endif
# ifndef PNG_STRING_NEWLINE
# define PNG_STRING_NEWLINE "\n"
# endif
#ifdef PNG_DEBUG
# if (PNG_DEBUG > 0)
# if !defined(PNG_DEBUG_FILE) && defined(_MSC_VER)
# include <crtdbg.h>
# if (PNG_DEBUG > 1)
# ifndef _DEBUG
# define _DEBUG
# endif
# ifndef png_debug
# define png_debug(l,m) _RPT0(_CRT_WARN,m PNG_STRING_NEWLINE)
# endif
# ifndef png_debug1
# define png_debug1(l,m,p1) _RPT1(_CRT_WARN,m PNG_STRING_NEWLINE,p1)
# endif
# ifndef png_debug2
# define png_debug2(l,m,p1,p2) \
_RPT2(_CRT_WARN,m PNG_STRING_NEWLINE,p1,p2)
# endif
# endif
# else /* PNG_DEBUG_FILE || !_MSC_VER */
# ifndef PNG_STDIO_SUPPORTED
# include <stdio.h> /* not included yet */
# endif
# ifndef PNG_DEBUG_FILE
# define PNG_DEBUG_FILE stderr
# endif /* PNG_DEBUG_FILE */
# if (PNG_DEBUG > 1)
/* Note: ["%s"m PNG_STRING_NEWLINE] probably does not work on
* non-ISO compilers
*/
# ifdef __STDC__
# ifndef png_debug
# define png_debug(l,m) \
do { \
int num_tabs=l; \
fprintf(PNG_DEBUG_FILE,"%s"m PNG_STRING_NEWLINE,(num_tabs==1 ? "\t" : \
(num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":"")))); \
} while (0)
# endif
# ifndef png_debug1
# define png_debug1(l,m,p1) \
do { \
int num_tabs=l; \
fprintf(PNG_DEBUG_FILE,"%s"m PNG_STRING_NEWLINE,(num_tabs==1 ? "\t" : \
(num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))),p1); \
} while (0)
# endif
# ifndef png_debug2
# define png_debug2(l,m,p1,p2) \
do { \
int num_tabs=l; \
fprintf(PNG_DEBUG_FILE,"%s"m PNG_STRING_NEWLINE,(num_tabs==1 ? "\t" : \
(num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))),p1,p2); \
} while (0)
# endif
# else /* __STDC __ */
# ifndef png_debug
# define png_debug(l,m) \
do { \
int num_tabs=l; \
char format[256]; \
snprintf(format,256,"%s%s%s",(num_tabs==1 ? "\t" : \
(num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))), \
m,PNG_STRING_NEWLINE); \
fprintf(PNG_DEBUG_FILE,format); \
} while (0)
# endif
# ifndef png_debug1
# define png_debug1(l,m,p1) \
do { \
int num_tabs=l; \
char format[256]; \
snprintf(format,256,"%s%s%s",(num_tabs==1 ? "\t" : \
(num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))), \
m,PNG_STRING_NEWLINE); \
fprintf(PNG_DEBUG_FILE,format,p1); \
} while (0)
# endif
# ifndef png_debug2
# define png_debug2(l,m,p1,p2) \
do { \
int num_tabs=l; \
char format[256]; \
snprintf(format,256,"%s%s%s",(num_tabs==1 ? "\t" : \
(num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))), \
m,PNG_STRING_NEWLINE); \
fprintf(PNG_DEBUG_FILE,format,p1,p2); \
} while (0)
# endif
# endif /* __STDC __ */
# endif /* (PNG_DEBUG > 1) */
# endif /* _MSC_VER */
# endif /* (PNG_DEBUG > 0) */
#endif /* PNG_DEBUG */
#ifndef png_debug
# define png_debug(l, m) ((void)0)
#endif
#ifndef png_debug1
# define png_debug1(l, m, p1) ((void)0)
#endif
#ifndef png_debug2
# define png_debug2(l, m, p1, p2) ((void)0)
#endif
#endif /* PNGDEBUG_H */

View File

@ -0,0 +1,447 @@
/* pngerror.c - stub functions for i/o and memory allocation
*
* Last changed in libpng 1.5.1 [February 3, 2011]
* Copyright (c) 1998-2011 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
*
* This code is released under the libpng license.
* For conditions of distribution and use, see the disclaimer
* and license in png.h
*
* This file provides a location for all error handling. Users who
* need special error handling are expected to write replacement functions
* and use png_set_error_fn() to use those functions. See the instructions
* at each function.
*/
#include "pngpriv.h"
#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
static PNG_FUNCTION(void, png_default_error,PNGARG((png_structp png_ptr,
png_const_charp error_message)),PNG_NORETURN);
#ifdef PNG_WARNINGS_SUPPORTED
static void /* PRIVATE */
png_default_warning PNGARG((png_structp png_ptr,
png_const_charp warning_message));
#endif /* PNG_WARNINGS_SUPPORTED */
/* This function is called whenever there is a fatal error. This function
* should not be changed. If there is a need to handle errors differently,
* you should supply a replacement error function and use png_set_error_fn()
* to replace the error function at run-time.
*/
#ifdef PNG_ERROR_TEXT_SUPPORTED
PNG_FUNCTION(void,PNGAPI
png_error,(png_structp png_ptr, png_const_charp error_message),PNG_NORETURN)
{
#ifdef PNG_ERROR_NUMBERS_SUPPORTED
char msg[16];
if (png_ptr != NULL)
{
if (png_ptr->flags&
(PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT))
{
if (*error_message == PNG_LITERAL_SHARP)
{
/* Strip "#nnnn " from beginning of error message. */
int offset;
for (offset = 1; offset<15; offset++)
if (error_message[offset] == ' ')
break;
if (png_ptr->flags&PNG_FLAG_STRIP_ERROR_TEXT)
{
int i;
for (i = 0; i < offset - 1; i++)
msg[i] = error_message[i + 1];
msg[i - 1] = '\0';
error_message = msg;
}
else
error_message += offset;
}
else
{
if (png_ptr->flags&PNG_FLAG_STRIP_ERROR_TEXT)
{
msg[0] = '0';
msg[1] = '\0';
error_message = msg;
}
}
}
}
#endif
if (png_ptr != NULL && png_ptr->error_fn != NULL)
(*(png_ptr->error_fn))(png_ptr, error_message);
/* If the custom handler doesn't exist, or if it returns,
use the default handler, which will not return. */
png_default_error(png_ptr, error_message);
}
#else
PNG_FUNCTION(void,PNGAPI
png_err,(png_structp png_ptr),PNG_NORETURN)
{
if (png_ptr != NULL && png_ptr->error_fn != NULL)
(*(png_ptr->error_fn))(png_ptr, '\0');
/* If the custom handler doesn't exist, or if it returns,
use the default handler, which will not return. */
png_default_error(png_ptr, '\0');
}
#endif /* PNG_ERROR_TEXT_SUPPORTED */
#ifdef PNG_WARNINGS_SUPPORTED
/* This function is called whenever there is a non-fatal error. This function
* should not be changed. If there is a need to handle warnings differently,
* you should supply a replacement warning function and use
* png_set_error_fn() to replace the warning function at run-time.
*/
void PNGAPI
png_warning(png_structp png_ptr, png_const_charp warning_message)
{
int offset = 0;
if (png_ptr != NULL)
{
#ifdef PNG_ERROR_NUMBERS_SUPPORTED
if (png_ptr->flags&
(PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT))
#endif
{
if (*warning_message == PNG_LITERAL_SHARP)
{
for (offset = 1; offset < 15; offset++)
if (warning_message[offset] == ' ')
break;
}
}
}
if (png_ptr != NULL && png_ptr->warning_fn != NULL)
(*(png_ptr->warning_fn))(png_ptr, warning_message + offset);
else
png_default_warning(png_ptr, warning_message + offset);
}
#endif /* PNG_WARNINGS_SUPPORTED */
#ifdef PNG_BENIGN_ERRORS_SUPPORTED
void PNGAPI
png_benign_error(png_structp png_ptr, png_const_charp error_message)
{
if (png_ptr->flags & PNG_FLAG_BENIGN_ERRORS_WARN)
png_warning(png_ptr, error_message);
else
png_error(png_ptr, error_message);
}
#endif
/* These utilities are used internally to build an error message that relates
* to the current chunk. The chunk name comes from png_ptr->chunk_name,
* this is used to prefix the message. The message is limited in length
* to 63 bytes, the name characters are output as hex digits wrapped in []
* if the character is invalid.
*/
#define isnonalpha(c) ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97))
static PNG_CONST char png_digit[16] = {
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'A', 'B', 'C', 'D', 'E', 'F'
};
#define PNG_MAX_ERROR_TEXT 64
#if defined(PNG_WARNINGS_SUPPORTED) || defined(PNG_ERROR_TEXT_SUPPORTED)
static void /* PRIVATE */
png_format_buffer(png_structp png_ptr, png_charp buffer, png_const_charp
error_message)
{
int iout = 0, iin = 0;
while (iin < 4)
{
int c = png_ptr->chunk_name[iin++];
if (isnonalpha(c))
{
buffer[iout++] = PNG_LITERAL_LEFT_SQUARE_BRACKET;
buffer[iout++] = png_digit[(c & 0xf0) >> 4];
buffer[iout++] = png_digit[c & 0x0f];
buffer[iout++] = PNG_LITERAL_RIGHT_SQUARE_BRACKET;
}
else
{
buffer[iout++] = (png_byte)c;
}
}
if (error_message == NULL)
buffer[iout] = '\0';
else
{
buffer[iout++] = ':';
buffer[iout++] = ' ';
png_memcpy(buffer + iout, error_message, PNG_MAX_ERROR_TEXT);
buffer[iout + PNG_MAX_ERROR_TEXT - 1] = '\0';
}
}
#endif /* PNG_WARNINGS_SUPPORTED || PNG_ERROR_TEXT_SUPPORTED */
#if defined(PNG_READ_SUPPORTED) && defined(PNG_ERROR_TEXT_SUPPORTED)
PNG_FUNCTION(void,PNGAPI
png_chunk_error,(png_structp png_ptr, png_const_charp error_message),
PNG_NORETURN)
{
char msg[18+PNG_MAX_ERROR_TEXT];
if (png_ptr == NULL)
png_error(png_ptr, error_message);
else
{
png_format_buffer(png_ptr, msg, error_message);
png_error(png_ptr, msg);
}
}
#endif /* PNG_READ_SUPPORTED && PNG_ERROR_TEXT_SUPPORTED */
#ifdef PNG_WARNINGS_SUPPORTED
void PNGAPI
png_chunk_warning(png_structp png_ptr, png_const_charp warning_message)
{
char msg[18+PNG_MAX_ERROR_TEXT];
if (png_ptr == NULL)
png_warning(png_ptr, warning_message);
else
{
png_format_buffer(png_ptr, msg, warning_message);
png_warning(png_ptr, msg);
}
}
#endif /* PNG_WARNINGS_SUPPORTED */
#ifdef PNG_READ_SUPPORTED
#ifdef PNG_BENIGN_ERRORS_SUPPORTED
void PNGAPI
png_chunk_benign_error(png_structp png_ptr, png_const_charp error_message)
{
if (png_ptr->flags & PNG_FLAG_BENIGN_ERRORS_WARN)
png_chunk_warning(png_ptr, error_message);
else
png_chunk_error(png_ptr, error_message);
}
#endif
#endif /* PNG_READ_SUPPORTED */
#ifdef PNG_ERROR_TEXT_SUPPORTED
#ifdef PNG_FLOATING_POINT_SUPPORTED
PNG_FUNCTION(void,
png_fixed_error,(png_structp png_ptr, png_const_charp name),PNG_NORETURN)
{
# define fixed_message "fixed point overflow in "
# define fixed_message_ln ((sizeof fixed_message)-1)
int iin;
char msg[fixed_message_ln+PNG_MAX_ERROR_TEXT];
png_memcpy(msg, fixed_message, fixed_message_ln);
iin = 0;
if (name != NULL) while (iin < (PNG_MAX_ERROR_TEXT-1) && name[iin] != 0)
{
msg[fixed_message_ln + iin] = name[iin];
++iin;
}
msg[fixed_message_ln + iin] = 0;
png_error(png_ptr, msg);
}
#endif
#endif
#ifdef PNG_SETJMP_SUPPORTED
/* This API only exists if ANSI-C style error handling is used,
* otherwise it is necessary for png_default_error to be overridden.
*/
jmp_buf* PNGAPI
png_set_longjmp_fn(png_structp png_ptr, png_longjmp_ptr longjmp_fn,
size_t jmp_buf_size)
{
if (png_ptr == NULL || jmp_buf_size != png_sizeof(jmp_buf))
return NULL;
png_ptr->longjmp_fn = longjmp_fn;
return &png_ptr->png_jmpbuf;
}
#endif
/* This is the default error handling function. Note that replacements for
* this function MUST NOT RETURN, or the program will likely crash. This
* function is used by default, or if the program supplies NULL for the
* error function pointer in png_set_error_fn().
*/
static PNG_FUNCTION(void /* PRIVATE */,
png_default_error,(png_structp png_ptr, png_const_charp error_message),
PNG_NORETURN)
{
#ifdef PNG_CONSOLE_IO_SUPPORTED
#ifdef PNG_ERROR_NUMBERS_SUPPORTED
if (*error_message == PNG_LITERAL_SHARP)
{
/* Strip "#nnnn " from beginning of error message. */
int offset;
char error_number[16];
for (offset = 0; offset<15; offset++)
{
error_number[offset] = error_message[offset + 1];
if (error_message[offset] == ' ')
break;
}
if ((offset > 1) && (offset < 15))
{
error_number[offset - 1] = '\0';
fprintf(stderr, "libpng error no. %s: %s",
error_number, error_message + offset + 1);
fprintf(stderr, PNG_STRING_NEWLINE);
}
else
{
fprintf(stderr, "libpng error: %s, offset=%d",
error_message, offset);
fprintf(stderr, PNG_STRING_NEWLINE);
}
}
else
#endif
{
fprintf(stderr, "libpng error: %s", error_message);
fprintf(stderr, PNG_STRING_NEWLINE);
}
#endif
#ifndef PNG_CONSOLE_IO_SUPPORTED
PNG_UNUSED(error_message) /* Make compiler happy */
#endif
png_longjmp(png_ptr, 1);
}
PNG_FUNCTION(void,PNGAPI
png_longjmp,(png_structp png_ptr, int val),PNG_NORETURN)
{
#ifdef PNG_SETJMP_SUPPORTED
if (png_ptr && png_ptr->longjmp_fn)
{
# ifdef USE_FAR_KEYWORD
{
jmp_buf png_jmpbuf;
png_memcpy(png_jmpbuf, png_ptr->png_jmpbuf, png_sizeof(jmp_buf));
png_ptr->longjmp_fn(png_jmpbuf, val);
}
# else
png_ptr->longjmp_fn(png_ptr->png_jmpbuf, val);
# endif
}
#endif
/* Here if not setjmp support or if png_ptr is null. */
PNG_ABORT();
}
#ifdef PNG_WARNINGS_SUPPORTED
/* This function is called when there is a warning, but the library thinks
* it can continue anyway. Replacement functions don't have to do anything
* here if you don't want them to. In the default configuration, png_ptr is
* not used, but it is passed in case it may be useful.
*/
static void /* PRIVATE */
png_default_warning(png_structp png_ptr, png_const_charp warning_message)
{
#ifdef PNG_CONSOLE_IO_SUPPORTED
# ifdef PNG_ERROR_NUMBERS_SUPPORTED
if (*warning_message == PNG_LITERAL_SHARP)
{
int offset;
char warning_number[16];
for (offset = 0; offset < 15; offset++)
{
warning_number[offset] = warning_message[offset + 1];
if (warning_message[offset] == ' ')
break;
}
if ((offset > 1) && (offset < 15))
{
warning_number[offset + 1] = '\0';
fprintf(stderr, "libpng warning no. %s: %s",
warning_number, warning_message + offset);
fprintf(stderr, PNG_STRING_NEWLINE);
}
else
{
fprintf(stderr, "libpng warning: %s",
warning_message);
fprintf(stderr, PNG_STRING_NEWLINE);
}
}
else
# endif
{
fprintf(stderr, "libpng warning: %s", warning_message);
fprintf(stderr, PNG_STRING_NEWLINE);
}
#else
PNG_UNUSED(warning_message) /* Make compiler happy */
#endif
PNG_UNUSED(png_ptr) /* Make compiler happy */
}
#endif /* PNG_WARNINGS_SUPPORTED */
/* This function is called when the application wants to use another method
* of handling errors and warnings. Note that the error function MUST NOT
* return to the calling routine or serious problems will occur. The return
* method used in the default routine calls longjmp(png_ptr->png_jmpbuf, 1)
*/
void PNGAPI
png_set_error_fn(png_structp png_ptr, png_voidp error_ptr,
png_error_ptr error_fn, png_error_ptr warning_fn)
{
if (png_ptr == NULL)
return;
png_ptr->error_ptr = error_ptr;
png_ptr->error_fn = error_fn;
png_ptr->warning_fn = warning_fn;
}
/* This function returns a pointer to the error_ptr associated with the user
* functions. The application should free any memory associated with this
* pointer before png_write_destroy and png_read_destroy are called.
*/
png_voidp PNGAPI
png_get_error_ptr(png_const_structp png_ptr)
{
if (png_ptr == NULL)
return NULL;
return ((png_voidp)png_ptr->error_ptr);
}
#ifdef PNG_ERROR_NUMBERS_SUPPORTED
void PNGAPI
png_set_strip_error_numbers(png_structp png_ptr, png_uint_32 strip_mode)
{
if (png_ptr != NULL)
{
png_ptr->flags &=
((~(PNG_FLAG_STRIP_ERROR_NUMBERS |
PNG_FLAG_STRIP_ERROR_TEXT))&strip_mode);
}
}
#endif
#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,270 @@
/* pnginfo.h - header file for PNG reference library
*
* Copyright (c) 1998-2011 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
*
* Last changed in libpng 1.5.0 [January 6, 2011]
*
* This code is released under the libpng license.
* For conditions of distribution and use, see the disclaimer
* and license in png.h
*/
/* png_info is a structure that holds the information in a PNG file so
* that the application can find out the characteristics of the image.
* If you are reading the file, this structure will tell you what is
* in the PNG file. If you are writing the file, fill in the information
* you want to put into the PNG file, using png_set_*() functions, then
* call png_write_info().
*
* The names chosen should be very close to the PNG specification, so
* consult that document for information about the meaning of each field.
*
* With libpng < 0.95, it was only possible to directly set and read the
* the values in the png_info_struct, which meant that the contents and
* order of the values had to remain fixed. With libpng 0.95 and later,
* however, there are now functions that abstract the contents of
* png_info_struct from the application, so this makes it easier to use
* libpng with dynamic libraries, and even makes it possible to use
* libraries that don't have all of the libpng ancillary chunk-handing
* functionality. In libpng-1.5.0 this was moved into a separate private
* file that is not visible to applications.
*
* The following members may have allocated storage attached that should be
* cleaned up before the structure is discarded: palette, trans, text,
* pcal_purpose, pcal_units, pcal_params, hist, iccp_name, iccp_profile,
* splt_palettes, scal_unit, row_pointers, and unknowns. By default, these
* are automatically freed when the info structure is deallocated, if they were
* allocated internally by libpng. This behavior can be changed by means
* of the png_data_freer() function.
*
* More allocation details: all the chunk-reading functions that
* change these members go through the corresponding png_set_*
* functions. A function to clear these members is available: see
* png_free_data(). The png_set_* functions do not depend on being
* able to point info structure members to any of the storage they are
* passed (they make their own copies), EXCEPT that the png_set_text
* functions use the same storage passed to them in the text_ptr or
* itxt_ptr structure argument, and the png_set_rows and png_set_unknowns
* functions do not make their own copies.
*/
#ifndef PNGINFO_H
#define PNGINFO_H
struct png_info_def
{
/* the following are necessary for every PNG file */
png_uint_32 width; /* width of image in pixels (from IHDR) */
png_uint_32 height; /* height of image in pixels (from IHDR) */
png_uint_32 valid; /* valid chunk data (see PNG_INFO_ below) */
png_size_t rowbytes; /* bytes needed to hold an untransformed row */
png_colorp palette; /* array of color values (valid & PNG_INFO_PLTE) */
png_uint_16 num_palette; /* number of color entries in "palette" (PLTE) */
png_uint_16 num_trans; /* number of transparent palette color (tRNS) */
png_byte bit_depth; /* 1, 2, 4, 8, or 16 bits/channel (from IHDR) */
png_byte color_type; /* see PNG_COLOR_TYPE_ below (from IHDR) */
/* The following three should have been named *_method not *_type */
png_byte compression_type; /* must be PNG_COMPRESSION_TYPE_BASE (IHDR) */
png_byte filter_type; /* must be PNG_FILTER_TYPE_BASE (from IHDR) */
png_byte interlace_type; /* One of PNG_INTERLACE_NONE, PNG_INTERLACE_ADAM7 */
/* The following is informational only on read, and not used on writes. */
png_byte channels; /* number of data channels per pixel (1, 2, 3, 4) */
png_byte pixel_depth; /* number of bits per pixel */
png_byte spare_byte; /* to align the data, and for future use */
png_byte signature[8]; /* magic bytes read by libpng from start of file */
/* The rest of the data is optional. If you are reading, check the
* valid field to see if the information in these are valid. If you
* are writing, set the valid field to those chunks you want written,
* and initialize the appropriate fields below.
*/
#if defined(PNG_gAMA_SUPPORTED)
/* The gAMA chunk describes the gamma characteristics of the system
* on which the image was created, normally in the range [1.0, 2.5].
* Data is valid if (valid & PNG_INFO_gAMA) is non-zero.
*/
png_fixed_point gamma;
#endif
#ifdef PNG_sRGB_SUPPORTED
/* GR-P, 0.96a */
/* Data valid if (valid & PNG_INFO_sRGB) non-zero. */
png_byte srgb_intent; /* sRGB rendering intent [0, 1, 2, or 3] */
#endif
#ifdef PNG_TEXT_SUPPORTED
/* The tEXt, and zTXt chunks contain human-readable textual data in
* uncompressed, compressed, and optionally compressed forms, respectively.
* The data in "text" is an array of pointers to uncompressed,
* null-terminated C strings. Each chunk has a keyword that describes the
* textual data contained in that chunk. Keywords are not required to be
* unique, and the text string may be empty. Any number of text chunks may
* be in an image.
*/
int num_text; /* number of comments read or comments to write */
int max_text; /* current size of text array */
png_textp text; /* array of comments read or comments to write */
#endif /* PNG_TEXT_SUPPORTED */
#ifdef PNG_tIME_SUPPORTED
/* The tIME chunk holds the last time the displayed image data was
* modified. See the png_time struct for the contents of this struct.
*/
png_time mod_time;
#endif
#ifdef PNG_sBIT_SUPPORTED
/* The sBIT chunk specifies the number of significant high-order bits
* in the pixel data. Values are in the range [1, bit_depth], and are
* only specified for the channels in the pixel data. The contents of
* the low-order bits is not specified. Data is valid if
* (valid & PNG_INFO_sBIT) is non-zero.
*/
png_color_8 sig_bit; /* significant bits in color channels */
#endif
#if defined(PNG_tRNS_SUPPORTED) || defined(PNG_READ_EXPAND_SUPPORTED) || \
defined(PNG_READ_BACKGROUND_SUPPORTED)
/* The tRNS chunk supplies transparency data for paletted images and
* other image types that don't need a full alpha channel. There are
* "num_trans" transparency values for a paletted image, stored in the
* same order as the palette colors, starting from index 0. Values
* for the data are in the range [0, 255], ranging from fully transparent
* to fully opaque, respectively. For non-paletted images, there is a
* single color specified that should be treated as fully transparent.
* Data is valid if (valid & PNG_INFO_tRNS) is non-zero.
*/
png_bytep trans; /* alpha values for paletted image */
png_bytep trans_alpha; /* alpha values for paletted image */
png_color_16 trans_color; /* transparent color for non-palette image */
#endif
#if defined(PNG_bKGD_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
/* The bKGD chunk gives the suggested image background color if the
* display program does not have its own background color and the image
* is needs to composited onto a background before display. The colors
* in "background" are normally in the same color space/depth as the
* pixel data. Data is valid if (valid & PNG_INFO_bKGD) is non-zero.
*/
png_color_16 background;
#endif
#ifdef PNG_oFFs_SUPPORTED
/* The oFFs chunk gives the offset in "offset_unit_type" units rightwards
* and downwards from the top-left corner of the display, page, or other
* application-specific co-ordinate space. See the PNG_OFFSET_ defines
* below for the unit types. Valid if (valid & PNG_INFO_oFFs) non-zero.
*/
png_int_32 x_offset; /* x offset on page */
png_int_32 y_offset; /* y offset on page */
png_byte offset_unit_type; /* offset units type */
#endif
#ifdef PNG_pHYs_SUPPORTED
/* The pHYs chunk gives the physical pixel density of the image for
* display or printing in "phys_unit_type" units (see PNG_RESOLUTION_
* defines below). Data is valid if (valid & PNG_INFO_pHYs) is non-zero.
*/
png_uint_32 x_pixels_per_unit; /* horizontal pixel density */
png_uint_32 y_pixels_per_unit; /* vertical pixel density */
png_byte phys_unit_type; /* resolution type (see PNG_RESOLUTION_ below) */
#endif
#ifdef PNG_hIST_SUPPORTED
/* The hIST chunk contains the relative frequency or importance of the
* various palette entries, so that a viewer can intelligently select a
* reduced-color palette, if required. Data is an array of "num_palette"
* values in the range [0,65535]. Data valid if (valid & PNG_INFO_hIST)
* is non-zero.
*/
png_uint_16p hist;
#endif
#ifdef PNG_cHRM_SUPPORTED
/* The cHRM chunk describes the CIE color characteristics of the monitor
* on which the PNG was created. This data allows the viewer to do gamut
* mapping of the input image to ensure that the viewer sees the same
* colors in the image as the creator. Values are in the range
* [0.0, 0.8]. Data valid if (valid & PNG_INFO_cHRM) non-zero.
*/
png_fixed_point x_white;
png_fixed_point y_white;
png_fixed_point x_red;
png_fixed_point y_red;
png_fixed_point x_green;
png_fixed_point y_green;
png_fixed_point x_blue;
png_fixed_point y_blue;
#endif
#ifdef PNG_pCAL_SUPPORTED
/* The pCAL chunk describes a transformation between the stored pixel
* values and original physical data values used to create the image.
* The integer range [0, 2^bit_depth - 1] maps to the floating-point
* range given by [pcal_X0, pcal_X1], and are further transformed by a
* (possibly non-linear) transformation function given by "pcal_type"
* and "pcal_params" into "pcal_units". Please see the PNG_EQUATION_
* defines below, and the PNG-Group's PNG extensions document for a
* complete description of the transformations and how they should be
* implemented, and for a description of the ASCII parameter strings.
* Data values are valid if (valid & PNG_INFO_pCAL) non-zero.
*/
png_charp pcal_purpose; /* pCAL chunk description string */
png_int_32 pcal_X0; /* minimum value */
png_int_32 pcal_X1; /* maximum value */
png_charp pcal_units; /* Latin-1 string giving physical units */
png_charpp pcal_params; /* ASCII strings containing parameter values */
png_byte pcal_type; /* equation type (see PNG_EQUATION_ below) */
png_byte pcal_nparams; /* number of parameters given in pcal_params */
#endif
/* New members added in libpng-1.0.6 */
png_uint_32 free_me; /* flags items libpng is responsible for freeing */
#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED) || \
defined(PNG_HANDLE_AS_UNKNOWN_SUPPORTED)
/* Storage for unknown chunks that the library doesn't recognize. */
png_unknown_chunkp unknown_chunks;
int unknown_chunks_num;
#endif
#ifdef PNG_iCCP_SUPPORTED
/* iCCP chunk data. */
png_charp iccp_name; /* profile name */
png_bytep iccp_profile; /* International Color Consortium profile data */
png_uint_32 iccp_proflen; /* ICC profile data length */
png_byte iccp_compression; /* Always zero */
#endif
#ifdef PNG_sPLT_SUPPORTED
/* Data on sPLT chunks (there may be more than one). */
png_sPLT_tp splt_palettes;
png_uint_32 splt_palettes_num;
#endif
#ifdef PNG_sCAL_SUPPORTED
/* The sCAL chunk describes the actual physical dimensions of the
* subject matter of the graphic. The chunk contains a unit specification
* a byte value, and two ASCII strings representing floating-point
* values. The values are width and height corresponsing to one pixel
* in the image. Data values are valid if (valid & PNG_INFO_sCAL) is
* non-zero.
*/
png_byte scal_unit; /* unit of physical scale */
png_charp scal_s_width; /* string containing height */
png_charp scal_s_height; /* string containing width */
#endif
#ifdef PNG_INFO_IMAGE_SUPPORTED
/* Memory has been allocated if (valid & PNG_ALLOCATED_INFO_ROWS)
non-zero */
/* Data valid if (valid & PNG_INFO_IDAT) non-zero */
png_bytepp row_pointers; /* the image bits */
#endif
};
#endif /* PNGINFO_H */

View File

@ -0,0 +1,173 @@
/* pnglibconf.h - library build configuration */
/* libpng version 1.5.0 - January 6, 2011 */
/* Copyright (c) 1998-2011 Glenn Randers-Pehrson */
/* This code is released under the libpng license. */
/* For conditions of distribution and use, see the disclaimer */
/* and license in png.h */
/* pnglibconf.h */
/* Machine generated file: DO NOT EDIT */
/* Derived from: scripts/pnglibconf.dfa */
#ifndef PNGLCONF_H
#define PNGLCONF_H
/* settings */
#define PNG_MAX_GAMMA_8 11
#define PNG_CALLOC_SUPPORTED
#define PNG_QUANTIZE_RED_BITS 5
#define PNG_USER_WIDTH_MAX 1000000L
#define PNG_QUANTIZE_GREEN_BITS 5
#define PNG_API_RULE 0
#define PNG_QUANTIZE_BLUE_BITS 5
#define PNG_USER_CHUNK_CACHE_MAX 0
#define PNG_USER_HEIGHT_MAX 1000000L
#define PNG_sCAL_PRECISION 5
#define PNG_COST_SHIFT 3
#define PNG_WEIGHT_SHIFT 8
#define PNG_USER_CHUNK_MALLOC_MAX 0
#define PNG_DEFAULT_READ_MACROS 1
#define PNG_ZBUF_SIZE 8192
#define PNG_GAMMA_THRESHOLD_FIXED 5000
/* end of settings */
/* options */
#define PNG_INFO_IMAGE_SUPPORTED
#define PNG_HANDLE_AS_UNKNOWN_SUPPORTED
#define PNG_POINTER_INDEXING_SUPPORTED
#define PNG_WARNINGS_SUPPORTED
#define PNG_FLOATING_ARITHMETIC_SUPPORTED
#define PNG_WRITE_SUPPORTED
#define PNG_WRITE_INTERLACING_SUPPORTED
#define PNG_WRITE_16BIT_SUPPORTED
#define PNG_EASY_ACCESS_SUPPORTED
#define PNG_ALIGN_MEMORY_SUPPORTED
#define PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
#define PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED
#define PNG_USER_LIMITS_SUPPORTED
#define PNG_FIXED_POINT_SUPPORTED
/*#undef PNG_ERROR_NUMBERS_SUPPORTED*/
#define PNG_ERROR_TEXT_SUPPORTED
#define PNG_READ_SUPPORTED
/*#undef PNG_READ_16_TO_8_ACCURATE_SCALE_SUPPORTED*/
#define PNG_BENIGN_ERRORS_SUPPORTED
#define PNG_SETJMP_SUPPORTED
#define PNG_WRITE_FLUSH_SUPPORTED
#define PNG_MNG_FEATURES_SUPPORTED
#define PNG_FLOATING_POINT_SUPPORTED
#define PNG_INCH_CONVERSIONS_SUPPORTED
#define PNG_STDIO_SUPPORTED
#define PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
#define PNG_USER_MEM_SUPPORTED
#define PNG_IO_STATE_SUPPORTED
#define PNG_SET_USER_LIMITS_SUPPORTED
#define PNG_READ_ANCILLARY_CHUNKS_SUPPORTED
#define PNG_WRITE_INT_FUNCTIONS_SUPPORTED
#define PNG_WRITE_ANCILLARY_CHUNKS_SUPPORTED
#define PNG_WRITE_FILTER_SUPPORTED
#define PNG_SET_CHUNK_CACHE_LIMIT_SUPPORTED
#define PNG_WRITE_iCCP_SUPPORTED
#define PNG_READ_TRANSFORMS_SUPPORTED
#define PNG_READ_GAMMA_SUPPORTED
#define PNG_READ_bKGD_SUPPORTED
#define PNG_UNKNOWN_CHUNKS_SUPPORTED
#define PNG_READ_sCAL_SUPPORTED
#define PNG_WRITE_hIST_SUPPORTED
#define PNG_READ_OPT_PLTE_SUPPORTED
#define PNG_SET_CHUNK_MALLOC_LIMIT_SUPPORTED
#define PNG_WRITE_gAMA_SUPPORTED
#define PNG_READ_GRAY_TO_RGB_SUPPORTED
#define PNG_WRITE_pCAL_SUPPORTED
#define PNG_READ_INVERT_ALPHA_SUPPORTED
#define PNG_WRITE_TRANSFORMS_SUPPORTED
#define PNG_READ_sBIT_SUPPORTED
#define PNG_READ_PACK_SUPPORTED
#define PNG_WRITE_SWAP_SUPPORTED
#define PNG_READ_cHRM_SUPPORTED
#define PNG_WRITE_tIME_SUPPORTED
#define PNG_READ_INTERLACING_SUPPORTED
#define PNG_READ_tRNS_SUPPORTED
#define PNG_WRITE_pHYs_SUPPORTED
#define PNG_WRITE_INVERT_SUPPORTED
#define PNG_READ_RGB_TO_GRAY_SUPPORTED
#define PNG_WRITE_sRGB_SUPPORTED
#define PNG_READ_oFFs_SUPPORTED
#define PNG_WRITE_FILLER_SUPPORTED
#define PNG_WRITE_TEXT_SUPPORTED
#define PNG_WRITE_SHIFT_SUPPORTED
#define PNG_PROGRESSIVE_READ_SUPPORTED
#define PNG_READ_SHIFT_SUPPORTED
#define PNG_CONVERT_tIME_SUPPORTED
#define PNG_READ_USER_TRANSFORM_SUPPORTED
#define PNG_READ_INT_FUNCTIONS_SUPPORTED
#define PNG_READ_USER_CHUNKS_SUPPORTED
#define PNG_READ_hIST_SUPPORTED
#define PNG_READ_16BIT_SUPPORTED
#define PNG_READ_SWAP_ALPHA_SUPPORTED
#define PNG_READ_COMPOSITE_NODIV_SUPPORTED
#define PNG_SEQUENTIAL_READ_SUPPORTED
#define PNG_READ_BACKGROUND_SUPPORTED
#define PNG_READ_QUANTIZE_SUPPORTED
#define PNG_READ_iCCP_SUPPORTED
#define PNG_READ_STRIP_ALPHA_SUPPORTED
#define PNG_READ_PACKSWAP_SUPPORTED
#define PNG_READ_sRGB_SUPPORTED
#define PNG_WRITE_tEXt_SUPPORTED
#define PNG_READ_gAMA_SUPPORTED
#define PNG_READ_pCAL_SUPPORTED
#define PNG_READ_EXPAND_SUPPORTED
#define PNG_WRITE_sPLT_SUPPORTED
#define PNG_READ_SWAP_SUPPORTED
#define PNG_READ_tIME_SUPPORTED
#define PNG_READ_pHYs_SUPPORTED
#define PNG_WRITE_SWAP_ALPHA_SUPPORTED
#define PNG_TIME_RFC1123_SUPPORTED
#define PNG_READ_TEXT_SUPPORTED
#define PNG_WRITE_BGR_SUPPORTED
#define PNG_USER_CHUNKS_SUPPORTED
#define PNG_CONSOLE_IO_SUPPORTED
#define PNG_WRITE_PACK_SUPPORTED
#define PNG_READ_FILLER_SUPPORTED
#define PNG_WRITE_bKGD_SUPPORTED
#define PNG_WRITE_tRNS_SUPPORTED
#define PNG_READ_sPLT_SUPPORTED
#define PNG_WRITE_sCAL_SUPPORTED
#define PNG_WRITE_oFFs_SUPPORTED
#define PNG_READ_tEXt_SUPPORTED
#define PNG_WRITE_sBIT_SUPPORTED
#define PNG_READ_INVERT_SUPPORTED
#define PNG_READ_16_TO_8_SUPPORTED
#define PNG_WRITE_cHRM_SUPPORTED
#define PNG_16BIT_SUPPORTED
#define PNG_WRITE_USER_TRANSFORM_SUPPORTED
#define PNG_READ_BGR_SUPPORTED
#define PNG_WRITE_PACKSWAP_SUPPORTED
#define PNG_WRITE_INVERT_ALPHA_SUPPORTED
#define PNG_sCAL_SUPPORTED
#define PNG_WRITE_zTXt_SUPPORTED
#define PNG_USER_TRANSFORM_INFO_SUPPORTED
#define PNG_sBIT_SUPPORTED
#define PNG_cHRM_SUPPORTED
#define PNG_bKGD_SUPPORTED
#define PNG_tRNS_SUPPORTED
#define PNG_WRITE_iTXt_SUPPORTED
#define PNG_oFFs_SUPPORTED
#define PNG_USER_TRANSFORM_PTR_SUPPORTED
#define PNG_hIST_SUPPORTED
#define PNG_iCCP_SUPPORTED
#define PNG_sRGB_SUPPORTED
#define PNG_READ_zTXt_SUPPORTED
#define PNG_gAMA_SUPPORTED
#define PNG_pCAL_SUPPORTED
#define PNG_CHECK_cHRM_SUPPORTED
#define PNG_tIME_SUPPORTED
#define PNG_pHYs_SUPPORTED
#define PNG_READ_iTXt_SUPPORTED
#define PNG_TEXT_SUPPORTED
#define PNG_SAVE_INT_32_SUPPORTED
#define PNG_sPLT_SUPPORTED
#define PNG_tEXt_SUPPORTED
#define PNG_zTXt_SUPPORTED
#define PNG_iTXt_SUPPORTED
/* end of options */
#endif /* PNGLCONF_H */

View File

@ -0,0 +1,658 @@
/* pngmem.c - stub functions for memory allocation
*
* Last changed in libpng 1.5.1 [February 3, 2011]
* Copyright (c) 1998-2011 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
*
* This code is released under the libpng license.
* For conditions of distribution and use, see the disclaimer
* and license in png.h
*
* This file provides a location for all memory allocation. Users who
* need special memory handling are expected to supply replacement
* functions for png_malloc() and png_free(), and to use
* png_create_read_struct_2() and png_create_write_struct_2() to
* identify the replacement functions.
*/
#include "pngpriv.h"
#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
/* Borland DOS special memory handler */
#if defined(__TURBOC__) && !defined(_Windows) && !defined(__FLAT__)
/* If you change this, be sure to change the one in png.h also */
/* Allocate memory for a png_struct. The malloc and memset can be replaced
by a single call to calloc() if this is thought to improve performance. */
PNG_FUNCTION(png_voidp /* PRIVATE */,
png_create_struct,(int type),PNG_ALLOCATED)
{
# ifdef PNG_USER_MEM_SUPPORTED
return (png_create_struct_2(type, NULL, NULL));
}
/* Alternate version of png_create_struct, for use with user-defined malloc. */
PNG_FUNCTION(png_voidp /* PRIVATE */,
png_create_struct_2,(int type, png_malloc_ptr malloc_fn, png_voidp mem_ptr),
PNG_ALLOCATED)
{
# endif /* PNG_USER_MEM_SUPPORTED */
png_size_t size;
png_voidp struct_ptr;
if (type == PNG_STRUCT_INFO)
size = png_sizeof(png_info);
else if (type == PNG_STRUCT_PNG)
size = png_sizeof(png_struct);
else
return (png_get_copyright(NULL));
# ifdef PNG_USER_MEM_SUPPORTED
if (malloc_fn != NULL)
{
png_struct dummy_struct;
png_structp png_ptr = &dummy_struct;
png_ptr->mem_ptr=mem_ptr;
struct_ptr = (*(malloc_fn))(png_ptr, (png_uint_32)size);
}
else
# endif /* PNG_USER_MEM_SUPPORTED */
struct_ptr = (png_voidp)farmalloc(size);
if (struct_ptr != NULL)
png_memset(struct_ptr, 0, size);
return (struct_ptr);
}
/* Free memory allocated by a png_create_struct() call */
void /* PRIVATE */
png_destroy_struct(png_voidp struct_ptr)
{
# ifdef PNG_USER_MEM_SUPPORTED
png_destroy_struct_2(struct_ptr, NULL, NULL);
}
/* Free memory allocated by a png_create_struct() call */
void /* PRIVATE */
png_destroy_struct_2(png_voidp struct_ptr, png_free_ptr free_fn,
png_voidp mem_ptr)
{
# endif
if (struct_ptr != NULL)
{
# ifdef PNG_USER_MEM_SUPPORTED
if (free_fn != NULL)
{
png_struct dummy_struct;
png_structp png_ptr = &dummy_struct;
png_ptr->mem_ptr=mem_ptr;
(*(free_fn))(png_ptr, struct_ptr);
return;
}
# endif /* PNG_USER_MEM_SUPPORTED */
farfree (struct_ptr);
}
}
/* Allocate memory. For reasonable files, size should never exceed
* 64K. However, zlib may allocate more then 64K if you don't tell
* it not to. See zconf.h and png.h for more information. zlib does
* need to allocate exactly 64K, so whatever you call here must
* have the ability to do that.
*
* Borland seems to have a problem in DOS mode for exactly 64K.
* It gives you a segment with an offset of 8 (perhaps to store its
* memory stuff). zlib doesn't like this at all, so we have to
* detect and deal with it. This code should not be needed in
* Windows or OS/2 modes, and only in 16 bit mode. This code has
* been updated by Alexander Lehmann for version 0.89 to waste less
* memory.
*
* Note that we can't use png_size_t for the "size" declaration,
* since on some systems a png_size_t is a 16-bit quantity, and as a
* result, we would be truncating potentially larger memory requests
* (which should cause a fatal error) and introducing major problems.
*/
PNG_FUNCTION(png_voidp,PNGAPI
png_calloc,(png_structp png_ptr, png_alloc_size_t size),PNG_ALLOCATED)
{
png_voidp ret;
ret = (png_malloc(png_ptr, size));
if (ret != NULL)
png_memset(ret,0,(png_size_t)size);
return (ret);
}
PNG_FUNCTION(png_voidp,PNGAPI
png_malloc,(png_structp png_ptr, png_alloc_size_t size),PNG_ALLOCATED)
{
png_voidp ret;
if (png_ptr == NULL || size == 0)
return (NULL);
# ifdef PNG_USER_MEM_SUPPORTED
if (png_ptr->malloc_fn != NULL)
ret = ((png_voidp)(*(png_ptr->malloc_fn))(png_ptr, (png_size_t)size));
else
ret = (png_malloc_default(png_ptr, size));
if (ret == NULL && (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
png_error(png_ptr, "Out of memory");
return (ret);
}
PNG_FUNCTION(png_voidp,PNGAPI
png_malloc_default,(png_structp png_ptr, png_alloc_size_t size),PNG_ALLOCATED)
{
png_voidp ret;
# endif /* PNG_USER_MEM_SUPPORTED */
if (png_ptr == NULL || size == 0)
return (NULL);
# ifdef PNG_MAX_MALLOC_64K
if (size > (png_uint_32)65536L)
{
png_warning(png_ptr, "Cannot Allocate > 64K");
ret = NULL;
}
else
# endif
if (size != (size_t)size)
ret = NULL;
else if (size == (png_uint_32)65536L)
{
if (png_ptr->offset_table == NULL)
{
/* Try to see if we need to do any of this fancy stuff */
ret = farmalloc(size);
if (ret == NULL || ((png_size_t)ret & 0xffff))
{
int num_blocks;
png_uint_32 total_size;
png_bytep table;
int i;
png_byte huge * hptr;
if (ret != NULL)
{
farfree(ret);
ret = NULL;
}
if (png_ptr->zlib_window_bits > 14)
num_blocks = (int)(1 << (png_ptr->zlib_window_bits - 14));
else
num_blocks = 1;
if (png_ptr->zlib_mem_level >= 7)
num_blocks += (int)(1 << (png_ptr->zlib_mem_level - 7));
else
num_blocks++;
total_size = ((png_uint_32)65536L) * (png_uint_32)num_blocks+16;
table = farmalloc(total_size);
if (table == NULL)
{
# ifndef PNG_USER_MEM_SUPPORTED
if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
png_error(png_ptr, "Out Of Memory"); /* Note "O", "M" */
else
png_warning(png_ptr, "Out Of Memory");
# endif
return (NULL);
}
if ((png_size_t)table & 0xfff0)
{
# ifndef PNG_USER_MEM_SUPPORTED
if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
png_error(png_ptr,
"Farmalloc didn't return normalized pointer");
else
png_warning(png_ptr,
"Farmalloc didn't return normalized pointer");
# endif
return (NULL);
}
png_ptr->offset_table = table;
png_ptr->offset_table_ptr = farmalloc(num_blocks *
png_sizeof(png_bytep));
if (png_ptr->offset_table_ptr == NULL)
{
# ifndef PNG_USER_MEM_SUPPORTED
if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
png_error(png_ptr, "Out Of memory"); /* Note "O", "m" */
else
png_warning(png_ptr, "Out Of memory");
# endif
return (NULL);
}
hptr = (png_byte huge *)table;
if ((png_size_t)hptr & 0xf)
{
hptr = (png_byte huge *)((long)(hptr) & 0xfffffff0L);
hptr = hptr + 16L; /* "hptr += 16L" fails on Turbo C++ 3.0 */
}
for (i = 0; i < num_blocks; i++)
{
png_ptr->offset_table_ptr[i] = (png_bytep)hptr;
hptr = hptr + (png_uint_32)65536L; /* "+=" fails on TC++3.0 */
}
png_ptr->offset_table_number = num_blocks;
png_ptr->offset_table_count = 0;
png_ptr->offset_table_count_free = 0;
}
}
if (png_ptr->offset_table_count >= png_ptr->offset_table_number)
{
# ifndef PNG_USER_MEM_SUPPORTED
if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
png_error(png_ptr, "Out of Memory"); /* Note "o" and "M" */
else
png_warning(png_ptr, "Out of Memory");
# endif
return (NULL);
}
ret = png_ptr->offset_table_ptr[png_ptr->offset_table_count++];
}
else
ret = farmalloc(size);
# ifndef PNG_USER_MEM_SUPPORTED
if (ret == NULL)
{
if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
png_error(png_ptr, "Out of memory"); /* Note "o" and "m" */
else
png_warning(png_ptr, "Out of memory"); /* Note "o" and "m" */
}
# endif
return (ret);
}
/* Free a pointer allocated by png_malloc(). In the default
* configuration, png_ptr is not used, but is passed in case it
* is needed. If ptr is NULL, return without taking any action.
*/
void PNGAPI
png_free(png_structp png_ptr, png_voidp ptr)
{
if (png_ptr == NULL || ptr == NULL)
return;
# ifdef PNG_USER_MEM_SUPPORTED
if (png_ptr->free_fn != NULL)
{
(*(png_ptr->free_fn))(png_ptr, ptr);
return;
}
else
png_free_default(png_ptr, ptr);
}
void PNGAPI
png_free_default(png_structp png_ptr, png_voidp ptr)
{
# endif /* PNG_USER_MEM_SUPPORTED */
if (png_ptr == NULL || ptr == NULL)
return;
if (png_ptr->offset_table != NULL)
{
int i;
for (i = 0; i < png_ptr->offset_table_count; i++)
{
if (ptr == png_ptr->offset_table_ptr[i])
{
ptr = NULL;
png_ptr->offset_table_count_free++;
break;
}
}
if (png_ptr->offset_table_count_free == png_ptr->offset_table_count)
{
farfree(png_ptr->offset_table);
farfree(png_ptr->offset_table_ptr);
png_ptr->offset_table = NULL;
png_ptr->offset_table_ptr = NULL;
}
}
if (ptr != NULL)
farfree(ptr);
}
#else /* Not the Borland DOS special memory handler */
/* Allocate memory for a png_struct or a png_info. The malloc and
memset can be replaced by a single call to calloc() if this is thought
to improve performance noticably. */
PNG_FUNCTION(png_voidp /* PRIVATE */,
png_create_struct,(int type),PNG_ALLOCATED)
{
# ifdef PNG_USER_MEM_SUPPORTED
return (png_create_struct_2(type, NULL, NULL));
}
/* Allocate memory for a png_struct or a png_info. The malloc and
memset can be replaced by a single call to calloc() if this is thought
to improve performance noticably. */
PNG_FUNCTION(png_voidp /* PRIVATE */,
png_create_struct_2,(int type, png_malloc_ptr malloc_fn, png_voidp mem_ptr),
PNG_ALLOCATED)
{
# endif /* PNG_USER_MEM_SUPPORTED */
png_size_t size;
png_voidp struct_ptr;
if (type == PNG_STRUCT_INFO)
size = png_sizeof(png_info);
else if (type == PNG_STRUCT_PNG)
size = png_sizeof(png_struct);
else
return (NULL);
# ifdef PNG_USER_MEM_SUPPORTED
if (malloc_fn != NULL)
{
png_struct dummy_struct;
png_structp png_ptr = &dummy_struct;
png_ptr->mem_ptr=mem_ptr;
struct_ptr = (*(malloc_fn))(png_ptr, size);
if (struct_ptr != NULL)
png_memset(struct_ptr, 0, size);
return (struct_ptr);
}
# endif /* PNG_USER_MEM_SUPPORTED */
# if defined(__TURBOC__) && !defined(__FLAT__)
struct_ptr = (png_voidp)farmalloc(size);
# else
# if defined(_MSC_VER) && defined(MAXSEG_64K)
struct_ptr = (png_voidp)halloc(size, 1);
# else
struct_ptr = (png_voidp)malloc(size);
# endif
# endif
if (struct_ptr != NULL)
png_memset(struct_ptr, 0, size);
return (struct_ptr);
}
/* Free memory allocated by a png_create_struct() call */
void /* PRIVATE */
png_destroy_struct(png_voidp struct_ptr)
{
# ifdef PNG_USER_MEM_SUPPORTED
png_destroy_struct_2(struct_ptr, NULL, NULL);
}
/* Free memory allocated by a png_create_struct() call */
void /* PRIVATE */
png_destroy_struct_2(png_voidp struct_ptr, png_free_ptr free_fn,
png_voidp mem_ptr)
{
# endif /* PNG_USER_MEM_SUPPORTED */
if (struct_ptr != NULL)
{
# ifdef PNG_USER_MEM_SUPPORTED
if (free_fn != NULL)
{
png_struct dummy_struct;
png_structp png_ptr = &dummy_struct;
png_ptr->mem_ptr=mem_ptr;
(*(free_fn))(png_ptr, struct_ptr);
return;
}
# endif /* PNG_USER_MEM_SUPPORTED */
# if defined(__TURBOC__) && !defined(__FLAT__)
farfree(struct_ptr);
# else
# if defined(_MSC_VER) && defined(MAXSEG_64K)
hfree(struct_ptr);
# else
free(struct_ptr);
# endif
# endif
}
}
/* Allocate memory. For reasonable files, size should never exceed
* 64K. However, zlib may allocate more then 64K if you don't tell
* it not to. See zconf.h and png.h for more information. zlib does
* need to allocate exactly 64K, so whatever you call here must
* have the ability to do that.
*/
PNG_FUNCTION(png_voidp,PNGAPI
png_calloc,(png_structp png_ptr, png_alloc_size_t size),PNG_ALLOCATED)
{
png_voidp ret;
ret = (png_malloc(png_ptr, size));
if (ret != NULL)
png_memset(ret,0,(png_size_t)size);
return (ret);
}
PNG_FUNCTION(png_voidp,PNGAPI
png_malloc,(png_structp png_ptr, png_alloc_size_t size),PNG_ALLOCATED)
{
png_voidp ret;
# ifdef PNG_USER_MEM_SUPPORTED
if (png_ptr == NULL || size == 0)
return (NULL);
if (png_ptr->malloc_fn != NULL)
ret = ((png_voidp)(*(png_ptr->malloc_fn))(png_ptr, (png_size_t)size));
else
ret = (png_malloc_default(png_ptr, size));
if (ret == NULL && (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
png_error(png_ptr, "Out of Memory");
return (ret);
}
PNG_FUNCTION(png_voidp,PNGAPI
png_malloc_default,(png_structp png_ptr, png_alloc_size_t size),PNG_ALLOCATED)
{
png_voidp ret;
# endif /* PNG_USER_MEM_SUPPORTED */
if (png_ptr == NULL || size == 0)
return (NULL);
# ifdef PNG_MAX_MALLOC_64K
if (size > (png_uint_32)65536L)
{
# ifndef PNG_USER_MEM_SUPPORTED
if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
png_error(png_ptr, "Cannot Allocate > 64K");
else
# endif
return NULL;
}
# endif
/* Check for overflow */
# if defined(__TURBOC__) && !defined(__FLAT__)
if (size != (unsigned long)size)
ret = NULL;
else
ret = farmalloc(size);
# else
# if defined(_MSC_VER) && defined(MAXSEG_64K)
if (size != (unsigned long)size)
ret = NULL;
else
ret = halloc(size, 1);
# else
if (size != (size_t)size)
ret = NULL;
else
ret = malloc((size_t)size);
# endif
# endif
# ifndef PNG_USER_MEM_SUPPORTED
if (ret == NULL && (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
png_error(png_ptr, "Out of Memory");
# endif
return (ret);
}
/* Free a pointer allocated by png_malloc(). If ptr is NULL, return
* without taking any action.
*/
void PNGAPI
png_free(png_structp png_ptr, png_voidp ptr)
{
if (png_ptr == NULL || ptr == NULL)
return;
# ifdef PNG_USER_MEM_SUPPORTED
if (png_ptr->free_fn != NULL)
{
(*(png_ptr->free_fn))(png_ptr, ptr);
return;
}
else
png_free_default(png_ptr, ptr);
}
void PNGAPI
png_free_default(png_structp png_ptr, png_voidp ptr)
{
if (png_ptr == NULL || ptr == NULL)
return;
# endif /* PNG_USER_MEM_SUPPORTED */
# if defined(__TURBOC__) && !defined(__FLAT__)
farfree(ptr);
# else
# if defined(_MSC_VER) && defined(MAXSEG_64K)
hfree(ptr);
# else
free(ptr);
# endif
# endif
}
#endif /* Not Borland DOS special memory handler */
/* This function was added at libpng version 1.2.3. The png_malloc_warn()
* function will set up png_malloc() to issue a png_warning and return NULL
* instead of issuing a png_error, if it fails to allocate the requested
* memory.
*/
PNG_FUNCTION(png_voidp,PNGAPI
png_malloc_warn,(png_structp png_ptr, png_alloc_size_t size),PNG_ALLOCATED)
{
png_voidp ptr;
png_uint_32 save_flags;
if (png_ptr == NULL)
return (NULL);
save_flags = png_ptr->flags;
png_ptr->flags|=PNG_FLAG_MALLOC_NULL_MEM_OK;
ptr = (png_voidp)png_malloc((png_structp)png_ptr, size);
png_ptr->flags=save_flags;
return(ptr);
}
#ifdef PNG_USER_MEM_SUPPORTED
/* This function is called when the application wants to use another method
* of allocating and freeing memory.
*/
void PNGAPI
png_set_mem_fn(png_structp png_ptr, png_voidp mem_ptr, png_malloc_ptr
malloc_fn, png_free_ptr free_fn)
{
if (png_ptr != NULL)
{
png_ptr->mem_ptr = mem_ptr;
png_ptr->malloc_fn = malloc_fn;
png_ptr->free_fn = free_fn;
}
}
/* This function returns a pointer to the mem_ptr associated with the user
* functions. The application should free any memory associated with this
* pointer before png_write_destroy and png_read_destroy are called.
*/
png_voidp PNGAPI
png_get_mem_ptr(png_const_structp png_ptr)
{
if (png_ptr == NULL)
return (NULL);
return ((png_voidp)png_ptr->mem_ptr);
}
#endif /* PNG_USER_MEM_SUPPORTED */
#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,176 @@
/* pngrio.c - functions for data input
*
* Last changed in libpng 1.5.0 [January 6, 2011]
* Copyright (c) 1998-2011 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
*
* This code is released under the libpng license.
* For conditions of distribution and use, see the disclaimer
* and license in png.h
*
* This file provides a location for all input. Users who need
* special handling are expected to write a function that has the same
* arguments as this and performs a similar function, but that possibly
* has a different input method. Note that you shouldn't change this
* function, but rather write a replacement function and then make
* libpng use it at run time with png_set_read_fn(...).
*/
#include "pngpriv.h"
#ifdef PNG_READ_SUPPORTED
/* Read the data from whatever input you are using. The default routine
* reads from a file pointer. Note that this routine sometimes gets called
* with very small lengths, so you should implement some kind of simple
* buffering if you are using unbuffered reads. This should never be asked
* to read more then 64K on a 16 bit machine.
*/
void /* PRIVATE */
png_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
{
png_debug1(4, "reading %d bytes", (int)length);
if (png_ptr->read_data_fn != NULL)
(*(png_ptr->read_data_fn))(png_ptr, data, length);
else
png_error(png_ptr, "Call to NULL read function");
}
#ifdef PNG_STDIO_SUPPORTED
/* This is the function that does the actual reading of data. If you are
* not reading from a standard C stream, you should create a replacement
* read_data function and use it at run time with png_set_read_fn(), rather
* than changing the library.
*/
# ifndef USE_FAR_KEYWORD
void PNGCBAPI
png_default_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
{
png_size_t check;
if (png_ptr == NULL)
return;
/* fread() returns 0 on error, so it is OK to store this in a png_size_t
* instead of an int, which is what fread() actually returns.
*/
check = fread(data, 1, length, (png_FILE_p)png_ptr->io_ptr);
if (check != length)
png_error(png_ptr, "Read Error");
}
# else
/* This is the model-independent version. Since the standard I/O library
can't handle far buffers in the medium and small models, we have to copy
the data.
*/
#define NEAR_BUF_SIZE 1024
#define MIN(a,b) (a <= b ? a : b)
static void PNGCBAPI
png_default_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
{
png_size_t check;
png_byte *n_data;
png_FILE_p io_ptr;
if (png_ptr == NULL)
return;
/* Check if data really is near. If so, use usual code. */
n_data = (png_byte *)CVT_PTR_NOCHECK(data);
io_ptr = (png_FILE_p)CVT_PTR(png_ptr->io_ptr);
if ((png_bytep)n_data == data)
{
check = fread(n_data, 1, length, io_ptr);
}
else
{
png_byte buf[NEAR_BUF_SIZE];
png_size_t read, remaining, err;
check = 0;
remaining = length;
do
{
read = MIN(NEAR_BUF_SIZE, remaining);
err = fread(buf, 1, read, io_ptr);
png_memcpy(data, buf, read); /* copy far buffer to near buffer */
if (err != read)
break;
else
check += err;
data += read;
remaining -= read;
}
while (remaining != 0);
}
if ((png_uint_32)check != (png_uint_32)length)
png_error(png_ptr, "read Error");
}
# endif
#endif
/* This function allows the application to supply a new input function
* for libpng if standard C streams aren't being used.
*
* This function takes as its arguments:
*
* png_ptr - pointer to a png input data structure
*
* io_ptr - pointer to user supplied structure containing info about
* the input functions. May be NULL.
*
* read_data_fn - pointer to a new input function that takes as its
* arguments a pointer to a png_struct, a pointer to
* a location where input data can be stored, and a 32-bit
* unsigned int that is the number of bytes to be read.
* To exit and output any fatal error messages the new write
* function should call png_error(png_ptr, "Error msg").
* May be NULL, in which case libpng's default function will
* be used.
*/
void PNGAPI
png_set_read_fn(png_structp png_ptr, png_voidp io_ptr,
png_rw_ptr read_data_fn)
{
if (png_ptr == NULL)
return;
png_ptr->io_ptr = io_ptr;
#ifdef PNG_STDIO_SUPPORTED
if (read_data_fn != NULL)
png_ptr->read_data_fn = read_data_fn;
else
png_ptr->read_data_fn = png_default_read_data;
#else
png_ptr->read_data_fn = read_data_fn;
#endif
/* It is an error to write to a read device */
if (png_ptr->write_data_fn != NULL)
{
png_ptr->write_data_fn = NULL;
png_warning(png_ptr,
"Can't set both read_data_fn and write_data_fn in the"
" same structure");
}
#ifdef PNG_WRITE_FLUSH_SUPPORTED
png_ptr->output_flush_fn = NULL;
#endif
}
#endif /* PNG_READ_SUPPORTED */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,308 @@
/* pngstruct.h - header file for PNG reference library
*
* Copyright (c) 1998-2011 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
*
* Last changed in libpng 1.5.0 [January 6, 2011]
*
* This code is released under the libpng license.
* For conditions of distribution and use, see the disclaimer
* and license in png.h
*/
/* The structure that holds the information to read and write PNG files.
* The only people who need to care about what is inside of this are the
* people who will be modifying the library for their own special needs.
* It should NOT be accessed directly by an application.
*/
#ifndef PNGSTRUCT_H
#define PNGSTRUCT_H
/* zlib.h defines the structure z_stream, an instance of which is included
* in this structure and is required for decompressing the LZ compressed
* data in PNG files.
*/
#include "zlib.h"
struct png_struct_def
{
#ifdef PNG_SETJMP_SUPPORTED
jmp_buf png_jmpbuf; /* used in png_error */
png_longjmp_ptr longjmp_fn;/* setjmp non-local goto function. */
#endif
png_error_ptr error_fn; /* function for printing errors and aborting */
png_error_ptr warning_fn; /* function for printing warnings */
png_voidp error_ptr; /* user supplied struct for error functions */
png_rw_ptr write_data_fn; /* function for writing output data */
png_rw_ptr read_data_fn; /* function for reading input data */
png_voidp io_ptr; /* ptr to application struct for I/O functions */
#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
png_user_transform_ptr read_user_transform_fn; /* user read transform */
#endif
#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED
png_user_transform_ptr write_user_transform_fn; /* user write transform */
#endif
/* These were added in libpng-1.0.2 */
#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED
#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
png_voidp user_transform_ptr; /* user supplied struct for user transform */
png_byte user_transform_depth; /* bit depth of user transformed pixels */
png_byte user_transform_channels; /* channels in user transformed pixels */
#endif
#endif
png_uint_32 mode; /* tells us where we are in the PNG file */
png_uint_32 flags; /* flags indicating various things to libpng */
png_uint_32 transformations; /* which transformations to perform */
z_stream zstream; /* pointer to decompression structure (below) */
png_bytep zbuf; /* buffer for zlib */
uInt zbuf_size; /* size of zbuf (typically 65536) */
int zlib_level; /* holds zlib compression level */
int zlib_method; /* holds zlib compression method */
int zlib_window_bits; /* holds zlib compression window bits */
int zlib_mem_level; /* holds zlib compression memory level */
int zlib_strategy; /* holds zlib compression strategy */
png_uint_32 width; /* width of image in pixels */
png_uint_32 height; /* height of image in pixels */
png_uint_32 num_rows; /* number of rows in current pass */
png_uint_32 usr_width; /* width of row at start of write */
png_size_t rowbytes; /* size of row in bytes */
png_uint_32 iwidth; /* width of current interlaced row in pixels */
png_uint_32 row_number; /* current row in interlace pass */
png_bytep prev_row; /* buffer to save previous (unfiltered) row */
png_bytep row_buf; /* buffer to save current (unfiltered) row */
png_bytep sub_row; /* buffer to save "sub" row when filtering */
png_bytep up_row; /* buffer to save "up" row when filtering */
png_bytep avg_row; /* buffer to save "avg" row when filtering */
png_bytep paeth_row; /* buffer to save "Paeth" row when filtering */
png_row_info row_info; /* used for transformation routines */
png_uint_32 idat_size; /* current IDAT size for read */
png_uint_32 crc; /* current chunk CRC value */
png_colorp palette; /* palette from the input file */
png_uint_16 num_palette; /* number of color entries in palette */
png_uint_16 num_trans; /* number of transparency values */
png_byte chunk_name[5]; /* null-terminated name of current chunk */
png_byte compression; /* file compression type (always 0) */
png_byte filter; /* file filter type (always 0) */
png_byte interlaced; /* PNG_INTERLACE_NONE, PNG_INTERLACE_ADAM7 */
png_byte pass; /* current interlace pass (0 - 6) */
png_byte do_filter; /* row filter flags (see PNG_FILTER_ below ) */
png_byte color_type; /* color type of file */
png_byte bit_depth; /* bit depth of file */
png_byte usr_bit_depth; /* bit depth of users row */
png_byte pixel_depth; /* number of bits per pixel */
png_byte channels; /* number of channels in file */
png_byte usr_channels; /* channels at start of write */
png_byte sig_bytes; /* magic bytes read/written from start of file */
#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED)
png_uint_16 filler; /* filler bytes for pixel expansion */
#endif
#ifdef PNG_bKGD_SUPPORTED
png_byte background_gamma_type;
png_fixed_point background_gamma;
png_color_16 background; /* background color in screen gamma space */
#ifdef PNG_READ_GAMMA_SUPPORTED
png_color_16 background_1; /* background normalized to gamma 1.0 */
#endif
#endif /* PNG_bKGD_SUPPORTED */
#ifdef PNG_WRITE_FLUSH_SUPPORTED
png_flush_ptr output_flush_fn; /* Function for flushing output */
png_uint_32 flush_dist; /* how many rows apart to flush, 0 - no flush */
png_uint_32 flush_rows; /* number of rows written since last flush */
#endif
#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
int gamma_shift; /* number of "insignificant" bits in 16-bit gamma */
png_fixed_point gamma; /* file gamma value */
png_fixed_point screen_gamma; /* screen gamma value (display_exponent) */
#endif
#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
png_bytep gamma_table; /* gamma table for 8-bit depth files */
png_bytep gamma_from_1; /* converts from 1.0 to screen */
png_bytep gamma_to_1; /* converts from file to 1.0 */
png_uint_16pp gamma_16_table; /* gamma table for 16-bit depth files */
png_uint_16pp gamma_16_from_1; /* converts from 1.0 to screen */
png_uint_16pp gamma_16_to_1; /* converts from file to 1.0 */
#endif
#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_sBIT_SUPPORTED)
png_color_8 sig_bit; /* significant bits in each available channel */
#endif
#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED)
png_color_8 shift; /* shift for significant bit tranformation */
#endif
#if defined(PNG_tRNS_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) \
|| defined(PNG_READ_EXPAND_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
png_bytep trans_alpha; /* alpha values for paletted files */
png_color_16 trans_color; /* transparent color for non-paletted files */
#endif
png_read_status_ptr read_row_fn; /* called after each row is decoded */
png_write_status_ptr write_row_fn; /* called after each row is encoded */
#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
png_progressive_info_ptr info_fn; /* called after header data fully read */
png_progressive_row_ptr row_fn; /* called after a prog. row is decoded */
png_progressive_end_ptr end_fn; /* called after image is complete */
png_bytep save_buffer_ptr; /* current location in save_buffer */
png_bytep save_buffer; /* buffer for previously read data */
png_bytep current_buffer_ptr; /* current location in current_buffer */
png_bytep current_buffer; /* buffer for recently used data */
png_uint_32 push_length; /* size of current input chunk */
png_uint_32 skip_length; /* bytes to skip in input data */
png_size_t save_buffer_size; /* amount of data now in save_buffer */
png_size_t save_buffer_max; /* total size of save_buffer */
png_size_t buffer_size; /* total amount of available input data */
png_size_t current_buffer_size; /* amount of data now in current_buffer */
int process_mode; /* what push library is currently doing */
int cur_palette; /* current push library palette index */
# ifdef PNG_TEXT_SUPPORTED
png_size_t current_text_size; /* current size of text input data */
png_size_t current_text_left; /* how much text left to read in input */
png_charp current_text; /* current text chunk buffer */
png_charp current_text_ptr; /* current location in current_text */
# endif /* PNG_PROGRESSIVE_READ_SUPPORTED && PNG_TEXT_SUPPORTED */
#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */
#if defined(__TURBOC__) && !defined(_Windows) && !defined(__FLAT__)
/* For the Borland special 64K segment handler */
png_bytepp offset_table_ptr;
png_bytep offset_table;
png_uint_16 offset_table_number;
png_uint_16 offset_table_count;
png_uint_16 offset_table_count_free;
#endif
#ifdef PNG_READ_QUANTIZE_SUPPORTED
png_bytep palette_lookup; /* lookup table for quantizing */
png_bytep quantize_index; /* index translation for palette files */
#endif
#if defined(PNG_READ_QUANTIZE_SUPPORTED) || defined(PNG_hIST_SUPPORTED)
png_uint_16p hist; /* histogram */
#endif
#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
png_byte heuristic_method; /* heuristic for row filter selection */
png_byte num_prev_filters; /* number of weights for previous rows */
png_bytep prev_filters; /* filter type(s) of previous row(s) */
png_uint_16p filter_weights; /* weight(s) for previous line(s) */
png_uint_16p inv_filter_weights; /* 1/weight(s) for previous line(s) */
png_uint_16p filter_costs; /* relative filter calculation cost */
png_uint_16p inv_filter_costs; /* 1/relative filter calculation cost */
#endif
#ifdef PNG_TIME_RFC1123_SUPPORTED
png_charp time_buffer; /* String to hold RFC 1123 time text */
#endif
/* New members added in libpng-1.0.6 */
png_uint_32 free_me; /* flags items libpng is responsible for freeing */
#ifdef PNG_USER_CHUNKS_SUPPORTED
png_voidp user_chunk_ptr;
png_user_chunk_ptr read_user_chunk_fn; /* user read chunk handler */
#endif
#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
int num_chunk_list;
png_bytep chunk_list;
#endif
/* New members added in libpng-1.0.3 */
#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
png_byte rgb_to_gray_status;
/* These were changed from png_byte in libpng-1.0.6 */
png_uint_16 rgb_to_gray_red_coeff;
png_uint_16 rgb_to_gray_green_coeff;
png_uint_16 rgb_to_gray_blue_coeff;
#endif
/* New member added in libpng-1.0.4 (renamed in 1.0.9) */
#if defined(PNG_MNG_FEATURES_SUPPORTED) || \
defined(PNG_READ_EMPTY_PLTE_SUPPORTED) || \
defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED)
/* Changed from png_byte to png_uint_32 at version 1.2.0 */
png_uint_32 mng_features_permitted;
#endif
/* New member added in libpng-1.0.9, ifdef'ed out in 1.0.12, enabled in 1.2.0 */
#ifdef PNG_MNG_FEATURES_SUPPORTED
png_byte filter_type;
#endif
/* New members added in libpng-1.2.0 */
/* New members added in libpng-1.0.2 but first enabled by default in 1.2.0 */
#ifdef PNG_USER_MEM_SUPPORTED
png_voidp mem_ptr; /* user supplied struct for mem functions */
png_malloc_ptr malloc_fn; /* function for allocating memory */
png_free_ptr free_fn; /* function for freeing memory */
#endif
/* New member added in libpng-1.0.13 and 1.2.0 */
png_bytep big_row_buf; /* buffer to save current (unfiltered) row */
#ifdef PNG_READ_QUANTIZE_SUPPORTED
/* The following three members were added at version 1.0.14 and 1.2.4 */
png_bytep quantize_sort; /* working sort array */
png_bytep index_to_palette; /* where the original index currently is
in the palette */
png_bytep palette_to_index; /* which original index points to this
palette color */
#endif
/* New members added in libpng-1.0.16 and 1.2.6 */
png_byte compression_type;
#ifdef PNG_USER_LIMITS_SUPPORTED
png_uint_32 user_width_max;
png_uint_32 user_height_max;
/* Added in libpng-1.4.0: Total number of sPLT, text, and unknown
* chunks that can be stored (0 means unlimited).
*/
png_uint_32 user_chunk_cache_max;
/* Total memory that a zTXt, sPLT, iTXt, iCCP, or unknown chunk
* can occupy when decompressed. 0 means unlimited.
*/
png_alloc_size_t user_chunk_malloc_max;
#endif
/* New member added in libpng-1.0.25 and 1.2.17 */
#ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED
/* Storage for unknown chunk that the library doesn't recognize. */
png_unknown_chunk unknown_chunk;
#endif
/* New members added in libpng-1.2.26 */
png_size_t old_big_row_buf_size;
png_size_t old_prev_row_size;
/* New member added in libpng-1.2.30 */
png_charp chunkdata; /* buffer for reading chunk data */
#ifdef PNG_IO_STATE_SUPPORTED
/* New member added in libpng-1.4.0 */
png_uint_32 io_state;
#endif
};
#endif /* PNGSTRUCT_H */

View File

@ -0,0 +1,723 @@
/* pngtrans.c - transforms the data in a row (used by both readers and writers)
*
* Last changed in libpng 1.5.1 [February 3, 2011]
* Copyright (c) 1998-2011 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
*
* This code is released under the libpng license.
* For conditions of distribution and use, see the disclaimer
* and license in png.h
*/
#include "pngpriv.h"
#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
/* Turn on BGR-to-RGB mapping */
void PNGAPI
png_set_bgr(png_structp png_ptr)
{
png_debug(1, "in png_set_bgr");
if (png_ptr == NULL)
return;
png_ptr->transformations |= PNG_BGR;
}
#endif
#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
/* Turn on 16 bit byte swapping */
void PNGAPI
png_set_swap(png_structp png_ptr)
{
png_debug(1, "in png_set_swap");
if (png_ptr == NULL)
return;
if (png_ptr->bit_depth == 16)
png_ptr->transformations |= PNG_SWAP_BYTES;
}
#endif
#if defined(PNG_READ_PACK_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED)
/* Turn on pixel packing */
void PNGAPI
png_set_packing(png_structp png_ptr)
{
png_debug(1, "in png_set_packing");
if (png_ptr == NULL)
return;
if (png_ptr->bit_depth < 8)
{
png_ptr->transformations |= PNG_PACK;
png_ptr->usr_bit_depth = 8;
}
}
#endif
#if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED)
/* Turn on packed pixel swapping */
void PNGAPI
png_set_packswap(png_structp png_ptr)
{
png_debug(1, "in png_set_packswap");
if (png_ptr == NULL)
return;
if (png_ptr->bit_depth < 8)
png_ptr->transformations |= PNG_PACKSWAP;
}
#endif
#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED)
void PNGAPI
png_set_shift(png_structp png_ptr, png_const_color_8p true_bits)
{
png_debug(1, "in png_set_shift");
if (png_ptr == NULL)
return;
png_ptr->transformations |= PNG_SHIFT;
png_ptr->shift = *true_bits;
}
#endif
#if defined(PNG_READ_INTERLACING_SUPPORTED) || \
defined(PNG_WRITE_INTERLACING_SUPPORTED)
int PNGAPI
png_set_interlace_handling(png_structp png_ptr)
{
png_debug(1, "in png_set_interlace handling");
if (png_ptr && png_ptr->interlaced)
{
png_ptr->transformations |= PNG_INTERLACE;
return (7);
}
return (1);
}
#endif
#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED)
/* Add a filler byte on read, or remove a filler or alpha byte on write.
* The filler type has changed in v0.95 to allow future 2-byte fillers
* for 48-bit input data, as well as to avoid problems with some compilers
* that don't like bytes as parameters.
*/
void PNGAPI
png_set_filler(png_structp png_ptr, png_uint_32 filler, int filler_loc)
{
png_debug(1, "in png_set_filler");
if (png_ptr == NULL)
return;
png_ptr->transformations |= PNG_FILLER;
png_ptr->filler = (png_uint_16)filler;
if (filler_loc == PNG_FILLER_AFTER)
png_ptr->flags |= PNG_FLAG_FILLER_AFTER;
else
png_ptr->flags &= ~PNG_FLAG_FILLER_AFTER;
/* This should probably go in the "do_read_filler" routine.
* I attempted to do that in libpng-1.0.1a but that caused problems
* so I restored it in libpng-1.0.2a
*/
if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
{
png_ptr->usr_channels = 4;
}
/* Also I added this in libpng-1.0.2a (what happens when we expand
* a less-than-8-bit grayscale to GA?) */
if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY && png_ptr->bit_depth >= 8)
{
png_ptr->usr_channels = 2;
}
}
/* Added to libpng-1.2.7 */
void PNGAPI
png_set_add_alpha(png_structp png_ptr, png_uint_32 filler, int filler_loc)
{
png_debug(1, "in png_set_add_alpha");
if (png_ptr == NULL)
return;
png_set_filler(png_ptr, filler, filler_loc);
png_ptr->transformations |= PNG_ADD_ALPHA;
}
#endif
#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || \
defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
void PNGAPI
png_set_swap_alpha(png_structp png_ptr)
{
png_debug(1, "in png_set_swap_alpha");
if (png_ptr == NULL)
return;
png_ptr->transformations |= PNG_SWAP_ALPHA;
}
#endif
#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) || \
defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
void PNGAPI
png_set_invert_alpha(png_structp png_ptr)
{
png_debug(1, "in png_set_invert_alpha");
if (png_ptr == NULL)
return;
png_ptr->transformations |= PNG_INVERT_ALPHA;
}
#endif
#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED)
void PNGAPI
png_set_invert_mono(png_structp png_ptr)
{
png_debug(1, "in png_set_invert_mono");
if (png_ptr == NULL)
return;
png_ptr->transformations |= PNG_INVERT_MONO;
}
/* Invert monochrome grayscale data */
void /* PRIVATE */
png_do_invert(png_row_infop row_info, png_bytep row)
{
png_debug(1, "in png_do_invert");
/* This test removed from libpng version 1.0.13 and 1.2.0:
* if (row_info->bit_depth == 1 &&
*/
if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
{
png_bytep rp = row;
png_size_t i;
png_size_t istop = row_info->rowbytes;
for (i = 0; i < istop; i++)
{
*rp = (png_byte)(~(*rp));
rp++;
}
}
else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA &&
row_info->bit_depth == 8)
{
png_bytep rp = row;
png_size_t i;
png_size_t istop = row_info->rowbytes;
for (i = 0; i < istop; i += 2)
{
*rp = (png_byte)(~(*rp));
rp += 2;
}
}
#ifdef PNG_16BIT_SUPPORTED
else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA &&
row_info->bit_depth == 16)
{
png_bytep rp = row;
png_size_t i;
png_size_t istop = row_info->rowbytes;
for (i = 0; i < istop; i += 4)
{
*rp = (png_byte)(~(*rp));
*(rp + 1) = (png_byte)(~(*(rp + 1)));
rp += 4;
}
}
#endif
}
#endif
#ifdef PNG_16BIT_SUPPORTED
#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
/* Swaps byte order on 16 bit depth images */
void /* PRIVATE */
png_do_swap(png_row_infop row_info, png_bytep row)
{
png_debug(1, "in png_do_swap");
if (row_info->bit_depth == 16)
{
png_bytep rp = row;
png_uint_32 i;
png_uint_32 istop= row_info->width * row_info->channels;
for (i = 0; i < istop; i++, rp += 2)
{
png_byte t = *rp;
*rp = *(rp + 1);
*(rp + 1) = t;
}
}
}
#endif
#endif
#if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED)
static PNG_CONST png_byte onebppswaptable[256] = {
0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0,
0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0,
0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8,
0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8,
0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4,
0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4,
0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC,
0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC,
0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2,
0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2,
0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA,
0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,
0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6,
0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6,
0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE,
0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE,
0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1,
0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,
0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9,
0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9,
0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5,
0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5,
0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED,
0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,
0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3,
0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3,
0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB,
0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB,
0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7,
0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7,
0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF,
0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF
};
static PNG_CONST png_byte twobppswaptable[256] = {
0x00, 0x40, 0x80, 0xC0, 0x10, 0x50, 0x90, 0xD0,
0x20, 0x60, 0xA0, 0xE0, 0x30, 0x70, 0xB0, 0xF0,
0x04, 0x44, 0x84, 0xC4, 0x14, 0x54, 0x94, 0xD4,
0x24, 0x64, 0xA4, 0xE4, 0x34, 0x74, 0xB4, 0xF4,
0x08, 0x48, 0x88, 0xC8, 0x18, 0x58, 0x98, 0xD8,
0x28, 0x68, 0xA8, 0xE8, 0x38, 0x78, 0xB8, 0xF8,
0x0C, 0x4C, 0x8C, 0xCC, 0x1C, 0x5C, 0x9C, 0xDC,
0x2C, 0x6C, 0xAC, 0xEC, 0x3C, 0x7C, 0xBC, 0xFC,
0x01, 0x41, 0x81, 0xC1, 0x11, 0x51, 0x91, 0xD1,
0x21, 0x61, 0xA1, 0xE1, 0x31, 0x71, 0xB1, 0xF1,
0x05, 0x45, 0x85, 0xC5, 0x15, 0x55, 0x95, 0xD5,
0x25, 0x65, 0xA5, 0xE5, 0x35, 0x75, 0xB5, 0xF5,
0x09, 0x49, 0x89, 0xC9, 0x19, 0x59, 0x99, 0xD9,
0x29, 0x69, 0xA9, 0xE9, 0x39, 0x79, 0xB9, 0xF9,
0x0D, 0x4D, 0x8D, 0xCD, 0x1D, 0x5D, 0x9D, 0xDD,
0x2D, 0x6D, 0xAD, 0xED, 0x3D, 0x7D, 0xBD, 0xFD,
0x02, 0x42, 0x82, 0xC2, 0x12, 0x52, 0x92, 0xD2,
0x22, 0x62, 0xA2, 0xE2, 0x32, 0x72, 0xB2, 0xF2,
0x06, 0x46, 0x86, 0xC6, 0x16, 0x56, 0x96, 0xD6,
0x26, 0x66, 0xA6, 0xE6, 0x36, 0x76, 0xB6, 0xF6,
0x0A, 0x4A, 0x8A, 0xCA, 0x1A, 0x5A, 0x9A, 0xDA,
0x2A, 0x6A, 0xAA, 0xEA, 0x3A, 0x7A, 0xBA, 0xFA,
0x0E, 0x4E, 0x8E, 0xCE, 0x1E, 0x5E, 0x9E, 0xDE,
0x2E, 0x6E, 0xAE, 0xEE, 0x3E, 0x7E, 0xBE, 0xFE,
0x03, 0x43, 0x83, 0xC3, 0x13, 0x53, 0x93, 0xD3,
0x23, 0x63, 0xA3, 0xE3, 0x33, 0x73, 0xB3, 0xF3,
0x07, 0x47, 0x87, 0xC7, 0x17, 0x57, 0x97, 0xD7,
0x27, 0x67, 0xA7, 0xE7, 0x37, 0x77, 0xB7, 0xF7,
0x0B, 0x4B, 0x8B, 0xCB, 0x1B, 0x5B, 0x9B, 0xDB,
0x2B, 0x6B, 0xAB, 0xEB, 0x3B, 0x7B, 0xBB, 0xFB,
0x0F, 0x4F, 0x8F, 0xCF, 0x1F, 0x5F, 0x9F, 0xDF,
0x2F, 0x6F, 0xAF, 0xEF, 0x3F, 0x7F, 0xBF, 0xFF
};
static PNG_CONST png_byte fourbppswaptable[256] = {
0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70,
0x80, 0x90, 0xA0, 0xB0, 0xC0, 0xD0, 0xE0, 0xF0,
0x01, 0x11, 0x21, 0x31, 0x41, 0x51, 0x61, 0x71,
0x81, 0x91, 0xA1, 0xB1, 0xC1, 0xD1, 0xE1, 0xF1,
0x02, 0x12, 0x22, 0x32, 0x42, 0x52, 0x62, 0x72,
0x82, 0x92, 0xA2, 0xB2, 0xC2, 0xD2, 0xE2, 0xF2,
0x03, 0x13, 0x23, 0x33, 0x43, 0x53, 0x63, 0x73,
0x83, 0x93, 0xA3, 0xB3, 0xC3, 0xD3, 0xE3, 0xF3,
0x04, 0x14, 0x24, 0x34, 0x44, 0x54, 0x64, 0x74,
0x84, 0x94, 0xA4, 0xB4, 0xC4, 0xD4, 0xE4, 0xF4,
0x05, 0x15, 0x25, 0x35, 0x45, 0x55, 0x65, 0x75,
0x85, 0x95, 0xA5, 0xB5, 0xC5, 0xD5, 0xE5, 0xF5,
0x06, 0x16, 0x26, 0x36, 0x46, 0x56, 0x66, 0x76,
0x86, 0x96, 0xA6, 0xB6, 0xC6, 0xD6, 0xE6, 0xF6,
0x07, 0x17, 0x27, 0x37, 0x47, 0x57, 0x67, 0x77,
0x87, 0x97, 0xA7, 0xB7, 0xC7, 0xD7, 0xE7, 0xF7,
0x08, 0x18, 0x28, 0x38, 0x48, 0x58, 0x68, 0x78,
0x88, 0x98, 0xA8, 0xB8, 0xC8, 0xD8, 0xE8, 0xF8,
0x09, 0x19, 0x29, 0x39, 0x49, 0x59, 0x69, 0x79,
0x89, 0x99, 0xA9, 0xB9, 0xC9, 0xD9, 0xE9, 0xF9,
0x0A, 0x1A, 0x2A, 0x3A, 0x4A, 0x5A, 0x6A, 0x7A,
0x8A, 0x9A, 0xAA, 0xBA, 0xCA, 0xDA, 0xEA, 0xFA,
0x0B, 0x1B, 0x2B, 0x3B, 0x4B, 0x5B, 0x6B, 0x7B,
0x8B, 0x9B, 0xAB, 0xBB, 0xCB, 0xDB, 0xEB, 0xFB,
0x0C, 0x1C, 0x2C, 0x3C, 0x4C, 0x5C, 0x6C, 0x7C,
0x8C, 0x9C, 0xAC, 0xBC, 0xCC, 0xDC, 0xEC, 0xFC,
0x0D, 0x1D, 0x2D, 0x3D, 0x4D, 0x5D, 0x6D, 0x7D,
0x8D, 0x9D, 0xAD, 0xBD, 0xCD, 0xDD, 0xED, 0xFD,
0x0E, 0x1E, 0x2E, 0x3E, 0x4E, 0x5E, 0x6E, 0x7E,
0x8E, 0x9E, 0xAE, 0xBE, 0xCE, 0xDE, 0xEE, 0xFE,
0x0F, 0x1F, 0x2F, 0x3F, 0x4F, 0x5F, 0x6F, 0x7F,
0x8F, 0x9F, 0xAF, 0xBF, 0xCF, 0xDF, 0xEF, 0xFF
};
/* Swaps pixel packing order within bytes */
void /* PRIVATE */
png_do_packswap(png_row_infop row_info, png_bytep row)
{
png_debug(1, "in png_do_packswap");
if (row_info->bit_depth < 8)
{
png_bytep rp;
png_const_bytep end, table;
end = row + row_info->rowbytes;
if (row_info->bit_depth == 1)
table = onebppswaptable;
else if (row_info->bit_depth == 2)
table = twobppswaptable;
else if (row_info->bit_depth == 4)
table = fourbppswaptable;
else
return;
for (rp = row; rp < end; rp++)
*rp = table[*rp];
}
}
#endif /* PNG_READ_PACKSWAP_SUPPORTED or PNG_WRITE_PACKSWAP_SUPPORTED */
#if defined(PNG_WRITE_FILLER_SUPPORTED) || \
defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
/* Remove filler or alpha byte(s) */
void /* PRIVATE */
png_do_strip_filler(png_row_infop row_info, png_bytep row, png_uint_32 flags)
{
png_debug(1, "in png_do_strip_filler");
{
png_bytep sp = row;
png_bytep dp = row;
png_uint_32 row_width = row_info->width;
png_uint_32 i;
if ((row_info->color_type == PNG_COLOR_TYPE_RGB ||
(row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA &&
(flags & PNG_FLAG_STRIP_ALPHA))) &&
row_info->channels == 4)
{
if (row_info->bit_depth == 8)
{
/* This converts from RGBX or RGBA to RGB */
if (flags & PNG_FLAG_FILLER_AFTER)
{
dp += 3; sp += 4;
for (i = 1; i < row_width; i++)
{
*dp++ = *sp++;
*dp++ = *sp++;
*dp++ = *sp++;
sp++;
}
}
/* This converts from XRGB or ARGB to RGB */
else
{
for (i = 0; i < row_width; i++)
{
sp++;
*dp++ = *sp++;
*dp++ = *sp++;
*dp++ = *sp++;
}
}
row_info->pixel_depth = 24;
row_info->rowbytes = row_width * 3;
}
else /* if (row_info->bit_depth == 16) */
{
if (flags & PNG_FLAG_FILLER_AFTER)
{
/* This converts from RRGGBBXX or RRGGBBAA to RRGGBB */
sp += 8; dp += 6;
for (i = 1; i < row_width; i++)
{
/* This could be (although png_memcpy is probably slower):
png_memcpy(dp, sp, 6);
sp += 8;
dp += 6;
*/
*dp++ = *sp++;
*dp++ = *sp++;
*dp++ = *sp++;
*dp++ = *sp++;
*dp++ = *sp++;
*dp++ = *sp++;
sp += 2;
}
}
else
{
/* This converts from XXRRGGBB or AARRGGBB to RRGGBB */
for (i = 0; i < row_width; i++)
{
/* This could be (although png_memcpy is probably slower):
png_memcpy(dp, sp, 6);
sp += 8;
dp += 6;
*/
sp += 2;
*dp++ = *sp++;
*dp++ = *sp++;
*dp++ = *sp++;
*dp++ = *sp++;
*dp++ = *sp++;
*dp++ = *sp++;
}
}
row_info->pixel_depth = 48;
row_info->rowbytes = row_width * 6;
}
row_info->channels = 3;
}
else if ((row_info->color_type == PNG_COLOR_TYPE_GRAY ||
(row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA &&
(flags & PNG_FLAG_STRIP_ALPHA))) &&
row_info->channels == 2)
{
if (row_info->bit_depth == 8)
{
if (flags & PNG_FLAG_FILLER_AFTER)
{
/* This converts from GX or GA to G */
for (i = 0; i < row_width; i++)
{
*dp++ = *sp++;
sp++;
}
}
else
{
/* This converts from XG or AG to G */
for (i = 0; i < row_width; i++)
{
sp++;
*dp++ = *sp++;
}
}
row_info->pixel_depth = 8;
row_info->rowbytes = row_width;
}
else /* if (row_info->bit_depth == 16) */
{
if (flags & PNG_FLAG_FILLER_AFTER)
{
/* This converts from GGXX or GGAA to GG */
sp += 4; dp += 2;
for (i = 1; i < row_width; i++)
{
*dp++ = *sp++;
*dp++ = *sp++;
sp += 2;
}
}
else
{
/* This converts from XXGG or AAGG to GG */
for (i = 0; i < row_width; i++)
{
sp += 2;
*dp++ = *sp++;
*dp++ = *sp++;
}
}
row_info->pixel_depth = 16;
row_info->rowbytes = row_width * 2;
}
row_info->channels = 1;
}
if (flags & PNG_FLAG_STRIP_ALPHA)
row_info->color_type = (png_byte)(row_info->color_type &
~PNG_COLOR_MASK_ALPHA);
}
}
#endif
#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
/* Swaps red and blue bytes within a pixel */
void /* PRIVATE */
png_do_bgr(png_row_infop row_info, png_bytep row)
{
png_debug(1, "in png_do_bgr");
if ((row_info->color_type & PNG_COLOR_MASK_COLOR))
{
png_uint_32 row_width = row_info->width;
if (row_info->bit_depth == 8)
{
if (row_info->color_type == PNG_COLOR_TYPE_RGB)
{
png_bytep rp;
png_uint_32 i;
for (i = 0, rp = row; i < row_width; i++, rp += 3)
{
png_byte save = *rp;
*rp = *(rp + 2);
*(rp + 2) = save;
}
}
else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
{
png_bytep rp;
png_uint_32 i;
for (i = 0, rp = row; i < row_width; i++, rp += 4)
{
png_byte save = *rp;
*rp = *(rp + 2);
*(rp + 2) = save;
}
}
}
#ifdef PNG_16BIT_SUPPORTED
else if (row_info->bit_depth == 16)
{
if (row_info->color_type == PNG_COLOR_TYPE_RGB)
{
png_bytep rp;
png_uint_32 i;
for (i = 0, rp = row; i < row_width; i++, rp += 6)
{
png_byte save = *rp;
*rp = *(rp + 4);
*(rp + 4) = save;
save = *(rp + 1);
*(rp + 1) = *(rp + 5);
*(rp + 5) = save;
}
}
else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
{
png_bytep rp;
png_uint_32 i;
for (i = 0, rp = row; i < row_width; i++, rp += 8)
{
png_byte save = *rp;
*rp = *(rp + 4);
*(rp + 4) = save;
save = *(rp + 1);
*(rp + 1) = *(rp + 5);
*(rp + 5) = save;
}
}
}
#endif
}
}
#endif /* PNG_READ_BGR_SUPPORTED or PNG_WRITE_BGR_SUPPORTED */
#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED
void PNGAPI
png_set_user_transform_info(png_structp png_ptr, png_voidp
user_transform_ptr, int user_transform_depth, int user_transform_channels)
{
png_debug(1, "in png_set_user_transform_info");
if (png_ptr == NULL)
return;
png_ptr->user_transform_ptr = user_transform_ptr;
png_ptr->user_transform_depth = (png_byte)user_transform_depth;
png_ptr->user_transform_channels = (png_byte)user_transform_channels;
}
#endif
/* This function returns a pointer to the user_transform_ptr associated with
* the user transform functions. The application should free any memory
* associated with this pointer before png_write_destroy and png_read_destroy
* are called.
*/
#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED
png_voidp PNGAPI
png_get_user_transform_ptr(png_const_structp png_ptr)
{
if (png_ptr == NULL)
return (NULL);
return ((png_voidp)png_ptr->user_transform_ptr);
}
#endif
png_uint_32 PNGAPI
png_get_current_row_number(png_const_structp png_ptr)
{
if (png_ptr != NULL)
return png_ptr->row_number;
return PNG_UINT_32_MAX; /* help the app not to fail silently */
}
png_byte PNGAPI
png_get_current_pass_number(png_const_structp png_ptr)
{
if (png_ptr != NULL)
return png_ptr->pass;
return 8; /* invalid */
}
#endif /* PNG_READ_USER_TRANSFORM_SUPPORTED ||
PNG_WRITE_USER_TRANSFORM_SUPPORTED */
#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */

View File

@ -0,0 +1,254 @@
/* pngwio.c - functions for data output
*
* Last changed in libpng 1.5.0 [January 6, 2011]
* Copyright (c) 1998-2011 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
*
* This code is released under the libpng license.
* For conditions of distribution and use, see the disclaimer
* and license in png.h
*
* This file provides a location for all output. Users who need
* special handling are expected to write functions that have the same
* arguments as these and perform similar functions, but that possibly
* use different output methods. Note that you shouldn't change these
* functions, but rather write replacement functions and then change
* them at run time with png_set_write_fn(...).
*/
#include "pngpriv.h"
#ifdef PNG_WRITE_SUPPORTED
/* Write the data to whatever output you are using. The default routine
* writes to a file pointer. Note that this routine sometimes gets called
* with very small lengths, so you should implement some kind of simple
* buffering if you are using unbuffered writes. This should never be asked
* to write more than 64K on a 16 bit machine.
*/
void /* PRIVATE */
png_write_data(png_structp png_ptr, png_const_bytep data, png_size_t length)
{
/* NOTE: write_data_fn must not change the buffer! */
if (png_ptr->write_data_fn != NULL )
(*(png_ptr->write_data_fn))(png_ptr, (png_bytep)data, length);
else
png_error(png_ptr, "Call to NULL write function");
}
#ifdef PNG_STDIO_SUPPORTED
/* This is the function that does the actual writing of data. If you are
* not writing to a standard C stream, you should create a replacement
* write_data function and use it at run time with png_set_write_fn(), rather
* than changing the library.
*/
#ifndef USE_FAR_KEYWORD
void PNGCBAPI
png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
{
png_size_t check;
if (png_ptr == NULL)
return;
check = fwrite(data, 1, length, (png_FILE_p)(png_ptr->io_ptr));
if (check != length)
png_error(png_ptr, "Write Error");
}
#else
/* This is the model-independent version. Since the standard I/O library
* can't handle far buffers in the medium and small models, we have to copy
* the data.
*/
#define NEAR_BUF_SIZE 1024
#define MIN(a,b) (a <= b ? a : b)
void PNGCBAPI
png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
{
png_uint_32 check;
png_byte *near_data; /* Needs to be "png_byte *" instead of "png_bytep" */
png_FILE_p io_ptr;
if (png_ptr == NULL)
return;
/* Check if data really is near. If so, use usual code. */
near_data = (png_byte *)CVT_PTR_NOCHECK(data);
io_ptr = (png_FILE_p)CVT_PTR(png_ptr->io_ptr);
if ((png_bytep)near_data == data)
{
check = fwrite(near_data, 1, length, io_ptr);
}
else
{
png_byte buf[NEAR_BUF_SIZE];
png_size_t written, remaining, err;
check = 0;
remaining = length;
do
{
written = MIN(NEAR_BUF_SIZE, remaining);
png_memcpy(buf, data, written); /* Copy far buffer to near buffer */
err = fwrite(buf, 1, written, io_ptr);
if (err != written)
break;
else
check += err;
data += written;
remaining -= written;
}
while (remaining != 0);
}
if (check != length)
png_error(png_ptr, "Write Error");
}
#endif
#endif
/* This function is called to output any data pending writing (normally
* to disk). After png_flush is called, there should be no data pending
* writing in any buffers.
*/
#ifdef PNG_WRITE_FLUSH_SUPPORTED
void /* PRIVATE */
png_flush(png_structp png_ptr)
{
if (png_ptr->output_flush_fn != NULL)
(*(png_ptr->output_flush_fn))(png_ptr);
}
# ifdef PNG_STDIO_SUPPORTED
void PNGCBAPI
png_default_flush(png_structp png_ptr)
{
png_FILE_p io_ptr;
if (png_ptr == NULL)
return;
io_ptr = (png_FILE_p)CVT_PTR((png_ptr->io_ptr));
fflush(io_ptr);
}
# endif
#endif
/* This function allows the application to supply new output functions for
* libpng if standard C streams aren't being used.
*
* This function takes as its arguments:
* png_ptr - pointer to a png output data structure
* io_ptr - pointer to user supplied structure containing info about
* the output functions. May be NULL.
* write_data_fn - pointer to a new output function that takes as its
* arguments a pointer to a png_struct, a pointer to
* data to be written, and a 32-bit unsigned int that is
* the number of bytes to be written. The new write
* function should call png_error(png_ptr, "Error msg")
* to exit and output any fatal error messages. May be
* NULL, in which case libpng's default function will
* be used.
* flush_data_fn - pointer to a new flush function that takes as its
* arguments a pointer to a png_struct. After a call to
* the flush function, there should be no data in any buffers
* or pending transmission. If the output method doesn't do
* any buffering of output, a function prototype must still be
* supplied although it doesn't have to do anything. If
* PNG_WRITE_FLUSH_SUPPORTED is not defined at libpng compile
* time, output_flush_fn will be ignored, although it must be
* supplied for compatibility. May be NULL, in which case
* libpng's default function will be used, if
* PNG_WRITE_FLUSH_SUPPORTED is defined. This is not
* a good idea if io_ptr does not point to a standard
* *FILE structure.
*/
void PNGAPI
png_set_write_fn(png_structp png_ptr, png_voidp io_ptr,
png_rw_ptr write_data_fn, png_flush_ptr output_flush_fn)
{
if (png_ptr == NULL)
return;
png_ptr->io_ptr = io_ptr;
#ifdef PNG_STDIO_SUPPORTED
if (write_data_fn != NULL)
png_ptr->write_data_fn = write_data_fn;
else
png_ptr->write_data_fn = png_default_write_data;
#else
png_ptr->write_data_fn = write_data_fn;
#endif
#ifdef PNG_WRITE_FLUSH_SUPPORTED
# ifdef PNG_STDIO_SUPPORTED
if (output_flush_fn != NULL)
png_ptr->output_flush_fn = output_flush_fn;
else
png_ptr->output_flush_fn = png_default_flush;
# else
png_ptr->output_flush_fn = output_flush_fn;
# endif
#endif /* PNG_WRITE_FLUSH_SUPPORTED */
/* It is an error to read while writing a png file */
if (png_ptr->read_data_fn != NULL)
{
png_ptr->read_data_fn = NULL;
png_warning(png_ptr,
"Can't set both read_data_fn and write_data_fn in the"
" same structure");
}
}
#ifdef USE_FAR_KEYWORD
# ifdef _MSC_VER
void *png_far_to_near(png_structp png_ptr, png_voidp ptr, int check)
{
void *near_ptr;
void FAR *far_ptr;
FP_OFF(near_ptr) = FP_OFF(ptr);
far_ptr = (void FAR *)near_ptr;
if (check != 0)
if (FP_SEG(ptr) != FP_SEG(far_ptr))
png_error(png_ptr, "segment lost in conversion");
return(near_ptr);
}
# else
void *png_far_to_near(png_structp png_ptr, png_voidp ptr, int check)
{
void *near_ptr;
void FAR *far_ptr;
near_ptr = (void FAR *)ptr;
far_ptr = (void FAR *)near_ptr;
if (check != 0)
if (far_ptr != ptr)
png_error(png_ptr, "segment lost in conversion");
return(near_ptr);
}
# endif
#endif
#endif /* PNG_WRITE_SUPPORTED */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,631 @@
/* pngwtran.c - transforms the data in a row for PNG writers
*
* Last changed in libpng 1.5.0 [January 6, 2011]
* Copyright (c) 1998-2011 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
*
* This code is released under the libpng license.
* For conditions of distribution and use, see the disclaimer
* and license in png.h
*/
#include "pngpriv.h"
#ifdef PNG_WRITE_SUPPORTED
/* Transform the data according to the user's wishes. The order of
* transformations is significant.
*/
void /* PRIVATE */
png_do_write_transformations(png_structp png_ptr)
{
png_debug(1, "in png_do_write_transformations");
if (png_ptr == NULL)
return;
#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED
if (png_ptr->transformations & PNG_USER_TRANSFORM)
if (png_ptr->write_user_transform_fn != NULL)
(*(png_ptr->write_user_transform_fn)) /* User write transform
function */
(png_ptr, /* png_ptr */
&(png_ptr->row_info), /* row_info: */
/* png_uint_32 width; width of row */
/* png_size_t rowbytes; number of bytes in row */
/* png_byte color_type; color type of pixels */
/* png_byte bit_depth; bit depth of samples */
/* png_byte channels; number of channels (1-4) */
/* png_byte pixel_depth; bits per pixel (depth*channels) */
png_ptr->row_buf + 1); /* start of pixel data for row */
#endif
#ifdef PNG_WRITE_FILLER_SUPPORTED
if (png_ptr->transformations & PNG_FILLER)
png_do_strip_filler(&(png_ptr->row_info), png_ptr->row_buf + 1,
png_ptr->flags);
#endif
#ifdef PNG_WRITE_PACKSWAP_SUPPORTED
if (png_ptr->transformations & PNG_PACKSWAP)
png_do_packswap(&(png_ptr->row_info), png_ptr->row_buf + 1);
#endif
#ifdef PNG_WRITE_PACK_SUPPORTED
if (png_ptr->transformations & PNG_PACK)
png_do_pack(&(png_ptr->row_info), png_ptr->row_buf + 1,
(png_uint_32)png_ptr->bit_depth);
#endif
#ifdef PNG_WRITE_SWAP_SUPPORTED
if (png_ptr->transformations & PNG_SWAP_BYTES)
png_do_swap(&(png_ptr->row_info), png_ptr->row_buf + 1);
#endif
#ifdef PNG_WRITE_SHIFT_SUPPORTED
if (png_ptr->transformations & PNG_SHIFT)
png_do_shift(&(png_ptr->row_info), png_ptr->row_buf + 1,
&(png_ptr->shift));
#endif
#ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED
if (png_ptr->transformations & PNG_SWAP_ALPHA)
png_do_write_swap_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1);
#endif
#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED
if (png_ptr->transformations & PNG_INVERT_ALPHA)
png_do_write_invert_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1);
#endif
#ifdef PNG_WRITE_BGR_SUPPORTED
if (png_ptr->transformations & PNG_BGR)
png_do_bgr(&(png_ptr->row_info), png_ptr->row_buf + 1);
#endif
#ifdef PNG_WRITE_INVERT_SUPPORTED
if (png_ptr->transformations & PNG_INVERT_MONO)
png_do_invert(&(png_ptr->row_info), png_ptr->row_buf + 1);
#endif
}
#ifdef PNG_WRITE_PACK_SUPPORTED
/* Pack pixels into bytes. Pass the true bit depth in bit_depth. The
* row_info bit depth should be 8 (one pixel per byte). The channels
* should be 1 (this only happens on grayscale and paletted images).
*/
void /* PRIVATE */
png_do_pack(png_row_infop row_info, png_bytep row, png_uint_32 bit_depth)
{
png_debug(1, "in png_do_pack");
if (row_info->bit_depth == 8 &&
row_info->channels == 1)
{
switch ((int)bit_depth)
{
case 1:
{
png_bytep sp, dp;
int mask, v;
png_uint_32 i;
png_uint_32 row_width = row_info->width;
sp = row;
dp = row;
mask = 0x80;
v = 0;
for (i = 0; i < row_width; i++)
{
if (*sp != 0)
v |= mask;
sp++;
if (mask > 1)
mask >>= 1;
else
{
mask = 0x80;
*dp = (png_byte)v;
dp++;
v = 0;
}
}
if (mask != 0x80)
*dp = (png_byte)v;
break;
}
case 2:
{
png_bytep sp, dp;
int shift, v;
png_uint_32 i;
png_uint_32 row_width = row_info->width;
sp = row;
dp = row;
shift = 6;
v = 0;
for (i = 0; i < row_width; i++)
{
png_byte value;
value = (png_byte)(*sp & 0x03);
v |= (value << shift);
if (shift == 0)
{
shift = 6;
*dp = (png_byte)v;
dp++;
v = 0;
}
else
shift -= 2;
sp++;
}
if (shift != 6)
*dp = (png_byte)v;
break;
}
case 4:
{
png_bytep sp, dp;
int shift, v;
png_uint_32 i;
png_uint_32 row_width = row_info->width;
sp = row;
dp = row;
shift = 4;
v = 0;
for (i = 0; i < row_width; i++)
{
png_byte value;
value = (png_byte)(*sp & 0x0f);
v |= (value << shift);
if (shift == 0)
{
shift = 4;
*dp = (png_byte)v;
dp++;
v = 0;
}
else
shift -= 4;
sp++;
}
if (shift != 4)
*dp = (png_byte)v;
break;
}
default:
break;
}
row_info->bit_depth = (png_byte)bit_depth;
row_info->pixel_depth = (png_byte)(bit_depth * row_info->channels);
row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,
row_info->width);
}
}
#endif
#ifdef PNG_WRITE_SHIFT_SUPPORTED
/* Shift pixel values to take advantage of whole range. Pass the
* true number of bits in bit_depth. The row should be packed
* according to row_info->bit_depth. Thus, if you had a row of
* bit depth 4, but the pixels only had values from 0 to 7, you
* would pass 3 as bit_depth, and this routine would translate the
* data to 0 to 15.
*/
void /* PRIVATE */
png_do_shift(png_row_infop row_info, png_bytep row,
png_const_color_8p bit_depth)
{
png_debug(1, "in png_do_shift");
if (row_info->color_type != PNG_COLOR_TYPE_PALETTE)
{
int shift_start[4], shift_dec[4];
int channels = 0;
if (row_info->color_type & PNG_COLOR_MASK_COLOR)
{
shift_start[channels] = row_info->bit_depth - bit_depth->red;
shift_dec[channels] = bit_depth->red;
channels++;
shift_start[channels] = row_info->bit_depth - bit_depth->green;
shift_dec[channels] = bit_depth->green;
channels++;
shift_start[channels] = row_info->bit_depth - bit_depth->blue;
shift_dec[channels] = bit_depth->blue;
channels++;
}
else
{
shift_start[channels] = row_info->bit_depth - bit_depth->gray;
shift_dec[channels] = bit_depth->gray;
channels++;
}
if (row_info->color_type & PNG_COLOR_MASK_ALPHA)
{
shift_start[channels] = row_info->bit_depth - bit_depth->alpha;
shift_dec[channels] = bit_depth->alpha;
channels++;
}
/* With low row depths, could only be grayscale, so one channel */
if (row_info->bit_depth < 8)
{
png_bytep bp = row;
png_size_t i;
png_byte mask;
png_size_t row_bytes = row_info->rowbytes;
if (bit_depth->gray == 1 && row_info->bit_depth == 2)
mask = 0x55;
else if (row_info->bit_depth == 4 && bit_depth->gray == 3)
mask = 0x11;
else
mask = 0xff;
for (i = 0; i < row_bytes; i++, bp++)
{
png_uint_16 v;
int j;
v = *bp;
*bp = 0;
for (j = shift_start[0]; j > -shift_dec[0]; j -= shift_dec[0])
{
if (j > 0)
*bp |= (png_byte)((v << j) & 0xff);
else
*bp |= (png_byte)((v >> (-j)) & mask);
}
}
}
else if (row_info->bit_depth == 8)
{
png_bytep bp = row;
png_uint_32 i;
png_uint_32 istop = channels * row_info->width;
for (i = 0; i < istop; i++, bp++)
{
png_uint_16 v;
int j;
int c = (int)(i%channels);
v = *bp;
*bp = 0;
for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c])
{
if (j > 0)
*bp |= (png_byte)((v << j) & 0xff);
else
*bp |= (png_byte)((v >> (-j)) & 0xff);
}
}
}
else
{
png_bytep bp;
png_uint_32 i;
png_uint_32 istop = channels * row_info->width;
for (bp = row, i = 0; i < istop; i++)
{
int c = (int)(i%channels);
png_uint_16 value, v;
int j;
v = (png_uint_16)(((png_uint_16)(*bp) << 8) + *(bp + 1));
value = 0;
for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c])
{
if (j > 0)
value |= (png_uint_16)((v << j) & (png_uint_16)0xffff);
else
value |= (png_uint_16)((v >> (-j)) & (png_uint_16)0xffff);
}
*bp++ = (png_byte)(value >> 8);
*bp++ = (png_byte)(value & 0xff);
}
}
}
}
#endif
#ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED
void /* PRIVATE */
png_do_write_swap_alpha(png_row_infop row_info, png_bytep row)
{
png_debug(1, "in png_do_write_swap_alpha");
{
if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
{
if (row_info->bit_depth == 8)
{
/* This converts from ARGB to RGBA */
png_bytep sp, dp;
png_uint_32 i;
png_uint_32 row_width = row_info->width;
for (i = 0, sp = dp = row; i < row_width; i++)
{
png_byte save = *(sp++);
*(dp++) = *(sp++);
*(dp++) = *(sp++);
*(dp++) = *(sp++);
*(dp++) = save;
}
}
#ifdef PNG_WRITE_16BIT_SUPPORTED
else
{
/* This converts from AARRGGBB to RRGGBBAA */
png_bytep sp, dp;
png_uint_32 i;
png_uint_32 row_width = row_info->width;
for (i = 0, sp = dp = row; i < row_width; i++)
{
png_byte save[2];
save[0] = *(sp++);
save[1] = *(sp++);
*(dp++) = *(sp++);
*(dp++) = *(sp++);
*(dp++) = *(sp++);
*(dp++) = *(sp++);
*(dp++) = *(sp++);
*(dp++) = *(sp++);
*(dp++) = save[0];
*(dp++) = save[1];
}
}
#endif /* PNG_WRITE_16BIT_SUPPORTED */
}
else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
{
if (row_info->bit_depth == 8)
{
/* This converts from AG to GA */
png_bytep sp, dp;
png_uint_32 i;
png_uint_32 row_width = row_info->width;
for (i = 0, sp = dp = row; i < row_width; i++)
{
png_byte save = *(sp++);
*(dp++) = *(sp++);
*(dp++) = save;
}
}
#ifdef PNG_WRITE_16BIT_SUPPORTED
else
{
/* This converts from AAGG to GGAA */
png_bytep sp, dp;
png_uint_32 i;
png_uint_32 row_width = row_info->width;
for (i = 0, sp = dp = row; i < row_width; i++)
{
png_byte save[2];
save[0] = *(sp++);
save[1] = *(sp++);
*(dp++) = *(sp++);
*(dp++) = *(sp++);
*(dp++) = save[0];
*(dp++) = save[1];
}
}
#endif /* PNG_WRITE_16BIT_SUPPORTED */
}
}
}
#endif
#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED
void /* PRIVATE */
png_do_write_invert_alpha(png_row_infop row_info, png_bytep row)
{
png_debug(1, "in png_do_write_invert_alpha");
{
if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
{
if (row_info->bit_depth == 8)
{
/* This inverts the alpha channel in RGBA */
png_bytep sp, dp;
png_uint_32 i;
png_uint_32 row_width = row_info->width;
for (i = 0, sp = dp = row; i < row_width; i++)
{
/* Does nothing
*(dp++) = *(sp++);
*(dp++) = *(sp++);
*(dp++) = *(sp++);
*/
sp+=3; dp = sp;
*(dp++) = (png_byte)(255 - *(sp++));
}
}
#ifdef PNG_WRITE_16BIT_SUPPORTED
else
{
/* This inverts the alpha channel in RRGGBBAA */
png_bytep sp, dp;
png_uint_32 i;
png_uint_32 row_width = row_info->width;
for (i = 0, sp = dp = row; i < row_width; i++)
{
/* Does nothing
*(dp++) = *(sp++);
*(dp++) = *(sp++);
*(dp++) = *(sp++);
*(dp++) = *(sp++);
*(dp++) = *(sp++);
*(dp++) = *(sp++);
*/
sp+=6; dp = sp;
*(dp++) = (png_byte)(255 - *(sp++));
*(dp++) = (png_byte)(255 - *(sp++));
}
}
#endif /* PNG_WRITE_16BIT_SUPPORTED */
}
else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
{
if (row_info->bit_depth == 8)
{
/* This inverts the alpha channel in GA */
png_bytep sp, dp;
png_uint_32 i;
png_uint_32 row_width = row_info->width;
for (i = 0, sp = dp = row; i < row_width; i++)
{
*(dp++) = *(sp++);
*(dp++) = (png_byte)(255 - *(sp++));
}
}
#ifdef PNG_WRITE_16BIT_SUPPORTED
else
{
/* This inverts the alpha channel in GGAA */
png_bytep sp, dp;
png_uint_32 i;
png_uint_32 row_width = row_info->width;
for (i = 0, sp = dp = row; i < row_width; i++)
{
/* Does nothing
*(dp++) = *(sp++);
*(dp++) = *(sp++);
*/
sp+=2; dp = sp;
*(dp++) = (png_byte)(255 - *(sp++));
*(dp++) = (png_byte)(255 - *(sp++));
}
}
#endif /* PNG_WRITE_16BIT_SUPPORTED */
}
}
}
#endif
#ifdef PNG_MNG_FEATURES_SUPPORTED
/* Undoes intrapixel differencing */
void /* PRIVATE */
png_do_write_intrapixel(png_row_infop row_info, png_bytep row)
{
png_debug(1, "in png_do_write_intrapixel");
if ((row_info->color_type & PNG_COLOR_MASK_COLOR))
{
int bytes_per_pixel;
png_uint_32 row_width = row_info->width;
if (row_info->bit_depth == 8)
{
png_bytep rp;
png_uint_32 i;
if (row_info->color_type == PNG_COLOR_TYPE_RGB)
bytes_per_pixel = 3;
else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
bytes_per_pixel = 4;
else
return;
for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
{
*(rp) = (png_byte)((*rp - *(rp + 1)) & 0xff);
*(rp + 2) = (png_byte)((*(rp + 2) - *(rp + 1)) & 0xff);
}
}
#ifdef PNG_WRITE_16BIT_SUPPORTED
else if (row_info->bit_depth == 16)
{
png_bytep rp;
png_uint_32 i;
if (row_info->color_type == PNG_COLOR_TYPE_RGB)
bytes_per_pixel = 6;
else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
bytes_per_pixel = 8;
else
return;
for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
{
png_uint_32 s0 = (*(rp ) << 8) | *(rp + 1);
png_uint_32 s1 = (*(rp + 2) << 8) | *(rp + 3);
png_uint_32 s2 = (*(rp + 4) << 8) | *(rp + 5);
png_uint_32 red = (png_uint_32)((s0 - s1) & 0xffffL);
png_uint_32 blue = (png_uint_32)((s2 - s1) & 0xffffL);
*(rp ) = (png_byte)((red >> 8) & 0xff);
*(rp + 1) = (png_byte)(red & 0xff);
*(rp + 4) = (png_byte)((blue >> 8) & 0xff);
*(rp + 5) = (png_byte)(blue & 0xff);
}
}
#endif /* PNG_WRITE_16BIT_SUPPORTED */
}
}
#endif /* PNG_MNG_FEATURES_SUPPORTED */
#endif /* PNG_WRITE_SUPPORTED */

File diff suppressed because it is too large Load Diff