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 | ||||||
|  | |||||||
							
								
								
									
										222
									
								
								png.h
									
									
									
									
									
								
							
							
						
						
									
										222
									
								
								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_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  width;     /* Image width in pixels (columns) */ | ||||||
|    png_uint_32  height;    /* Image height in pixels (rows) */ |    png_uint_32  height;    /* Image height in pixels (rows) */ | ||||||
|    png_uint_32  format;    /* Image format as defined below */ |    png_uint_32  format;    /* Image format as defined below */ | ||||||
|    png_uint_32  flags;     /* A bit mask containing informational flags */ |    png_uint_32  flags;     /* A bit mask containing informational flags */ | ||||||
|    png_controlp opaque; /* Initialize to NULL, free with png_image_free */ |    png_uint_32  colormap_entries; | ||||||
| 
 |                            /* Number of entries in the color-map */ | ||||||
|    /* The following is only used for write; initialize it to NULL */ |  | ||||||
|    png_const_bytep colormap; /* A pointer to the application 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 | ||||||
|  | |||||||
							
								
								
									
										20
									
								
								pngpriv.h
									
									
									
									
									
								
							
							
						
						
									
										20
									
								
								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 ? \ | ||||||
| @ -1633,6 +1644,9 @@ typedef struct png_control | |||||||
|    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
	 John Bowler
						John Bowler