mirror of
https://git.code.sf.net/p/libpng/code.git
synced 2025-07-10 18:04:09 +02:00
[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
|
changes some of the macro definitions in png.h, app code
|
||||||
may need corresponding changes.
|
may need corresponding changes.
|
||||||
Increased the formatted warning buffer to 192 bytes.
|
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
|
Send comments/corrections/commendations to png-mng-implement at lists.sf.net
|
||||||
(subscription required; visit
|
(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
|
changes some of the macro definitions in png.h, app code
|
||||||
may need corresponding changes.
|
may need corresponding changes.
|
||||||
Increased the formatted warning buffer to 192 bytes.
|
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
|
Send comments/corrections/commendations to png-mng-implement at lists.sf.net
|
||||||
(subscription required; visit
|
(subscription required; visit
|
||||||
|
|||||||
230
png.h
230
png.h
@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
/* png.h - header file for PNG reference library
|
/* 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
|
* Copyright (c) 1998-2012 Glenn Randers-Pehrson
|
||||||
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
|
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
|
||||||
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
|
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
|
||||||
@ -11,7 +11,7 @@
|
|||||||
* Authors and maintainers:
|
* Authors and maintainers:
|
||||||
* libpng versions 0.71, May 1995, through 0.88, January 1996: Guy Schalnat
|
* 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.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.
|
* See also "Contributing Authors", below.
|
||||||
*
|
*
|
||||||
* Note about libpng version numbers:
|
* Note about libpng version numbers:
|
||||||
@ -198,7 +198,7 @@
|
|||||||
*
|
*
|
||||||
* This code is released under the libpng license.
|
* 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
|
* Copyright (c) 2004, 2006-2012 Glenn Randers-Pehrson, and are
|
||||||
* distributed according to the same disclaimer and license as libpng-1.2.5
|
* distributed according to the same disclaimer and license as libpng-1.2.5
|
||||||
* with the following individual added to the list of Contributing Authors:
|
* with the following individual added to the list of Contributing Authors:
|
||||||
@ -310,7 +310,7 @@
|
|||||||
* Y2K compliance in libpng:
|
* Y2K compliance in libpng:
|
||||||
* =========================
|
* =========================
|
||||||
*
|
*
|
||||||
* January 16, 2012
|
* January 24, 2012
|
||||||
*
|
*
|
||||||
* Since the PNG Development group is an ad-hoc body, we can't make
|
* Since the PNG Development group is an ad-hoc body, we can't make
|
||||||
* an official declaration.
|
* an official declaration.
|
||||||
@ -376,7 +376,7 @@
|
|||||||
/* Version information for png.h - this should match the version in png.c */
|
/* Version information for png.h - this should match the version in png.c */
|
||||||
#define PNG_LIBPNG_VER_STRING "1.6.0beta06"
|
#define PNG_LIBPNG_VER_STRING "1.6.0beta06"
|
||||||
#define PNG_HEADER_VERSION_STRING \
|
#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_SONUM 16
|
||||||
#define PNG_LIBPNG_VER_DLLNUM 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:
|
* To read a PNG file using the simplified API:
|
||||||
*
|
*
|
||||||
* 1) Declare a 'png_image' structure (see below) on the stack and memset() it
|
* 1) Declare a 'png_image' structure (see below) on the stack and set the
|
||||||
* to all zero.
|
* version field to PNG_IMAGE_VERSION.
|
||||||
* 2) Call the appropriate png_image_begin_read... function.
|
* 2) Call the appropriate png_image_begin_read... function.
|
||||||
* 3) Set the png_image 'format' member to the required sample format.
|
* 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
|
* 4) Allocate a buffer for the image and, if required, the color-map.
|
||||||
* request return of a color-mapped image.
|
* 5) Call png_image_finish_read to read the image and, if required, the
|
||||||
* 5) Allocate a buffer for the image.
|
* color-map into your buffers.
|
||||||
* 6) Call png_image_finish_read to read the image into your buffer.
|
|
||||||
*
|
*
|
||||||
* There are no restrictions on the format of the PNG input itself; all valid
|
* 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
|
* color types, bit depths, and interlace methods are acceptable, and the
|
||||||
* input image is transformed as necessary to the requested in-memory format
|
* 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
|
* 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
|
* request a color-mapped image from a PNG that is full-color or makes
|
||||||
* the transformation is extremely lossy and the result may look terrible.
|
* 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:
|
* To write a PNG file using the simplified API:
|
||||||
*
|
*
|
||||||
* 1) Declare a 'png_image' structure on the stack and memset() it to all zero.
|
* 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
|
* 2) Initialize the members of the structure that describe the image, setting
|
||||||
* the 'format' member to the format of the image samples.
|
* the 'format' member to the format of the image samples.
|
||||||
* 3) [Optionally] call png_image_write_colormap to set the image color-map if
|
* 3) Call the appropriate png_image_write... function with a pointer to the
|
||||||
* the data to be written is color-mapped.
|
* image and, if necessary, the color-map to write the PNG data.
|
||||||
* 4) Call the appropriate png_image_write... function with a pointer to the
|
|
||||||
* image to write the PNG data.
|
|
||||||
*
|
*
|
||||||
* png_image is a structure that describes the in-memory format of an image
|
* 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:
|
* need to write:
|
||||||
*/
|
*/
|
||||||
|
#define PNG_IMAGE_VERSION 1
|
||||||
|
|
||||||
typedef struct png_control *png_controlp;
|
typedef struct png_control *png_controlp;
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
png_uint_32 width; /* Image width in pixels (columns) */
|
png_controlp opaque; /* Initialize to NULL, free with png_image_free */
|
||||||
png_uint_32 height; /* Image height in pixels (rows) */
|
png_uint_32 version; /* Set to PNG_IMAGE_VERSION */
|
||||||
png_uint_32 format; /* Image format as defined below */
|
png_uint_32 width; /* Image width in pixels (columns) */
|
||||||
png_uint_32 flags; /* A bit mask containing informational flags */
|
png_uint_32 height; /* Image height in pixels (rows) */
|
||||||
png_controlp opaque; /* Initialize to NULL, free with png_image_free */
|
png_uint_32 format; /* Image format as defined below */
|
||||||
|
png_uint_32 flags; /* A bit mask containing informational flags */
|
||||||
/* The following is only used for write; initialize it to NULL */
|
png_uint_32 colormap_entries;
|
||||||
png_const_bytep colormap; /* A pointer to the application color-map */
|
/* Number of entries in the color-map */
|
||||||
|
|
||||||
/* In the event of an error or warning the following field will be set to a
|
/* 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
|
* non-zero value and the 'message' field will contain a '\0' terminated
|
||||||
@ -2706,15 +2705,15 @@ typedef struct
|
|||||||
char message[64];
|
char message[64];
|
||||||
} png_image, *png_imagep;
|
} png_image, *png_imagep;
|
||||||
|
|
||||||
/* The pixels (samples) of the image have one to four channels whose components
|
/* The samples of the image have one to four channels whose components have
|
||||||
* have original values in the range 0 to 1.0:
|
* original values in the range 0 to 1.0:
|
||||||
*
|
*
|
||||||
* 1: A single gray or luminance channel (G).
|
* 1: A single gray or luminance channel (G).
|
||||||
* 2: A gray/luminance channel and an alpha channel (GA).
|
* 2: A gray/luminance channel and an alpha channel (GA).
|
||||||
* 3: Three red, green, blue color channels (RGB).
|
* 3: Three red, green, blue color channels (RGB).
|
||||||
* 4: Three color channels and an alpha channel (RGBA).
|
* 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
|
* 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
|
* 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
|
* channel: the color/gray channels are scaled (pre-multiplied) by the alpha
|
||||||
* value.
|
* value.
|
||||||
*
|
*
|
||||||
* When a color-mapped image is used as a result of calling
|
* The samples are either contained directly in the image data, between 1 and 8
|
||||||
* png_image_read_colormap or png_image_write_colormap the channels are encoded
|
* bytes per pixel according to the encoding, or are held in a color-map indexed
|
||||||
* in the color-map and the descriptions above apply to the color-map entries.
|
* by bytes in the image data. In the case of a color-map the color-map entries
|
||||||
* The image data is encoded as small integers, value 0..255, that index the
|
* are individual samples, encoded as above, and the image data has one byte per
|
||||||
* entries in the color-map. One integer (one byte) is stored for each pixel.
|
* pixel to select the relevant sample from the color-map.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* PNG_FORMAT_*
|
/* PNG_FORMAT_*
|
||||||
*
|
*
|
||||||
* #defines to be used in png_image::format. Each #define identifies a
|
* #defines to be used in png_image::format. Each #define identifies a
|
||||||
* particular layout of channel data and, if present, alpha values. There are
|
* particular layout of sample data and, if present, alpha values. There are
|
||||||
* separate defines for each of the two channel encodings.
|
* separate defines for each of the two component encodings.
|
||||||
*
|
*
|
||||||
* A format is built up using single bit flag values. Not all combinations are
|
* A format is built up using single bit flag values. All combinations are
|
||||||
* valid: use the bit flag values below for testing a format returned by the
|
* valid. Formats can be built up from the flag values or you can use one of
|
||||||
* read APIs, but set formats from the derived values.
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* PNG_SIMPLIFIED_{READ,WRITE}_{BGR,AFIRST}_SUPPORTED
|
||||||
*/
|
*/
|
||||||
#define PNG_FORMAT_FLAG_ALPHA 0x01U /* format with an alpha channel */
|
#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_COLOR 0x02U /* color format: otherwise grayscale */
|
||||||
#define PNG_FORMAT_FLAG_LINEAR 0x04U /* 2 byte channels else 1 byte */
|
#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
|
#ifdef PNG_FORMAT_BGR_SUPPORTED
|
||||||
# define PNG_FORMAT_FLAG_BGR 0x10U /* BGR colors, else order is RGB */
|
# 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 */
|
# define PNG_FORMAT_FLAG_AFIRST 0x20U /* alpha channel comes first */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Supported formats are as follows. Future versions of libpng may support more
|
/* Commonly used formats have predefined macros.
|
||||||
* 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.
|
|
||||||
*
|
*
|
||||||
* First the single byte formats:
|
* First the single byte (sRGB) formats:
|
||||||
*/
|
*/
|
||||||
#define PNG_FORMAT_GRAY 0
|
#define PNG_FORMAT_GRAY 0
|
||||||
#define PNG_FORMAT_GA PNG_FORMAT_FLAG_ALPHA
|
#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)
|
#define PNG_FORMAT_ABGR (PNG_FORMAT_BGRA|PNG_FORMAT_FLAG_AFIRST)
|
||||||
|
|
||||||
/* Then the linear 2-byte formats. When naming these "Y" is used to
|
/* Then the linear 2-byte formats. When naming these "Y" is used to
|
||||||
* indicate a luminance (gray) channel. The component order within the pixel
|
* indicate a luminance (gray) channel.
|
||||||
* is always the same - there is no provision for swapping the order of the
|
|
||||||
* components in the linear format.
|
|
||||||
*/
|
*/
|
||||||
#define PNG_FORMAT_LINEAR_Y PNG_FORMAT_FLAG_LINEAR
|
#define PNG_FORMAT_LINEAR_Y PNG_FORMAT_FLAG_LINEAR
|
||||||
#define PNG_FORMAT_LINEAR_Y_ALPHA (PNG_FORMAT_FLAG_LINEAR|PNG_FORMAT_FLAG_ALPHA)
|
#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 \
|
#define PNG_FORMAT_LINEAR_RGB_ALPHA \
|
||||||
(PNG_FORMAT_FLAG_LINEAR|PNG_FORMAT_FLAG_COLOR|PNG_FORMAT_FLAG_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,
|
/* With color-mapped formats the image data is one byte for each pixel, the byte
|
||||||
* as appropriate after setting png_image::format to the format of the color-map
|
* is an index into the color-map which is formatted as above. To obtain a
|
||||||
* to be read or written. Applications may check the value of
|
* color-mapped format it is sufficient just to add the PNG_FOMAT_FLAG_COLORMAP
|
||||||
* PNG_FORMAT_FLAG_COLORMAP to see if they have called the colormap API. The
|
* to one of the above definitions, or you can use one of the definitions below.
|
||||||
* format of the color-map may be extracted using the following macro.
|
|
||||||
*/
|
*/
|
||||||
#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
|
/* PNG_IMAGE macros
|
||||||
*
|
*
|
||||||
@ -2822,9 +2822,9 @@ typedef struct
|
|||||||
* structure. The PNG_IMAGE_SAMPLE_ macros return values appropriate to the
|
* structure. The PNG_IMAGE_SAMPLE_ macros return values appropriate to the
|
||||||
* actual image sample values - either the entries in the color-map or 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
|
* pixels in the image. The PNG_IMAGE_PIXEL_ macros return corresponding values
|
||||||
* for the pixels and will always return 1 after a call to
|
* for the pixels and will always return 1 for color-mapped formats. The
|
||||||
* png_image_{read,write}_colormap. The remaining macros return information
|
* remaining macros return information about the rows in the image and the
|
||||||
* about the rows in the image and the complete image.
|
* complete image.
|
||||||
*
|
*
|
||||||
* NOTE: All the macros that take a png_image::format parameter are compile time
|
* 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
|
* constants if the format parameter is, itself, a constant. Therefore these
|
||||||
@ -2841,7 +2841,7 @@ typedef struct
|
|||||||
#define PNG_IMAGE_SAMPLE_COMPONENT_SIZE(fmt)\
|
#define PNG_IMAGE_SAMPLE_COMPONENT_SIZE(fmt)\
|
||||||
((((fmt) & PNG_FORMAT_FLAG_LINEAR) >> 2)+1)
|
((((fmt) & PNG_FORMAT_FLAG_LINEAR) >> 2)+1)
|
||||||
/* Return the size in bytes of a single component of a pixel or color-map
|
/* 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)\
|
#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.
|
* 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)
|
#define PNG_IMAGE_MAXIMUM_COLORMAP_COMPONENTS(fmt)\
|
||||||
/* The size of the color-map required by the format; this is the size of the
|
(PNG_IMAGE_SAMPLE_CHANNELS(fmt) * 256)
|
||||||
* color-map buffer passed to the png_image_{read,write}_colormap APIs, it is
|
/* The maximum size of the color-map required by the format expressed in a
|
||||||
* a fixed number determined by the format so can easily be allocated on the
|
* count of components. This can be used to compile-time allocate a
|
||||||
* stack if necessary.
|
* 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 */
|
/* Corresponding information about the pixels */
|
||||||
@ -2898,6 +2906,14 @@ typedef struct
|
|||||||
* the row stride is the minimum stride required for the image.
|
* 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_*
|
/* PNG_IMAGE_FLAG_*
|
||||||
*
|
*
|
||||||
* Flags containing additional information about the image are held in the
|
* 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.
|
* 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
|
#ifdef PNG_SIMPLIFIED_READ_SUPPORTED
|
||||||
/* READ APIs
|
/* 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));
|
png_const_voidp memory, png_size_t size));
|
||||||
/* The PNG header is read from the given memory buffer. */
|
/* 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_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
|
/* Finish reading the image into the supplied buffer and clean up the
|
||||||
* png_image structure.
|
* 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,
|
* onto the buffer. The value is an sRGB color to use for the background,
|
||||||
* for grayscale output the green channel is used.
|
* for grayscale output the green channel is used.
|
||||||
*
|
*
|
||||||
* If png_image_read_colormap has been called the value of background must be
|
* background must be supplied when an alpha channel must be removed from a
|
||||||
* the same as that passed to the colormap call or the resultant image pixels
|
* single byte color-mapped output format, in other words if:
|
||||||
* are implementation defined and may vary between libpng minor releases.
|
*
|
||||||
|
* 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
|
* 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));
|
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
|
/* WRITE APIS
|
||||||
* ----------
|
* ----------
|
||||||
* For write you must initialize a png_image structure to describe the image to
|
* 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
|
* opaque: must be initialized to NULL
|
||||||
* colormap: must be initialized to NULL
|
|
||||||
* width: image width in pixels
|
* width: image width in pixels
|
||||||
* height: image height in rows
|
* 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
|
* 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
|
* PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB for color format images where the RGB
|
||||||
* values do not correspond to the colors in sRGB.
|
* 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,
|
PNG_EXPORT(239, int, png_image_write_to_file, (png_imagep image,
|
||||||
const char *file, int convert_to_8bit, const void *buffer,
|
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. */
|
/* Write the image to the named file. */
|
||||||
|
|
||||||
PNG_EXPORT(240, int, png_image_write_to_stdio, (png_imagep image, FILE *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*). */
|
/* Write the image to the given (FILE*). */
|
||||||
|
|
||||||
/* With all write APIs if image is in one of the linear formats with 16-bit data
|
/* With both write APIs if image is in one of the linear formats with 16-bit
|
||||||
* then setting convert_to_8_bit will cause the output to be an 8-bit PNG gamma
|
* data then setting convert_to_8_bit will cause the output to be an 8-bit PNG
|
||||||
* encoded according to the sRGB specification, otherwise a 16-bit linear
|
* gamma encoded according to the sRGB specification, otherwise a 16-bit linear
|
||||||
* encoded PNG file is written.
|
* encoded PNG file is written.
|
||||||
*
|
*
|
||||||
* With color-mapped data png_image_write_colormap must be called. The palette
|
* With color-mapped data formats the colormap parameter point to a color-map
|
||||||
* may contain linear (16-bit) entries, these will be converted to sRGB values
|
* with at least image->colormap_entries encoded in the specified format. If
|
||||||
* regardless of the setting of convert_to_8_bit.
|
* 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
|
* 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
|
* 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.
|
* scripts/symbols.def as well.
|
||||||
*/
|
*/
|
||||||
#ifdef PNG_EXPORT_LAST_ORDINAL
|
#ifdef PNG_EXPORT_LAST_ORDINAL
|
||||||
PNG_EXPORT_LAST_ORDINAL(243);
|
PNG_EXPORT_LAST_ORDINAL(241);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#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
|
#ifdef PNG_SIMPLIFIED_READ_SUPPORTED
|
||||||
extern /*PRIVATE*/ PNG_CONST_DATA png_uint_16 png_sRGB_table[256];
|
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,
|
/* 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
|
#endif
|
||||||
|
|
||||||
extern /*PRIVATE*/ PNG_CONST_DATA png_uint_16 png_sRGB_base[512];
|
extern /*PRIVATE*/ PNG_CONST_DATA png_uint_16 png_sRGB_base[512];
|
||||||
extern /*PRIVATE*/ PNG_CONST_DATA png_byte png_sRGB_delta[512];
|
extern /*PRIVATE*/ PNG_CONST_DATA png_byte png_sRGB_delta[512];
|
||||||
|
|
||||||
#define PNG_sRGB_FROM_LINEAR(linear) ((png_sRGB_base[(linear)>>15] +\
|
#define PNG_sRGB_FROM_LINEAR(linear) ((png_byte)((png_sRGB_base[(linear)>>15] +\
|
||||||
((((linear)&0x7fff)*png_sRGB_delta[(linear)>>15])>>12)) >> 8)
|
((((linear)&0x7fff)*png_sRGB_delta[(linear)>>15])>>12)) >> 8))
|
||||||
/* Given a value 'linear' in the range 0..255*65535 calculate the 8-bit sRGB
|
/* 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
|
* encoded value with maximum error 0.646365. Note that the input is not a
|
||||||
* 16-bit value; it has been multiplied by 255! */
|
* 16-bit value; it has been multiplied by 255! */
|
||||||
#endif /* PNG_SIMPLIFIED_READ/WRITE */
|
#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 */
|
/* Added to libpng-1.2.6 JB */
|
||||||
#define PNG_ROWBYTES(pixel_bits, width) \
|
#define PNG_ROWBYTES(pixel_bits, width) \
|
||||||
((pixel_bits) >= 8 ? \
|
((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. */
|
/* The internal structure that png_image::opaque points to. */
|
||||||
typedef struct png_control
|
typedef struct png_control
|
||||||
{
|
{
|
||||||
png_structp png_ptr;
|
png_structp png_ptr;
|
||||||
png_infop info_ptr;
|
png_infop info_ptr;
|
||||||
png_voidp error_buf; /* Always a jmp_buf at present. */
|
png_voidp error_buf; /* Always a jmp_buf at present. */
|
||||||
|
|
||||||
png_const_bytep memory; /* Memory buffer. */
|
png_const_bytep memory; /* Memory buffer. */
|
||||||
png_size_t size; /* Size of the memory buffer. */
|
png_size_t size; /* Size of the memory buffer. */
|
||||||
|
|
||||||
unsigned int for_write :1; /* Otherwise it is a read structure */
|
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 owned_file :1; /* We own the file in io_ptr */
|
||||||
} png_control;
|
} 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
|
/* 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.
|
* 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
|
* NOTE: this discards the low 16 bits of the user supplied background
|
||||||
* color, but until expand_16 works properly there is no choice!
|
* 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.red);
|
||||||
CHOP(png_ptr->background.green);
|
CHOP(png_ptr->background.green);
|
||||||
CHOP(png_ptr->background.blue);
|
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");
|
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: */
|
/* Arguments to png_image_write_main: */
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
@ -1594,6 +1568,7 @@ typedef struct
|
|||||||
png_imagep image;
|
png_imagep image;
|
||||||
png_const_voidp buffer;
|
png_const_voidp buffer;
|
||||||
png_int_32 row_stride;
|
png_int_32 row_stride;
|
||||||
|
png_const_voidp colormap;
|
||||||
int convert_to_8bit;
|
int convert_to_8bit;
|
||||||
/* Local variables: */
|
/* Local variables: */
|
||||||
png_const_voidp first_row;
|
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
|
/* 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
|
* is present it must be removed from the components, the components are then
|
||||||
* written in sRGB encoding. No components are added or removed.
|
* 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
|
static int
|
||||||
png_write_image_8bit(png_voidp argument)
|
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 */
|
if (aindex != 0) while (out_ptr < row_end) /* Alpha channel case */
|
||||||
{
|
{
|
||||||
png_uint_16 alpha = in_ptr[aindex];
|
png_uint_16 alpha = in_ptr[aindex];
|
||||||
|
png_byte alphabyte = (png_byte)PNG_DIV257(alpha);
|
||||||
png_uint_32 reciprocal = 0;
|
png_uint_32 reciprocal = 0;
|
||||||
int c;
|
int c;
|
||||||
|
|
||||||
/* Scale and write the alpha channel. See pngrtran.c
|
/* Scale and write the alpha channel. */
|
||||||
* png_do_scale_16_to_8 for a discussion of this calculation. The
|
out_ptr[aindex] = alphabyte;
|
||||||
* code here has machine native values, so use:
|
|
||||||
*
|
|
||||||
* (V * 255 + 32895) >> 16
|
|
||||||
*/
|
|
||||||
out_ptr[aindex] = (png_byte)((alpha * 255 + 32895) >> 16);
|
|
||||||
|
|
||||||
/* Calculate a reciprocal. As above the calculation can be done to
|
if (alphabyte > 0 && alphabyte < 255)
|
||||||
* 15 bits of accuracy, however the output needs to be scaled in the
|
reciprocal = UNP_RECIPROCAL(alpha);
|
||||||
* range 0..255*65535, so include that scaling here.
|
|
||||||
*/
|
|
||||||
if (alpha > 0 && alpha < 65535)
|
|
||||||
reciprocal = (((0xffff*0xff)<<7)+(alpha>>1))/alpha;
|
|
||||||
|
|
||||||
c = channels;
|
c = channels;
|
||||||
do /* always at least one channel */
|
do /* always at least one channel */
|
||||||
{
|
*out_ptr++ = png_unpremultiply(*in_ptr++, alpha, reciprocal);
|
||||||
/* 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;
|
|
||||||
}
|
|
||||||
while (--c > 0);
|
while (--c > 0);
|
||||||
|
|
||||||
/* Skip to next component (skip the intervening alpha channel) */
|
/* Skip to next component (skip the intervening alpha channel) */
|
||||||
@ -1846,6 +1829,151 @@ png_write_image_8bit(png_voidp argument)
|
|||||||
return 1;
|
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
|
static int
|
||||||
png_image_write_main(png_voidp argument)
|
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_inforp info_ptr = image->opaque->info_ptr;
|
||||||
png_uint_32 format = image->format;
|
png_uint_32 format = image->format;
|
||||||
|
|
||||||
int linear = (format & PNG_FORMAT_FLAG_LINEAR) != 0; /* input */
|
int colormap = (format & PNG_FORMAT_FLAG_COLORMAP) != 0;
|
||||||
int alpha = (format & PNG_FORMAT_FLAG_ALPHA) != 0;
|
int linear = !colormap && (format & PNG_FORMAT_FLAG_LINEAR) != 0; /* input */
|
||||||
int write_16bit = linear && !display->convert_to_8bit;
|
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. */
|
/* Default the 'row_stride' parameter if required. */
|
||||||
if (display->row_stride == 0)
|
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. */
|
/* Set the required transforms then write the rows in the correct order. */
|
||||||
if (format & PNG_FORMAT_FLAG_COLORMAP)
|
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
|
else
|
||||||
png_set_IHDR(png_ptr, info_ptr, image->width, image->height,
|
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
|
* must still be called before. Just set the color space information, never
|
||||||
* write an interlaced image.
|
* write an interlaced image.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (write_16bit)
|
if (write_16bit)
|
||||||
{
|
{
|
||||||
/* The gamma here is 1.0 (linear) and the cHRM chunk matches sRGB. */
|
/* 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
|
# ifdef PNG_SIMPLIFIED_WRITE_BGR_SUPPORTED
|
||||||
if (format & PNG_FORMAT_FLAG_BGR)
|
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);
|
png_set_bgr(png_ptr);
|
||||||
format &= ~PNG_FORMAT_FLAG_BGR;
|
format &= ~PNG_FORMAT_FLAG_BGR;
|
||||||
}
|
}
|
||||||
@ -1932,15 +2078,21 @@ png_image_write_main(png_voidp argument)
|
|||||||
# ifdef PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED
|
# ifdef PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED
|
||||||
if (format & PNG_FORMAT_FLAG_AFIRST)
|
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);
|
png_set_swap_alpha(png_ptr);
|
||||||
format &= ~PNG_FORMAT_FLAG_AFIRST;
|
format &= ~PNG_FORMAT_FLAG_AFIRST;
|
||||||
}
|
}
|
||||||
# endif
|
# 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. */
|
/* That should have handled all (both) the transforms. */
|
||||||
if ((format & ~(png_uint_32)(PNG_FORMAT_FLAG_COLOR | PNG_FORMAT_FLAG_LINEAR |
|
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");
|
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
|
* 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.
|
* 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_bytep row = png_voidcast(png_bytep, png_malloc(png_ptr,
|
||||||
png_get_rowbytes(png_ptr, info_ptr)));
|
png_get_rowbytes(png_ptr, info_ptr)));
|
||||||
@ -2003,10 +2155,10 @@ png_image_write_main(png_voidp argument)
|
|||||||
|
|
||||||
int PNGAPI
|
int PNGAPI
|
||||||
png_image_write_to_stdio(png_imagep image, FILE *file, int convert_to_8bit,
|
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*). */
|
/* Write the image to the given (FILE*). */
|
||||||
if (image != NULL)
|
if (image != NULL || image->version != PNG_IMAGE_VERSION)
|
||||||
{
|
{
|
||||||
if (file != NULL)
|
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.image = image;
|
||||||
display.buffer = buffer;
|
display.buffer = buffer;
|
||||||
display.row_stride = row_stride;
|
display.row_stride = row_stride;
|
||||||
|
display.colormap = colormap;
|
||||||
display.convert_to_8bit = convert_to_8bit;
|
display.convert_to_8bit = convert_to_8bit;
|
||||||
|
|
||||||
result = png_safe_execute(image, png_image_write_main, &display);
|
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
|
int PNGAPI
|
||||||
png_image_write_to_file(png_imagep image, const char *file_name,
|
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. */
|
/* Write the image to the named file. */
|
||||||
if (image != NULL)
|
if (image != NULL || image->version != PNG_IMAGE_VERSION)
|
||||||
{
|
{
|
||||||
if (file_name != NULL)
|
if (file_name != NULL)
|
||||||
{
|
{
|
||||||
@ -2059,7 +2213,7 @@ png_image_write_to_file(png_imagep image, const char *file_name,
|
|||||||
if (fp != NULL)
|
if (fp != NULL)
|
||||||
{
|
{
|
||||||
if (png_image_write_to_stdio(image, fp, convert_to_8bit, buffer,
|
if (png_image_write_to_stdio(image, fp, convert_to_8bit, buffer,
|
||||||
row_stride))
|
row_stride, colormap))
|
||||||
{
|
{
|
||||||
int error; /* from fflush/fclose */
|
int error; /* from fflush/fclose */
|
||||||
|
|
||||||
|
|||||||
@ -247,5 +247,3 @@ EXPORTS
|
|||||||
png_image_write_to_file @239
|
png_image_write_to_file @239
|
||||||
png_image_write_to_stdio @240
|
png_image_write_to_stdio @240
|
||||||
png_convert_to_rfc1123_buffer @241
|
png_convert_to_rfc1123_buffer @241
|
||||||
png_image_read_colormap @242
|
|
||||||
png_image_write_colormap @243
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user