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