[libpng16] Added color-map support to simplified API.
This is an initial version for review; the documentation has not yet been updated.
This commit is contained in:
parent
2312167d51
commit
5bc90389bf
2
ANNOUNCE
2
ANNOUNCE
@ -114,6 +114,8 @@ Version 1.6.0beta06 [January 24, 2012]
|
||||
changes some of the macro definitions in png.h, app code
|
||||
may need corresponding changes.
|
||||
Increased the formatted warning buffer to 192 bytes.
|
||||
Added color-map support to simplified API. This is an initial version for
|
||||
review; the documentation has not yet been updated.
|
||||
|
||||
Send comments/corrections/commendations to png-mng-implement at lists.sf.net
|
||||
(subscription required; visit
|
||||
|
2
CHANGES
2
CHANGES
@ -3865,6 +3865,8 @@ Version 1.6.0beta06 [January 24, 2012]
|
||||
changes some of the macro definitions in png.h, app code
|
||||
may need corresponding changes.
|
||||
Increased the formatted warning buffer to 192 bytes.
|
||||
Added color-map support to simplified API. This is an initial version for
|
||||
review; the documentation has not yet been updated.
|
||||
|
||||
Send comments/corrections/commendations to png-mng-implement at lists.sf.net
|
||||
(subscription required; visit
|
||||
|
230
png.h
230
png.h
@ -1,7 +1,7 @@
|
||||
|
||||
/* png.h - header file for PNG reference library
|
||||
*
|
||||
* libpng version 1.6.0beta06 - January 16, 2012
|
||||
* libpng version 1.6.0beta06 - January 24, 2012
|
||||
* Copyright (c) 1998-2012 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.)
|
||||
@ -11,7 +11,7 @@
|
||||
* Authors and maintainers:
|
||||
* libpng versions 0.71, May 1995, through 0.88, January 1996: Guy Schalnat
|
||||
* libpng versions 0.89c, June 1996, through 0.96, May 1997: Andreas Dilger
|
||||
* libpng versions 0.97, January 1998, through 1.6.0beta06 - January 16, 2012: Glenn
|
||||
* libpng versions 0.97, January 1998, through 1.6.0beta06 - January 24, 2012: Glenn
|
||||
* See also "Contributing Authors", below.
|
||||
*
|
||||
* Note about libpng version numbers:
|
||||
@ -198,7 +198,7 @@
|
||||
*
|
||||
* This code is released under the libpng license.
|
||||
*
|
||||
* libpng versions 1.2.6, August 15, 2004, through 1.6.0beta06, January 16, 2012, are
|
||||
* libpng versions 1.2.6, August 15, 2004, through 1.6.0beta06, January 24, 2012, are
|
||||
* Copyright (c) 2004, 2006-2012 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:
|
||||
@ -310,7 +310,7 @@
|
||||
* Y2K compliance in libpng:
|
||||
* =========================
|
||||
*
|
||||
* January 16, 2012
|
||||
* January 24, 2012
|
||||
*
|
||||
* Since the PNG Development group is an ad-hoc body, we can't make
|
||||
* an official declaration.
|
||||
@ -376,7 +376,7 @@
|
||||
/* Version information for png.h - this should match the version in png.c */
|
||||
#define PNG_LIBPNG_VER_STRING "1.6.0beta06"
|
||||
#define PNG_HEADER_VERSION_STRING \
|
||||
" libpng version 1.6.0beta06 - January 16, 2012\n"
|
||||
" libpng version 1.6.0beta06 - January 24, 2012\n"
|
||||
|
||||
#define PNG_LIBPNG_VER_SONUM 16
|
||||
#define PNG_LIBPNG_VER_DLLNUM 16
|
||||
@ -2636,48 +2636,47 @@ PNG_EXPORT(207, void, png_save_uint_16, (png_bytep buf, unsigned int i));
|
||||
*
|
||||
* To read a PNG file using the simplified API:
|
||||
*
|
||||
* 1) Declare a 'png_image' structure (see below) on the stack and memset() it
|
||||
* to all zero.
|
||||
* 1) Declare a 'png_image' structure (see below) on the stack and set the
|
||||
* version field to PNG_IMAGE_VERSION.
|
||||
* 2) Call the appropriate png_image_begin_read... function.
|
||||
* 3) Set the png_image 'format' member to the required sample format.
|
||||
* 4) [Optionally] Call png_image_read_colormap to read the image color-map and
|
||||
* request return of a color-mapped image.
|
||||
* 5) Allocate a buffer for the image.
|
||||
* 6) Call png_image_finish_read to read the image into your buffer.
|
||||
* 4) Allocate a buffer for the image and, if required, the color-map.
|
||||
* 5) Call png_image_finish_read to read the image and, if required, the
|
||||
* color-map into your buffers.
|
||||
*
|
||||
* There are no restrictions on the format of the PNG input itself; all valid
|
||||
* color types, bit depths, and interlace methods are acceptable, and the
|
||||
* input image is transformed as necessary to the requested in-memory format
|
||||
* during the png_image_finish_read() step. The only caveat is that if you
|
||||
* request a color-mapped image from a PNG that was not originally color-mapped
|
||||
* the transformation is extremely lossy and the result may look terrible.
|
||||
* request a color-mapped image from a PNG that is full-color or makes
|
||||
* complex use of an alpha channel the transformation is extremely lossy and the
|
||||
* result may look terrible.
|
||||
*
|
||||
* To write a PNG file using the simplified API:
|
||||
*
|
||||
* 1) Declare a 'png_image' structure on the stack and memset() it to all zero.
|
||||
* 2) Initialize the members of the structure that describe the image, setting
|
||||
* the 'format' member to the format of the image samples.
|
||||
* 3) [Optionally] call png_image_write_colormap to set the image color-map if
|
||||
* the data to be written is color-mapped.
|
||||
* 4) Call the appropriate png_image_write... function with a pointer to the
|
||||
* image to write the PNG data.
|
||||
* 3) Call the appropriate png_image_write... function with a pointer to the
|
||||
* image and, if necessary, the color-map to write the PNG data.
|
||||
*
|
||||
* png_image is a structure that describes the in-memory format of an image
|
||||
* when it is being read or define the in-memory format of an image that you
|
||||
* when it is being read or defines the in-memory format of an image that you
|
||||
* need to write:
|
||||
*/
|
||||
#define PNG_IMAGE_VERSION 1
|
||||
|
||||
typedef struct png_control *png_controlp;
|
||||
typedef struct
|
||||
{
|
||||
png_uint_32 width; /* Image width in pixels (columns) */
|
||||
png_uint_32 height; /* Image height in pixels (rows) */
|
||||
png_uint_32 format; /* Image format as defined below */
|
||||
png_uint_32 flags; /* A bit mask containing informational flags */
|
||||
png_controlp opaque; /* Initialize to NULL, free with png_image_free */
|
||||
|
||||
/* The following is only used for write; initialize it to NULL */
|
||||
png_const_bytep colormap; /* A pointer to the application color-map */
|
||||
png_controlp opaque; /* Initialize to NULL, free with png_image_free */
|
||||
png_uint_32 version; /* Set to PNG_IMAGE_VERSION */
|
||||
png_uint_32 width; /* Image width in pixels (columns) */
|
||||
png_uint_32 height; /* Image height in pixels (rows) */
|
||||
png_uint_32 format; /* Image format as defined below */
|
||||
png_uint_32 flags; /* A bit mask containing informational flags */
|
||||
png_uint_32 colormap_entries;
|
||||
/* Number of entries in the color-map */
|
||||
|
||||
/* In the event of an error or warning the following field will be set to a
|
||||
* non-zero value and the 'message' field will contain a '\0' terminated
|
||||
@ -2706,15 +2705,15 @@ typedef struct
|
||||
char message[64];
|
||||
} png_image, *png_imagep;
|
||||
|
||||
/* The pixels (samples) of the image have one to four channels whose components
|
||||
* have original values in the range 0 to 1.0:
|
||||
/* The samples of the image have one to four channels whose components have
|
||||
* original values in the range 0 to 1.0:
|
||||
*
|
||||
* 1: A single gray or luminance channel (G).
|
||||
* 2: A gray/luminance channel and an alpha channel (GA).
|
||||
* 3: Three red, green, blue color channels (RGB).
|
||||
* 4: Three color channels and an alpha channel (RGBA).
|
||||
*
|
||||
* The channels are encoded in one of two ways:
|
||||
* The components are encoded in one of two ways:
|
||||
*
|
||||
* a) As a small integer, value 0..255, contained in a single byte. For the
|
||||
* alpha channel the original value is simply value/255. For the color or
|
||||
@ -2735,22 +2734,24 @@ typedef struct
|
||||
* channel: the color/gray channels are scaled (pre-multiplied) by the alpha
|
||||
* value.
|
||||
*
|
||||
* When a color-mapped image is used as a result of calling
|
||||
* png_image_read_colormap or png_image_write_colormap the channels are encoded
|
||||
* in the color-map and the descriptions above apply to the color-map entries.
|
||||
* The image data is encoded as small integers, value 0..255, that index the
|
||||
* entries in the color-map. One integer (one byte) is stored for each pixel.
|
||||
* The samples are either contained directly in the image data, between 1 and 8
|
||||
* bytes per pixel according to the encoding, or are held in a color-map indexed
|
||||
* by bytes in the image data. In the case of a color-map the color-map entries
|
||||
* are individual samples, encoded as above, and the image data has one byte per
|
||||
* pixel to select the relevant sample from the color-map.
|
||||
*/
|
||||
|
||||
/* PNG_FORMAT_*
|
||||
*
|
||||
* #defines to be used in png_image::format. Each #define identifies a
|
||||
* particular layout of channel data and, if present, alpha values. There are
|
||||
* separate defines for each of the two channel encodings.
|
||||
* particular layout of sample data and, if present, alpha values. There are
|
||||
* separate defines for each of the two component encodings.
|
||||
*
|
||||
* A format is built up using single bit flag values. Not all combinations are
|
||||
* valid: use the bit flag values below for testing a format returned by the
|
||||
* read APIs, but set formats from the derived values.
|
||||
* A format is built up using single bit flag values. All combinations are
|
||||
* valid. Formats can be built up from the flag values or you can use one of
|
||||
* the predefined values below. When testing formats always use the FORMAT_FLAG
|
||||
* macros to test for individual features - future versions of the library may
|
||||
* add new flags.
|
||||
*
|
||||
* When reading or writing color-mapped images the format should be set to the
|
||||
* format of the entries in the color-map then png_image_{read,write}_colormap
|
||||
@ -2762,14 +2763,15 @@ typedef struct
|
||||
* compiled out it is because libpng does not have the required support. It is
|
||||
* possible, however, for the libpng configuration to enable the format on just
|
||||
* read or just write; in that case you may see an error at run time. You can
|
||||
* guard against this by checking for the definition of:
|
||||
* guard against this by checking for the definition of the appropriate
|
||||
* "_SUPPORTED" macro, one of:
|
||||
*
|
||||
* PNG_SIMPLIFIED_{READ,WRITE}_{BGR,AFIRST}_SUPPORTED
|
||||
*/
|
||||
#define PNG_FORMAT_FLAG_ALPHA 0x01U /* format with an alpha channel */
|
||||
#define PNG_FORMAT_FLAG_COLOR 0x02U /* color format: otherwise grayscale */
|
||||
#define PNG_FORMAT_FLAG_LINEAR 0x04U /* 2 byte channels else 1 byte */
|
||||
#define PNG_FORMAT_FLAG_COLORMAP 0x08U /* libpng use only */
|
||||
#define PNG_FORMAT_FLAG_COLORMAP 0x08U /* image data is color-mapped */
|
||||
|
||||
#ifdef PNG_FORMAT_BGR_SUPPORTED
|
||||
# define PNG_FORMAT_FLAG_BGR 0x10U /* BGR colors, else order is RGB */
|
||||
@ -2779,13 +2781,9 @@ typedef struct
|
||||
# define PNG_FORMAT_FLAG_AFIRST 0x20U /* alpha channel comes first */
|
||||
#endif
|
||||
|
||||
/* Supported formats are as follows. Future versions of libpng may support more
|
||||
* formats; for compatibility with older versions simply check if the format
|
||||
* macro is defined using #ifdef. These defines describe the in-memory layout
|
||||
* of the components of the pixels of the image or, for color-mapped images, the
|
||||
* layout of the entries of the color-map.
|
||||
/* Commonly used formats have predefined macros.
|
||||
*
|
||||
* First the single byte formats:
|
||||
* First the single byte (sRGB) formats:
|
||||
*/
|
||||
#define PNG_FORMAT_GRAY 0
|
||||
#define PNG_FORMAT_GA PNG_FORMAT_FLAG_ALPHA
|
||||
@ -2798,9 +2796,7 @@ typedef struct
|
||||
#define PNG_FORMAT_ABGR (PNG_FORMAT_BGRA|PNG_FORMAT_FLAG_AFIRST)
|
||||
|
||||
/* Then the linear 2-byte formats. When naming these "Y" is used to
|
||||
* indicate a luminance (gray) channel. The component order within the pixel
|
||||
* is always the same - there is no provision for swapping the order of the
|
||||
* components in the linear format.
|
||||
* indicate a luminance (gray) channel.
|
||||
*/
|
||||
#define PNG_FORMAT_LINEAR_Y PNG_FORMAT_FLAG_LINEAR
|
||||
#define PNG_FORMAT_LINEAR_Y_ALPHA (PNG_FORMAT_FLAG_LINEAR|PNG_FORMAT_FLAG_ALPHA)
|
||||
@ -2808,13 +2804,17 @@ typedef struct
|
||||
#define PNG_FORMAT_LINEAR_RGB_ALPHA \
|
||||
(PNG_FORMAT_FLAG_LINEAR|PNG_FORMAT_FLAG_COLOR|PNG_FORMAT_FLAG_ALPHA)
|
||||
|
||||
/* Color-mapped formats are obtained by calling png_image_{read,write}_colormap,
|
||||
* as appropriate after setting png_image::format to the format of the color-map
|
||||
* to be read or written. Applications may check the value of
|
||||
* PNG_FORMAT_FLAG_COLORMAP to see if they have called the colormap API. The
|
||||
* format of the color-map may be extracted using the following macro.
|
||||
/* With color-mapped formats the image data is one byte for each pixel, the byte
|
||||
* is an index into the color-map which is formatted as above. To obtain a
|
||||
* color-mapped format it is sufficient just to add the PNG_FOMAT_FLAG_COLORMAP
|
||||
* to one of the above definitions, or you can use one of the definitions below.
|
||||
*/
|
||||
#define PNG_FORMAT_OF_COLORMAP(fmt) ((fmt) & ~PNG_FORMAT_FLAG_COLORMAP)
|
||||
#define PNG_FORMAT_RGB_COLORMAP (PNG_FORMAT_RGB|PNG_FORMAT_FLAG_COLORMAP)
|
||||
#define PNG_FORMAT_BGR_COLORMAP (PNG_FORMAT_BGR|PNG_FORMAT_FLAG_COLORMAP)
|
||||
#define PNG_FORMAT_RGBA_COLORMAP (PNG_FORMAT_RGBA|PNG_FORMAT_FLAG_COLORMAP)
|
||||
#define PNG_FORMAT_ARGB_COLORMAP (PNG_FORMAT_ARGB|PNG_FORMAT_FLAG_COLORMAP)
|
||||
#define PNG_FORMAT_BGRA_COLORMAP (PNG_FORMAT_BGRA|PNG_FORMAT_FLAG_COLORMAP)
|
||||
#define PNG_FORMAT_ABGR_COLORMAP (PNG_FORMAT_ABGR|PNG_FORMAT_FLAG_COLORMAP)
|
||||
|
||||
/* PNG_IMAGE macros
|
||||
*
|
||||
@ -2822,9 +2822,9 @@ typedef struct
|
||||
* structure. The PNG_IMAGE_SAMPLE_ macros return values appropriate to the
|
||||
* actual image sample values - either the entries in the color-map or the
|
||||
* pixels in the image. The PNG_IMAGE_PIXEL_ macros return corresponding values
|
||||
* for the pixels and will always return 1 after a call to
|
||||
* png_image_{read,write}_colormap. The remaining macros return information
|
||||
* about the rows in the image and the complete image.
|
||||
* for the pixels and will always return 1 for color-mapped formats. The
|
||||
* remaining macros return information about the rows in the image and the
|
||||
* complete image.
|
||||
*
|
||||
* NOTE: All the macros that take a png_image::format parameter are compile time
|
||||
* constants if the format parameter is, itself, a constant. Therefore these
|
||||
@ -2841,7 +2841,7 @@ typedef struct
|
||||
#define PNG_IMAGE_SAMPLE_COMPONENT_SIZE(fmt)\
|
||||
((((fmt) & PNG_FORMAT_FLAG_LINEAR) >> 2)+1)
|
||||
/* Return the size in bytes of a single component of a pixel or color-map
|
||||
* entry (as appropriate) in the image.
|
||||
* entry (as appropriate) in the image: 1 or 2.
|
||||
*/
|
||||
|
||||
#define PNG_IMAGE_SAMPLE_SIZE(fmt)\
|
||||
@ -2851,11 +2851,19 @@ typedef struct
|
||||
* one byte in size), otherwise it is the size of one image pixel.
|
||||
*/
|
||||
|
||||
#define PNG_IMAGE_COLORMAP_SIZE(fmt) (PNG_IMAGE_SAMPLE_SIZE(format) * 256)
|
||||
/* The size of the color-map required by the format; this is the size of the
|
||||
* color-map buffer passed to the png_image_{read,write}_colormap APIs, it is
|
||||
* a fixed number determined by the format so can easily be allocated on the
|
||||
* stack if necessary.
|
||||
#define PNG_IMAGE_MAXIMUM_COLORMAP_COMPONENTS(fmt)\
|
||||
(PNG_IMAGE_SAMPLE_CHANNELS(fmt) * 256)
|
||||
/* The maximum size of the color-map required by the format expressed in a
|
||||
* count of components. This can be used to compile-time allocate a
|
||||
* color-map:
|
||||
*
|
||||
* png_uint_16 colormap[PNG_IMAGE_MAXIMUM_COLORMAP_COMPONENTS(linear_fmt)];
|
||||
*
|
||||
* png_byte colormap[PNG_IMAGE_MAXIMUM_COLORMAP_COMPONENTS(sRGB_fmt)];
|
||||
*
|
||||
* Alternatively use the PNG_IMAGE_COLORMAP_SIZE macro below to use the
|
||||
* information from one of the png_image_begin_read_ APIs and dynamically
|
||||
* allocate the required memory.
|
||||
*/
|
||||
|
||||
/* Corresponding information about the pixels */
|
||||
@ -2898,6 +2906,14 @@ typedef struct
|
||||
* the row stride is the minimum stride required for the image.
|
||||
*/
|
||||
|
||||
#define PNG_IMAGE_COLORMAP_SIZE(image)\
|
||||
(PNG_IMAGE_SAMPLE_SIZE((image).format) * (image).colormap_entries)
|
||||
/* Return the size, in bytes, of the color-map of this image. If the image
|
||||
* format is not a color-map format this will return a size sufficient for
|
||||
* 256 entries in the given format; check PNG_IMAGE_FORMAT_FLAG_COLORMAP if
|
||||
* you don't want to allocate a color-map in this case.
|
||||
*/
|
||||
|
||||
/* PNG_IMAGE_FLAG_*
|
||||
*
|
||||
* Flags containing additional information about the image are held in the
|
||||
@ -2908,13 +2924,6 @@ typedef struct
|
||||
* correspond to the red, green and blue end-points defined by sRGB.
|
||||
*/
|
||||
|
||||
#define PNG_IMAGE_FLAG_COLORMAP 0x02
|
||||
/* The PNG is color-mapped. If this flag is set png_image_read_colormap
|
||||
* can be used without further loss of image information. If it is not set
|
||||
* png_image_read_colormap will cause significant loss if the image has any
|
||||
* colors (if PNG_FORMAT_FLAG_COLOR is set).
|
||||
*/
|
||||
|
||||
#ifdef PNG_SIMPLIFIED_READ_SUPPORTED
|
||||
/* READ APIs
|
||||
* ---------
|
||||
@ -2938,28 +2947,9 @@ PNG_EXPORT(236, int, png_image_begin_read_from_memory, (png_imagep image,
|
||||
png_const_voidp memory, png_size_t size));
|
||||
/* The PNG header is read from the given memory buffer. */
|
||||
|
||||
PNG_EXPORT(242, int, png_image_read_colormap, (png_imagep image,
|
||||
png_bytep colormap, png_colorp background));
|
||||
/* Set the png_image to read a color-mapped image. image->format must be set
|
||||
* to the format required for the color-map, typically PNG_FORMAT_RGBA or
|
||||
* just PNG_FORMAT_RGB if an alpha channel is to be removed.
|
||||
*
|
||||
* The color-map is filled in and the actual number of valid entries
|
||||
* returned, 0 is returned on error. A subsequent call to
|
||||
* png_image_finish_read will return the color-mapped image data; one byte
|
||||
* per pixel.
|
||||
*
|
||||
* background is used as described below to remove alpha or transparency
|
||||
* information from an 8-bit color-map by compositing onto a solid color.
|
||||
*
|
||||
* If background is NULL *and* PNG_FORMAT_RGB is requested *and* the input
|
||||
* has an alpha channel then the call will currently FAIL, however, in the
|
||||
* future, libpng may be extended to composite onto the buffer in this case
|
||||
* too.
|
||||
*/
|
||||
|
||||
PNG_EXPORT(237, int, png_image_finish_read, (png_imagep image,
|
||||
png_colorp background, void *buffer, png_int_32 row_stride));
|
||||
png_colorp background, void *buffer, png_int_32 row_stride,
|
||||
void *colormap));
|
||||
/* Finish reading the image into the supplied buffer and clean up the
|
||||
* png_image structure.
|
||||
*
|
||||
@ -2974,12 +2964,22 @@ PNG_EXPORT(237, int, png_image_finish_read, (png_imagep image,
|
||||
* onto the buffer. The value is an sRGB color to use for the background,
|
||||
* for grayscale output the green channel is used.
|
||||
*
|
||||
* If png_image_read_colormap has been called the value of background must be
|
||||
* the same as that passed to the colormap call or the resultant image pixels
|
||||
* are implementation defined and may vary between libpng minor releases.
|
||||
* background must be supplied when an alpha channel must be removed from a
|
||||
* single byte color-mapped output format, in other words if:
|
||||
*
|
||||
* 1) The original format from png_image_begin_read_from_* had
|
||||
* PNG_FORMAT_FLAG_ALPHA set.
|
||||
* 2) The format set by the application does not.
|
||||
* 3) The format set by the application has PNG_FORMAT_FLAG_COLORMAP set and
|
||||
* PNG_FORMAT_FLAG_LINEAR *not* set.
|
||||
*
|
||||
* For linear output removing the alpha channel is always done by compositing
|
||||
* on black.
|
||||
* on black and background is ignored.:
|
||||
*
|
||||
* colormap must be supplied when PNG_FORMAT_FLAG_COLORMAP is set. It must
|
||||
* be at least the size (in bytes) returned by PNG_IMAGE_COLORMAP_SIZE.
|
||||
* image->colormap_entries will be updated to the actual number of entries
|
||||
* written to the colormap; this may be less than the original value.
|
||||
*/
|
||||
|
||||
PNG_EXPORT(238, void, png_image_free, (png_imagep image));
|
||||
@ -2992,42 +2992,38 @@ PNG_EXPORT(238, void, png_image_free, (png_imagep image));
|
||||
/* WRITE APIS
|
||||
* ----------
|
||||
* For write you must initialize a png_image structure to describe the image to
|
||||
* be written:
|
||||
* be written. To do this use memset to set the whole structure to 0 then
|
||||
* initialize fields describing your image.
|
||||
*
|
||||
* version: must be set to PNG_IMAGE_VERSION
|
||||
* opaque: must be initialized to NULL
|
||||
* colormap: must be initialized to NULL
|
||||
* width: image width in pixels
|
||||
* height: image height in rows
|
||||
* format: the format of the data you wish to write
|
||||
* format: the format of the data (image and color-map) you wish to write
|
||||
* flags: set to 0 unless one of the defined flags applies; set
|
||||
* PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB for color format images where the RGB
|
||||
* values do not correspond to the colors in sRGB.
|
||||
* colormap_entries: set to the number of entries in the color-map (0 to 256)
|
||||
*/
|
||||
PNG_EXPORT(243, int, png_image_write_colormap, (png_imagep image,
|
||||
png_const_bytep colormap));
|
||||
/* Optionally write a color-mapped image. 'format' must be set to the format
|
||||
* of the data in the color-map and must not be changed after the call. The
|
||||
* colormap *pointer* is retained, the color-map data itself is not copied;
|
||||
* the data must not be freed until after the called to png_image_write_*
|
||||
*/
|
||||
|
||||
PNG_EXPORT(239, int, png_image_write_to_file, (png_imagep image,
|
||||
const char *file, int convert_to_8bit, const void *buffer,
|
||||
png_int_32 row_stride));
|
||||
png_int_32 row_stride, const void *colormap));
|
||||
/* Write the image to the named file. */
|
||||
|
||||
PNG_EXPORT(240, int, png_image_write_to_stdio, (png_imagep image, FILE *file,
|
||||
int convert_to_8_bit, const void *buffer, png_int_32 row_stride));
|
||||
int convert_to_8_bit, const void *buffer, png_int_32 row_stride,
|
||||
const void *colormap));
|
||||
/* Write the image to the given (FILE*). */
|
||||
|
||||
/* With all write APIs if image is in one of the linear formats with 16-bit data
|
||||
* then setting convert_to_8_bit will cause the output to be an 8-bit PNG gamma
|
||||
* encoded according to the sRGB specification, otherwise a 16-bit linear
|
||||
/* With both write APIs if image is in one of the linear formats with 16-bit
|
||||
* data then setting convert_to_8_bit will cause the output to be an 8-bit PNG
|
||||
* gamma encoded according to the sRGB specification, otherwise a 16-bit linear
|
||||
* encoded PNG file is written.
|
||||
*
|
||||
* With color-mapped data png_image_write_colormap must be called. The palette
|
||||
* may contain linear (16-bit) entries, these will be converted to sRGB values
|
||||
* regardless of the setting of convert_to_8_bit.
|
||||
* With color-mapped data formats the colormap parameter point to a color-map
|
||||
* with at least image->colormap_entries encoded in the specified format. If
|
||||
* the format is linear the written PNG color-map will be converted to sRGB
|
||||
* regardless of the convert_to_8_bit flag.
|
||||
*
|
||||
* With all APIs row_stride is handled as in the read APIs - it is the spacing
|
||||
* from one row to the next in component sized units (1 or 2 bytes) and if
|
||||
@ -3049,7 +3045,7 @@ PNG_EXPORT(240, int, png_image_write_to_stdio, (png_imagep image, FILE *file,
|
||||
* scripts/symbols.def as well.
|
||||
*/
|
||||
#ifdef PNG_EXPORT_LAST_ORDINAL
|
||||
PNG_EXPORT_LAST_ORDINAL(243);
|
||||
PNG_EXPORT_LAST_ORDINAL(241);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
34
pngpriv.h
34
pngpriv.h
@ -519,20 +519,31 @@ typedef const png_uint_16p * png_const_uint_16pp;
|
||||
#ifdef PNG_SIMPLIFIED_READ_SUPPORTED
|
||||
extern /*PRIVATE*/ PNG_CONST_DATA png_uint_16 png_sRGB_table[256];
|
||||
/* Convert from an sRGB encoded value 0..255 to a 16-bit linear value,
|
||||
* 0..65535. This table gives the closes 16-bit answers (no errors).
|
||||
* 0..65535. This table gives the closest 16-bit answers (no errors).
|
||||
*/
|
||||
#endif
|
||||
|
||||
extern /*PRIVATE*/ PNG_CONST_DATA png_uint_16 png_sRGB_base[512];
|
||||
extern /*PRIVATE*/ PNG_CONST_DATA png_byte png_sRGB_delta[512];
|
||||
|
||||
#define PNG_sRGB_FROM_LINEAR(linear) ((png_sRGB_base[(linear)>>15] +\
|
||||
((((linear)&0x7fff)*png_sRGB_delta[(linear)>>15])>>12)) >> 8)
|
||||
#define PNG_sRGB_FROM_LINEAR(linear) ((png_byte)((png_sRGB_base[(linear)>>15] +\
|
||||
((((linear)&0x7fff)*png_sRGB_delta[(linear)>>15])>>12)) >> 8))
|
||||
/* Given a value 'linear' in the range 0..255*65535 calculate the 8-bit sRGB
|
||||
* encoded value with maximum error 0.646365. Note that the input is not a
|
||||
* 16-bit value; it has been multiplied by 255! */
|
||||
#endif /* PNG_SIMPLIFIED_READ/WRITE */
|
||||
|
||||
/* Added to libpng-1.6.0: scale a 16-bit value in the range 0..65535 to 0..255
|
||||
* by dividing by 257 *with rounding*. This macro is exact for the given range.
|
||||
* See the discourse in pngrtran.c png_do_scale_16_to_8. The values in the
|
||||
* macro were established by experiment (modifying the added value). The macro
|
||||
* has a second variant that takes a value already scaled by 255 and divides by
|
||||
* 65535 - this has a maximum error of .502. Over the range 0..65535*65535 it
|
||||
* only gives off-by-one errors and only for 0.5% (1 in 200) of the values.
|
||||
*/
|
||||
#define PNG_DIV65535(v24) (((v24) + 32895) >> 16)
|
||||
#define PNG_DIV257(v16) PNG_DIV65535((png_uint_32)(v16) * 255)
|
||||
|
||||
/* Added to libpng-1.2.6 JB */
|
||||
#define PNG_ROWBYTES(pixel_bits, width) \
|
||||
((pixel_bits) >= 8 ? \
|
||||
@ -1622,17 +1633,20 @@ PNG_EXTERN void png_build_gamma_table PNGARG((png_structrp png_ptr,
|
||||
/* The internal structure that png_image::opaque points to. */
|
||||
typedef struct png_control
|
||||
{
|
||||
png_structp png_ptr;
|
||||
png_infop info_ptr;
|
||||
png_voidp error_buf; /* Always a jmp_buf at present. */
|
||||
png_structp png_ptr;
|
||||
png_infop info_ptr;
|
||||
png_voidp error_buf; /* Always a jmp_buf at present. */
|
||||
|
||||
png_const_bytep memory; /* Memory buffer. */
|
||||
png_size_t size; /* Size of the memory buffer. */
|
||||
png_const_bytep memory; /* Memory buffer. */
|
||||
png_size_t size; /* Size of the memory buffer. */
|
||||
|
||||
unsigned int for_write :1; /* Otherwise it is a read structure */
|
||||
unsigned int owned_file :1; /* We own the file in io_ptr */
|
||||
unsigned int for_write :1; /* Otherwise it is a read structure */
|
||||
unsigned int owned_file :1; /* We own the file in io_ptr */
|
||||
} png_control;
|
||||
|
||||
/* This is used to name an sPLT written by the simplified API. */
|
||||
#define LIBPNG_SPLT_NAME "libpng " PNG_LIBPNG_VER_STRING
|
||||
|
||||
/* Return the pointer to the jmp_buf from a png_control: necessary because C
|
||||
* does not reveal the type of the elements of jmp_buf.
|
||||
*/
|
||||
|
@ -1454,7 +1454,7 @@ png_init_read_transformations(png_structrp png_ptr)
|
||||
* NOTE: this discards the low 16 bits of the user supplied background
|
||||
* color, but until expand_16 works properly there is no choice!
|
||||
*/
|
||||
# define CHOP(x) (x)=((png_uint_16)(((png_uint_32)(x)*255+32895) >> 16))
|
||||
# define CHOP(x) (x)=((png_uint_16)PNG_DIV257(x))
|
||||
CHOP(png_ptr->background.red);
|
||||
CHOP(png_ptr->background.green);
|
||||
CHOP(png_ptr->background.blue);
|
||||
|
330
pngwrite.c
330
pngwrite.c
@ -1561,32 +1561,6 @@ png_image_write_init(png_imagep image)
|
||||
return png_image_error(image, "png_image_read: out of memory");
|
||||
}
|
||||
|
||||
int PNGAPI
|
||||
png_image_write_colormap(png_imagep image, png_const_bytep colormap)
|
||||
{
|
||||
if (image != NULL)
|
||||
{
|
||||
if (colormap != NULL)
|
||||
{
|
||||
if ((image->format & PNG_FORMAT_FLAG_COLORMAP) == 0)
|
||||
{
|
||||
image->colormap = colormap; /* alias, caller must preserve */
|
||||
image->format |= PNG_FORMAT_FLAG_COLORMAP;
|
||||
}
|
||||
|
||||
else
|
||||
return png_image_error(image,
|
||||
"png_image_write_colormap: colormap already set");
|
||||
}
|
||||
|
||||
else
|
||||
return png_image_error(image,
|
||||
"png_image_write_colormap: invalid argument");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Arguments to png_image_write_main: */
|
||||
typedef struct
|
||||
{
|
||||
@ -1594,6 +1568,7 @@ typedef struct
|
||||
png_imagep image;
|
||||
png_const_voidp buffer;
|
||||
png_int_32 row_stride;
|
||||
png_const_voidp colormap;
|
||||
int convert_to_8bit;
|
||||
/* Local variables: */
|
||||
png_const_voidp first_row;
|
||||
@ -1708,7 +1683,58 @@ png_write_image_16bit(png_voidp argument)
|
||||
/* Given 16-bit input (1 to 4 channels) write 8-bit output. If an alpha channel
|
||||
* is present it must be removed from the components, the components are then
|
||||
* written in sRGB encoding. No components are added or removed.
|
||||
*
|
||||
* Calculate an alpha reciprocal to reverse pre-multiplication. As above the
|
||||
* calculation can be done to 15 bits of accuracy; however, the output needs to
|
||||
* be scaled in the range 0..255*65535, so include that scaling here.
|
||||
*/
|
||||
#define UNP_RECIPROCAL(alpha) ((((0xffff*0xff)<<7)+(alpha>>1))/alpha)
|
||||
|
||||
static png_byte
|
||||
png_unpremultiply(png_uint_32 component, png_uint_32 alpha,
|
||||
png_uint_32 reciprocal/*from the above macro*/)
|
||||
{
|
||||
/* The following gives 1.0 for an alpha of 0, which is fine, otherwise if 0/0
|
||||
* is represented as some other value there is more likely to be a
|
||||
* discontinuity which will probably damage compression when moving from a
|
||||
* fully transparent area to a nearly transparent one. (The assumption here
|
||||
* is that opaque areas tend not to be 0 intensity.)
|
||||
*
|
||||
* There is a rounding problem here; if alpha is less than 128 it will end up
|
||||
* as 0 when scaled to 8 bits. To avoid introducing spurious colors into the
|
||||
* output change for this too.
|
||||
*/
|
||||
if (component >= alpha || alpha < 128)
|
||||
return 255;
|
||||
|
||||
/* component<alpha, so component/alpha is less than one and
|
||||
* component*reciprocal is less than 2^31.
|
||||
*/
|
||||
else if (component > 0)
|
||||
{
|
||||
/* The test is that alpha/257 (rounded) is less than 255, the first value
|
||||
* that becomes 255 is 65407.
|
||||
* NOTE: this must agree with the PNG_DIV257 macro (which must, therefore,
|
||||
* be exact!) [Could also test reciprocal != 0]
|
||||
*/
|
||||
if (alpha < 65407)
|
||||
{
|
||||
component *= reciprocal;
|
||||
component += 64; /* round to nearest */
|
||||
component >>= 7;
|
||||
}
|
||||
|
||||
else
|
||||
component *= 255;
|
||||
|
||||
/* Convert the component to sRGB. */
|
||||
return (png_byte)PNG_sRGB_FROM_LINEAR(component);
|
||||
}
|
||||
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
png_write_image_8bit(png_voidp argument)
|
||||
{
|
||||
@ -1749,62 +1775,19 @@ png_write_image_8bit(png_voidp argument)
|
||||
if (aindex != 0) while (out_ptr < row_end) /* Alpha channel case */
|
||||
{
|
||||
png_uint_16 alpha = in_ptr[aindex];
|
||||
png_byte alphabyte = (png_byte)PNG_DIV257(alpha);
|
||||
png_uint_32 reciprocal = 0;
|
||||
int c;
|
||||
|
||||
/* Scale and write the alpha channel. See pngrtran.c
|
||||
* png_do_scale_16_to_8 for a discussion of this calculation. The
|
||||
* code here has machine native values, so use:
|
||||
*
|
||||
* (V * 255 + 32895) >> 16
|
||||
*/
|
||||
out_ptr[aindex] = (png_byte)((alpha * 255 + 32895) >> 16);
|
||||
/* Scale and write the alpha channel. */
|
||||
out_ptr[aindex] = alphabyte;
|
||||
|
||||
/* Calculate a reciprocal. As above the calculation can be done to
|
||||
* 15 bits of accuracy, however the output needs to be scaled in the
|
||||
* range 0..255*65535, so include that scaling here.
|
||||
*/
|
||||
if (alpha > 0 && alpha < 65535)
|
||||
reciprocal = (((0xffff*0xff)<<7)+(alpha>>1))/alpha;
|
||||
if (alphabyte > 0 && alphabyte < 255)
|
||||
reciprocal = UNP_RECIPROCAL(alpha);
|
||||
|
||||
c = channels;
|
||||
do /* always at least one channel */
|
||||
{
|
||||
/* Need 32 bit accuracy in the sRGB tables */
|
||||
png_uint_32 component = *in_ptr++;
|
||||
|
||||
/* The following gives 1.0 for an alpha of 0, which is fine,
|
||||
* otherwise if 0/0 is represented as some other value there is
|
||||
* more likely to be a discontinuity which will probably damage
|
||||
* compression when moving from a fully transparent area to a
|
||||
* nearly transparent one. (The assumption here is that opaque
|
||||
* areas tend not to be 0 intensity.)
|
||||
*/
|
||||
if (component >= alpha)
|
||||
*out_ptr++ = 255;
|
||||
|
||||
/* component<alpha, so component/alpha is less than one and
|
||||
* component*reciprocal is less than 2^31.
|
||||
*/
|
||||
else if (component > 0)
|
||||
{
|
||||
if (alpha < 65535)
|
||||
{
|
||||
component *= reciprocal;
|
||||
component += 64; /* round to nearest */
|
||||
component >>= 7;
|
||||
}
|
||||
|
||||
else
|
||||
component *= 255;
|
||||
|
||||
/* Convert the component to sRGB. */
|
||||
*out_ptr++ = (png_byte)PNG_sRGB_FROM_LINEAR(component);
|
||||
}
|
||||
|
||||
else
|
||||
*out_ptr++ = 0;
|
||||
}
|
||||
*out_ptr++ = png_unpremultiply(*in_ptr++, alpha, reciprocal);
|
||||
while (--c > 0);
|
||||
|
||||
/* Skip to next component (skip the intervening alpha channel) */
|
||||
@ -1846,6 +1829,151 @@ png_write_image_8bit(png_voidp argument)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
png_image_set_PLTE(png_image_write_control *display)
|
||||
{
|
||||
const png_imagep image = display->image;
|
||||
const void *cmap = display->colormap;
|
||||
const int entries = image->colormap_entries > 256 ? 256 :
|
||||
(int)image->colormap_entries;
|
||||
|
||||
/* NOTE: the caller must check for cmap != NULL and entries != 0 */
|
||||
const png_uint_32 format = image->format;
|
||||
const int channels = PNG_IMAGE_SAMPLE_CHANNELS(format);
|
||||
|
||||
# ifdef PNG_FORMAT_BGR_SUPPORTED
|
||||
const int afirst = (format & PNG_FORMAT_FLAG_AFIRST) != 0 &&
|
||||
(format & PNG_FORMAT_FLAG_ALPHA) != 0;
|
||||
# else
|
||||
# define afirst 0
|
||||
# endif
|
||||
|
||||
# ifdef PNG_FORMAT_BGR_SUPPORTED
|
||||
const int bgr = (format & PNG_FORMAT_FLAG_BGR) ? 2 : 0;
|
||||
# else
|
||||
# define bgr 0
|
||||
# endif
|
||||
|
||||
int i, num_trans;
|
||||
png_color palette[256];
|
||||
png_byte tRNS[256];
|
||||
|
||||
memset(tRNS, 255, sizeof tRNS);
|
||||
memset(palette, 0, sizeof palette);
|
||||
|
||||
for (i=num_trans=0; i<entries; ++i)
|
||||
{
|
||||
/* This gets automatically converted to sRGB with reversal of the
|
||||
* pre-multiplication if the color-map has an alpha channel.
|
||||
*/
|
||||
if (format & PNG_FORMAT_FLAG_LINEAR)
|
||||
{
|
||||
png_const_uint_16p entry = png_voidcast(png_const_uint_16p, cmap);
|
||||
|
||||
entry += i * channels;
|
||||
|
||||
if (channels & 1) /* no alpha */
|
||||
{
|
||||
if (channels >= 3) /* RGB */
|
||||
{
|
||||
palette[i].blue = (png_byte)PNG_sRGB_FROM_LINEAR(255 *
|
||||
entry[(2 ^ bgr)]);
|
||||
palette[i].green = (png_byte)PNG_sRGB_FROM_LINEAR(255 *
|
||||
entry[1]);
|
||||
palette[i].red = (png_byte)PNG_sRGB_FROM_LINEAR(255 *
|
||||
entry[bgr]);
|
||||
}
|
||||
|
||||
else /* Gray */
|
||||
palette[i].blue = palette[i].red = palette[i].green =
|
||||
(png_byte)PNG_sRGB_FROM_LINEAR(255 * *entry);
|
||||
}
|
||||
|
||||
else /* alpha */
|
||||
{
|
||||
png_uint_16 alpha = entry[afirst ? 0 : channels-1];
|
||||
png_byte alphabyte = (png_byte)PNG_DIV257(alpha);
|
||||
png_uint_32 reciprocal = 0;
|
||||
|
||||
/* Calculate a reciprocal, as in the png_write_image_8bit code above
|
||||
* this is designed to produce a value scaled to 255*65535 when
|
||||
* divided by 128 (i.e. asr 7).
|
||||
*/
|
||||
if (alphabyte > 0 && alphabyte < 255)
|
||||
reciprocal = (((0xffff*0xff)<<7)+(alpha>>1))/alpha;
|
||||
|
||||
tRNS[i] = alphabyte;
|
||||
if (alphabyte < 255)
|
||||
num_trans = i+1;
|
||||
|
||||
if (channels >= 3) /* RGB */
|
||||
{
|
||||
palette[i].blue = png_unpremultiply(entry[afirst + (2 ^ bgr)],
|
||||
alpha, reciprocal);
|
||||
palette[i].green = png_unpremultiply(entry[afirst + 1], alpha,
|
||||
reciprocal);
|
||||
palette[i].red = png_unpremultiply(entry[afirst + bgr], alpha,
|
||||
reciprocal);
|
||||
}
|
||||
|
||||
else /* gray */
|
||||
palette[i].blue = palette[i].red = palette[i].green =
|
||||
png_unpremultiply(entry[afirst], alpha, reciprocal);
|
||||
}
|
||||
}
|
||||
|
||||
else /* Color-map has sRGB values */
|
||||
{
|
||||
png_const_bytep entry = png_voidcast(png_const_bytep, cmap);
|
||||
|
||||
entry += i * channels;
|
||||
|
||||
switch (channels)
|
||||
{
|
||||
case 4:
|
||||
tRNS[i] = entry[afirst ? 0 : 3];
|
||||
if (tRNS[i] < 255)
|
||||
num_trans = i+1;
|
||||
/* FALL THROUGH */
|
||||
case 3:
|
||||
palette[i].blue = entry[afirst + (2 ^ bgr)];
|
||||
palette[i].green = entry[afirst + 1];
|
||||
palette[i].red = entry[afirst + bgr];
|
||||
break;
|
||||
|
||||
case 2:
|
||||
tRNS[i] = entry[1 ^ afirst];
|
||||
if (tRNS[i] < 255)
|
||||
num_trans = i+1;
|
||||
/* FALL THROUGH */
|
||||
case 1:
|
||||
palette[i].blue = palette[i].red = palette[i].green =
|
||||
entry[afirst];
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# ifdef afirst
|
||||
# undef afirst
|
||||
# endif
|
||||
# ifdef bgr
|
||||
# undef bgr
|
||||
# endif
|
||||
|
||||
png_set_PLTE(image->opaque->png_ptr, image->opaque->info_ptr, palette,
|
||||
entries);
|
||||
|
||||
if (num_trans > 0)
|
||||
png_set_tRNS(image->opaque->png_ptr, image->opaque->info_ptr, tRNS,
|
||||
num_trans, NULL);
|
||||
|
||||
image->colormap_entries = entries;
|
||||
}
|
||||
|
||||
static int
|
||||
png_image_write_main(png_voidp argument)
|
||||
{
|
||||
@ -1856,9 +1984,10 @@ png_image_write_main(png_voidp argument)
|
||||
png_inforp info_ptr = image->opaque->info_ptr;
|
||||
png_uint_32 format = image->format;
|
||||
|
||||
int linear = (format & PNG_FORMAT_FLAG_LINEAR) != 0; /* input */
|
||||
int alpha = (format & PNG_FORMAT_FLAG_ALPHA) != 0;
|
||||
int write_16bit = linear && !display->convert_to_8bit;
|
||||
int colormap = (format & PNG_FORMAT_FLAG_COLORMAP) != 0;
|
||||
int linear = !colormap && (format & PNG_FORMAT_FLAG_LINEAR) != 0; /* input */
|
||||
int alpha = !colormap && (format & PNG_FORMAT_FLAG_ALPHA) != 0;
|
||||
int write_16bit = linear && !colormap && !display->convert_to_8bit;
|
||||
|
||||
/* Default the 'row_stride' parameter if required. */
|
||||
if (display->row_stride == 0)
|
||||
@ -1866,7 +1995,23 @@ png_image_write_main(png_voidp argument)
|
||||
|
||||
/* Set the required transforms then write the rows in the correct order. */
|
||||
if (format & PNG_FORMAT_FLAG_COLORMAP)
|
||||
return png_image_error(image, "png_image_write: colormap NYI");
|
||||
{
|
||||
if (display->colormap != NULL && image->colormap_entries > 0)
|
||||
{
|
||||
png_uint_32 entries = image->colormap_entries;
|
||||
|
||||
png_set_IHDR(png_ptr, info_ptr, image->width, image->height,
|
||||
entries > 16 ? 8 : (entries > 4 ? 4 : (entries > 2 ? 2 : 1)),
|
||||
PNG_COLOR_TYPE_PALETTE, PNG_INTERLACE_NONE,
|
||||
PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
|
||||
|
||||
png_image_set_PLTE(display);
|
||||
}
|
||||
|
||||
else
|
||||
png_error(image->opaque->png_ptr,
|
||||
"no color-map for color-mapped image");
|
||||
}
|
||||
|
||||
else
|
||||
png_set_IHDR(png_ptr, info_ptr, image->width, image->height,
|
||||
@ -1880,6 +2025,7 @@ png_image_write_main(png_voidp argument)
|
||||
* must still be called before. Just set the color space information, never
|
||||
* write an interlaced image.
|
||||
*/
|
||||
|
||||
if (write_16bit)
|
||||
{
|
||||
/* The gamma here is 1.0 (linear) and the cHRM chunk matches sRGB. */
|
||||
@ -1923,7 +2069,7 @@ png_image_write_main(png_voidp argument)
|
||||
# ifdef PNG_SIMPLIFIED_WRITE_BGR_SUPPORTED
|
||||
if (format & PNG_FORMAT_FLAG_BGR)
|
||||
{
|
||||
if (format & PNG_FORMAT_FLAG_COLOR)
|
||||
if (!colormap && (format & PNG_FORMAT_FLAG_COLOR) != 0)
|
||||
png_set_bgr(png_ptr);
|
||||
format &= ~PNG_FORMAT_FLAG_BGR;
|
||||
}
|
||||
@ -1932,15 +2078,21 @@ png_image_write_main(png_voidp argument)
|
||||
# ifdef PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED
|
||||
if (format & PNG_FORMAT_FLAG_AFIRST)
|
||||
{
|
||||
if (format & PNG_FORMAT_FLAG_ALPHA)
|
||||
if (!colormap && (format & PNG_FORMAT_FLAG_ALPHA) != 0)
|
||||
png_set_swap_alpha(png_ptr);
|
||||
format &= ~PNG_FORMAT_FLAG_AFIRST;
|
||||
}
|
||||
# endif
|
||||
|
||||
/* If there are 16 or fewer color-map entries we wrote a lower bit depth
|
||||
* above, but the application data is still byte packed.
|
||||
*/
|
||||
if (colormap && image->colormap_entries <= 16)
|
||||
png_set_packing(png_ptr);
|
||||
|
||||
/* That should have handled all (both) the transforms. */
|
||||
if ((format & ~(png_uint_32)(PNG_FORMAT_FLAG_COLOR | PNG_FORMAT_FLAG_LINEAR |
|
||||
PNG_FORMAT_FLAG_ALPHA)) != 0)
|
||||
PNG_FORMAT_FLAG_ALPHA | PNG_FORMAT_FLAG_COLORMAP)) != 0)
|
||||
png_error(png_ptr, "png_write_image: unsupported transformation");
|
||||
|
||||
{
|
||||
@ -1961,7 +2113,7 @@ png_image_write_main(png_voidp argument)
|
||||
* before it is written. This only applies when the input is 16-bit and
|
||||
* either there is an alpha channel or it is converted to 8-bit.
|
||||
*/
|
||||
if ((linear && alpha) || display->convert_to_8bit)
|
||||
if ((linear && alpha) || (!colormap && display->convert_to_8bit))
|
||||
{
|
||||
png_bytep row = png_voidcast(png_bytep, png_malloc(png_ptr,
|
||||
png_get_rowbytes(png_ptr, info_ptr)));
|
||||
@ -2003,10 +2155,10 @@ png_image_write_main(png_voidp argument)
|
||||
|
||||
int PNGAPI
|
||||
png_image_write_to_stdio(png_imagep image, FILE *file, int convert_to_8bit,
|
||||
const void *buffer, png_int_32 row_stride)
|
||||
const void *buffer, png_int_32 row_stride, const void *colormap)
|
||||
{
|
||||
/* Write the image to the given (FILE*). */
|
||||
if (image != NULL)
|
||||
if (image != NULL || image->version != PNG_IMAGE_VERSION)
|
||||
{
|
||||
if (file != NULL)
|
||||
{
|
||||
@ -2025,6 +2177,7 @@ png_image_write_to_stdio(png_imagep image, FILE *file, int convert_to_8bit,
|
||||
display.image = image;
|
||||
display.buffer = buffer;
|
||||
display.row_stride = row_stride;
|
||||
display.colormap = colormap;
|
||||
display.convert_to_8bit = convert_to_8bit;
|
||||
|
||||
result = png_safe_execute(image, png_image_write_main, &display);
|
||||
@ -2047,10 +2200,11 @@ png_image_write_to_stdio(png_imagep image, FILE *file, int convert_to_8bit,
|
||||
|
||||
int PNGAPI
|
||||
png_image_write_to_file(png_imagep image, const char *file_name,
|
||||
int convert_to_8bit, const void *buffer, png_int_32 row_stride)
|
||||
int convert_to_8bit, const void *buffer, png_int_32 row_stride,
|
||||
const void *colormap)
|
||||
{
|
||||
/* Write the image to the named file. */
|
||||
if (image != NULL)
|
||||
if (image != NULL || image->version != PNG_IMAGE_VERSION)
|
||||
{
|
||||
if (file_name != NULL)
|
||||
{
|
||||
@ -2059,7 +2213,7 @@ png_image_write_to_file(png_imagep image, const char *file_name,
|
||||
if (fp != NULL)
|
||||
{
|
||||
if (png_image_write_to_stdio(image, fp, convert_to_8bit, buffer,
|
||||
row_stride))
|
||||
row_stride, colormap))
|
||||
{
|
||||
int error; /* from fflush/fclose */
|
||||
|
||||
|
@ -247,5 +247,3 @@ EXPORTS
|
||||
png_image_write_to_file @239
|
||||
png_image_write_to_stdio @240
|
||||
png_convert_to_rfc1123_buffer @241
|
||||
png_image_read_colormap @242
|
||||
png_image_write_colormap @243
|
||||
|
Loading…
Reference in New Issue
Block a user