summaryrefslogtreecommitdiff
path: root/lodepng.h
diff options
context:
space:
mode:
authorTom Smeding <tom.smeding@gmail.com>2020-05-05 17:41:14 +0200
committerTom Smeding <tom.smeding@gmail.com>2020-05-05 17:41:14 +0200
commitc4d58222e0c396585ae19301796097fde4d3f19d (patch)
tree4b888aa3412ad2e3adfa25fe7a88c358597c86a5 /lodepng.h
parent6878d573e50cca6ad917b67d596e5bb38c93b42a (diff)
Upgrade lodepng
Diffstat (limited to 'lodepng.h')
-rw-r--r--lodepng.h456
1 files changed, 316 insertions, 140 deletions
diff --git a/lodepng.h b/lodepng.h
index 8e0f742..a386459 100644
--- a/lodepng.h
+++ b/lodepng.h
@@ -1,7 +1,7 @@
/*
-LodePNG version 20180326
+LodePNG version 20200306
-Copyright (c) 2005-2018 Lode Vandevenne
+Copyright (c) 2005-2020 Lode Vandevenne
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
@@ -44,36 +44,44 @@ the custom_zlib field of the compress and decompress settings*/
#ifndef LODEPNG_NO_COMPILE_ZLIB
#define LODEPNG_COMPILE_ZLIB
#endif
+
/*png encoder and png decoder*/
#ifndef LODEPNG_NO_COMPILE_PNG
#define LODEPNG_COMPILE_PNG
#endif
+
/*deflate&zlib decoder and png decoder*/
#ifndef LODEPNG_NO_COMPILE_DECODER
#define LODEPNG_COMPILE_DECODER
#endif
+
/*deflate&zlib encoder and png encoder*/
#ifndef LODEPNG_NO_COMPILE_ENCODER
#define LODEPNG_COMPILE_ENCODER
#endif
+
/*the optional built in harddisk file loading and saving functions*/
#ifndef LODEPNG_NO_COMPILE_DISK
#define LODEPNG_COMPILE_DISK
#endif
+
/*support for chunks other than IHDR, IDAT, PLTE, tRNS, IEND: ancillary and unknown chunks*/
#ifndef LODEPNG_NO_COMPILE_ANCILLARY_CHUNKS
#define LODEPNG_COMPILE_ANCILLARY_CHUNKS
#endif
+
/*ability to convert error numerical codes to English text string*/
#ifndef LODEPNG_NO_COMPILE_ERROR_TEXT
#define LODEPNG_COMPILE_ERROR_TEXT
#endif
+
/*Compile the default allocators (C's free, malloc and realloc). If you disable this,
you can define the functions lodepng_free, lodepng_malloc and lodepng_realloc in your
source files with custom allocators.*/
#ifndef LODEPNG_NO_COMPILE_ALLOCATORS
#define LODEPNG_COMPILE_ALLOCATORS
#endif
+
/*compile the C++ version (you can disable the C++ wrapper here even when compiling for C++)*/
#ifdef __cplusplus
#ifndef LODEPNG_NO_COMPILE_CPP
@@ -87,14 +95,19 @@ source files with custom allocators.*/
#endif /*LODEPNG_COMPILE_CPP*/
#ifdef LODEPNG_COMPILE_PNG
-/*The PNG color types (also used for raw).*/
-typedef enum LodePNGColorType
-{
- LCT_GREY = 0, /*greyscale: 1,2,4,8,16 bit*/
+/*The PNG color types (also used for raw image).*/
+typedef enum LodePNGColorType {
+ LCT_GREY = 0, /*grayscale: 1,2,4,8,16 bit*/
LCT_RGB = 2, /*RGB: 8,16 bit*/
LCT_PALETTE = 3, /*palette: 1,2,4,8 bit*/
- LCT_GREY_ALPHA = 4, /*greyscale with alpha: 8,16 bit*/
- LCT_RGBA = 6 /*RGB with alpha: 8,16 bit*/
+ LCT_GREY_ALPHA = 4, /*grayscale with alpha: 8,16 bit*/
+ LCT_RGBA = 6, /*RGB with alpha: 8,16 bit*/
+ /*LCT_MAX_OCTET_VALUE lets the compiler allow this enum to represent any invalid
+ byte value from 0 to 255 that could be present in an invalid PNG file header. Do
+ not use, compare with or set the name LCT_MAX_OCTET_VALUE, instead either use
+ the valid color type names above, or numeric values like 1 or 7 when checking for
+ particular disallowed color type byte values, or cast to integer to print it.*/
+ LCT_MAX_OCTET_VALUE = 255
} LodePNGColorType;
#ifdef LODEPNG_COMPILE_DECODER
@@ -196,8 +209,7 @@ unsigned lodepng_encode24_file(const char* filename,
#ifdef LODEPNG_COMPILE_CPP
-namespace lodepng
-{
+namespace lodepng {
#ifdef LODEPNG_COMPILE_DECODER
/*Same as lodepng_decode_memory, but decodes to an std::vector. The colortype
is the format to output the pixels to. Default is RGBA 8-bit per channel.*/
@@ -253,18 +265,17 @@ const char* lodepng_error_text(unsigned code);
#ifdef LODEPNG_COMPILE_DECODER
/*Settings for zlib decompression*/
typedef struct LodePNGDecompressSettings LodePNGDecompressSettings;
-struct LodePNGDecompressSettings
-{
- /* Check LodePNGDecoderSettings for more ignorable errors */
+struct LodePNGDecompressSettings {
+ /* Check LodePNGDecoderSettings for more ignorable errors such as ignore_crc */
unsigned ignore_adler32; /*if 1, continue and don't give an error message if the Adler32 checksum is corrupted*/
+ unsigned ignore_nlen; /*ignore complement of len checksum in uncompressed blocks*/
/*use custom zlib decoder instead of built in one (default: null)*/
unsigned (*custom_zlib)(unsigned char**, size_t*,
const unsigned char*, size_t,
const LodePNGDecompressSettings*);
/*use custom deflate decoder instead of built in one (default: null)
- if custom_zlib is used, custom_deflate is ignored since only the built in
- zlib function will call custom_deflate*/
+ if custom_zlib is not null, custom_inflate is ignored (the zlib format uses deflate)*/
unsigned (*custom_inflate)(unsigned char**, size_t*,
const unsigned char*, size_t,
const LodePNGDecompressSettings*);
@@ -282,13 +293,12 @@ Settings for zlib compression. Tweaking these settings tweaks the balance
between speed and compression ratio.
*/
typedef struct LodePNGCompressSettings LodePNGCompressSettings;
-struct LodePNGCompressSettings /*deflate = compress*/
-{
+struct LodePNGCompressSettings /*deflate = compress*/ {
/*LZ77 related settings*/
unsigned btype; /*the block type for LZ (0, 1, 2 or 3, see zlib standard). Should be 2 for proper compression.*/
unsigned use_lz77; /*whether or not to use LZ77. Should be 1 for proper compression.*/
unsigned windowsize; /*must be a power of two <= 32768. higher compresses more but is slower. Default value: 2048.*/
- unsigned minmatch; /*mininum lz77 length. 3 is normally best, 6 can be better for some PNGs. Default: 0*/
+ unsigned minmatch; /*minimum lz77 length. 3 is normally best, 6 can be better for some PNGs. Default: 0*/
unsigned nicematch; /*stop searching if >= this length found. Set to 258 for best compression. Default: 128*/
unsigned lazymatching; /*use lazy matching: better compression but a bit slower. Default: true*/
@@ -316,8 +326,7 @@ Color mode of an image. Contains all information required to decode the pixel
bits to RGBA colors. This information is the same as used in the PNG file
format, and is used both for PNG and raw image data in LodePNG.
*/
-typedef struct LodePNGColorMode
-{
+typedef struct LodePNGColorMode {
/*header (IHDR)*/
LodePNGColorType colortype; /*color type, see PNG standard or documentation further in this header file*/
unsigned bitdepth; /*bits per sample, see PNG standard or documentation further in this header file*/
@@ -326,23 +335,25 @@ typedef struct LodePNGColorMode
palette (PLTE and tRNS)
Dynamically allocated with the colors of the palette, including alpha.
- When encoding a PNG, to store your colors in the palette of the LodePNGColorMode, first use
- lodepng_palette_clear, then for each color use lodepng_palette_add.
- If you encode an image without alpha with palette, don't forget to put value 255 in each A byte of the palette.
+ This field may not be allocated directly, use lodepng_color_mode_init first,
+ then lodepng_palette_add per color to correctly initialize it (to ensure size
+ of exactly 1024 bytes).
+
+ The alpha channels must be set as well, set them to 255 for opaque images.
When decoding, by default you can ignore this palette, since LodePNG already
fills the palette colors in the pixels of the raw RGBA output.
The palette is only supported for color type 3.
*/
- unsigned char* palette; /*palette in RGBARGBA... order. When allocated, must be either 0, or have size 1024*/
- size_t palettesize; /*palette size in number of colors (amount of bytes is 4 * palettesize)*/
+ unsigned char* palette; /*palette in RGBARGBA... order. Must be either 0, or when allocated must have 1024 bytes*/
+ size_t palettesize; /*palette size in number of colors (amount of used bytes is 4 * palettesize)*/
/*
transparent color key (tRNS)
This color uses the same bit depth as the bitdepth value in this struct, which can be 1-bit to 16-bit.
- For greyscale PNGs, r, g and b will all 3 be set to the same.
+ For grayscale PNGs, r, g and b will all 3 be set to the same.
When decoding, by default you can ignore this information, since LodePNG sets
pixels with this key to transparent already in the raw RGBA output.
@@ -350,7 +361,7 @@ typedef struct LodePNGColorMode
The color key is only supported for color types 0 and 2.
*/
unsigned key_defined; /*is a transparent color key given? 0 = false, 1 = true*/
- unsigned key_r; /*red/greyscale component of color key*/
+ unsigned key_r; /*red/grayscale component of color key*/
unsigned key_g; /*green component of color key*/
unsigned key_b; /*blue component of color key*/
} LodePNGColorMode;
@@ -360,6 +371,8 @@ void lodepng_color_mode_init(LodePNGColorMode* info);
void lodepng_color_mode_cleanup(LodePNGColorMode* info);
/*return value is error code (0 means no error)*/
unsigned lodepng_color_mode_copy(LodePNGColorMode* dest, const LodePNGColorMode* source);
+/* Makes a temporary LodePNGColorMode that does not need cleanup (no palette) */
+LodePNGColorMode lodepng_color_mode_make(LodePNGColorType colortype, unsigned bitdepth);
void lodepng_palette_clear(LodePNGColorMode* info);
/*add 1 color to the palette*/
@@ -371,7 +384,7 @@ unsigned lodepng_get_bpp(const LodePNGColorMode* info);
/*get the amount of color channels used, based on colortype in the struct.
If a palette is used, it counts as 1 channel.*/
unsigned lodepng_get_channels(const LodePNGColorMode* info);
-/*is it a greyscale type? (only colortype 0 or 4)*/
+/*is it a grayscale type? (only colortype 0 or 4)*/
unsigned lodepng_is_greyscale_type(const LodePNGColorMode* info);
/*has it got an alpha channel? (only colortype 2 or 6)*/
unsigned lodepng_is_alpha_type(const LodePNGColorMode* info);
@@ -393,8 +406,7 @@ size_t lodepng_get_raw_size(unsigned w, unsigned h, const LodePNGColorMode* colo
#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
/*The information of a Time chunk in PNG.*/
-typedef struct LodePNGTime
-{
+typedef struct LodePNGTime {
unsigned year; /*2 bytes used (0-65535)*/
unsigned month; /*1-12*/
unsigned day; /*1-31*/
@@ -405,28 +417,39 @@ typedef struct LodePNGTime
#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
/*Information about the PNG image, except pixels, width and height.*/
-typedef struct LodePNGInfo
-{
+typedef struct LodePNGInfo {
/*header (IHDR), palette (PLTE) and transparency (tRNS) chunks*/
unsigned compression_method;/*compression method of the original file. Always 0.*/
unsigned filter_method; /*filter method of the original file*/
- unsigned interlace_method; /*interlace method of the original file*/
+ unsigned interlace_method; /*interlace method of the original file: 0=none, 1=Adam7*/
LodePNGColorMode color; /*color type and bits, palette and transparency of the PNG file*/
#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
/*
- suggested background color chunk (bKGD)
- This color uses the same color mode as the PNG (except alpha channel), which can be 1-bit to 16-bit.
+ Suggested background color chunk (bKGD)
+
+ This uses the same color mode and bit depth as the PNG (except no alpha channel),
+ with values truncated to the bit depth in the unsigned integer.
+
+ For grayscale and palette PNGs, the value is stored in background_r. The values
+ in background_g and background_b are then unused.
- For greyscale PNGs, r, g and b will all 3 be set to the same. When encoding
- the encoder writes the red one. For palette PNGs: When decoding, the RGB value
- will be stored, not a palette index. But when encoding, specify the index of
- the palette in background_r, the other two are then ignored.
+ So when decoding, you may get these in a different color mode than the one you requested
+ for the raw pixels.
- The decoder does not use this background color to edit the color of pixels.
+ When encoding with auto_convert, you must use the color model defined in info_png.color for
+ these values. The encoder normally ignores info_png.color when auto_convert is on, but will
+ use it to interpret these values (and convert copies of them to its chosen color model).
+
+ When encoding, avoid setting this to an expensive color, such as a non-gray value
+ when the image is gray, or the compression will be worse since it will be forced to
+ write the PNG with a more expensive color mode (when auto_convert is on).
+
+ The decoder does not use this background color to edit the color of pixels. This is a
+ completely optional metadata feature.
*/
unsigned background_defined; /*is a suggested background color given?*/
- unsigned background_r; /*red component of suggested background color*/
+ unsigned background_r; /*red/gray/palette component of suggested background color*/
unsigned background_g; /*green component of suggested background color*/
unsigned background_b; /*blue component of suggested background color*/
@@ -437,6 +460,10 @@ typedef struct LodePNGInfo
text_strings, while text_keys are keywords that give a short description what
the actual text represents, e.g. Title, Author, Description, or anything else.
+ All the string fields below including keys, names and language tags are null terminated.
+ The PNG specification uses null characters for the keys, names and tags, and forbids null
+ characters to appear in the main text which is why we can use null termination everywhere here.
+
A keyword is minimum 1 character and maximum 79 characters long. It's
discouraged to use a single line length longer than 79 characters for texts.
@@ -469,11 +496,86 @@ typedef struct LodePNGInfo
unsigned phys_unit; /*may be 0 (unknown unit) or 1 (metre)*/
/*
- unknown chunks
- There are 3 buffers, one for each position in the PNG where unknown chunks can appear
- each buffer contains all unknown chunks for that position consecutively
- The 3 buffers are the unknown chunks between certain critical chunks:
- 0: IHDR-PLTE, 1: PLTE-IDAT, 2: IDAT-IEND
+ Color profile related chunks: gAMA, cHRM, sRGB, iCPP
+
+ LodePNG does not apply any color conversions on pixels in the encoder or decoder and does not interpret these color
+ profile values. It merely passes on the information. If you wish to use color profiles and convert colors, please
+ use these values with a color management library.
+
+ See the PNG, ICC and sRGB specifications for more information about the meaning of these values.
+ */
+
+ /* gAMA chunk: optional, overridden by sRGB or iCCP if those are present. */
+ unsigned gama_defined; /* Whether a gAMA chunk is present (0 = not present, 1 = present). */
+ unsigned gama_gamma; /* Gamma exponent times 100000 */
+
+ /* cHRM chunk: optional, overridden by sRGB or iCCP if those are present. */
+ unsigned chrm_defined; /* Whether a cHRM chunk is present (0 = not present, 1 = present). */
+ unsigned chrm_white_x; /* White Point x times 100000 */
+ unsigned chrm_white_y; /* White Point y times 100000 */
+ unsigned chrm_red_x; /* Red x times 100000 */
+ unsigned chrm_red_y; /* Red y times 100000 */
+ unsigned chrm_green_x; /* Green x times 100000 */
+ unsigned chrm_green_y; /* Green y times 100000 */
+ unsigned chrm_blue_x; /* Blue x times 100000 */
+ unsigned chrm_blue_y; /* Blue y times 100000 */
+
+ /*
+ sRGB chunk: optional. May not appear at the same time as iCCP.
+ If gAMA is also present gAMA must contain value 45455.
+ If cHRM is also present cHRM must contain respectively 31270,32900,64000,33000,30000,60000,15000,6000.
+ */
+ unsigned srgb_defined; /* Whether an sRGB chunk is present (0 = not present, 1 = present). */
+ unsigned srgb_intent; /* Rendering intent: 0=perceptual, 1=rel. colorimetric, 2=saturation, 3=abs. colorimetric */
+
+ /*
+ iCCP chunk: optional. May not appear at the same time as sRGB.
+
+ LodePNG does not parse or use the ICC profile (except its color space header field for an edge case), a
+ separate library to handle the ICC data (not included in LodePNG) format is needed to use it for color
+ management and conversions.
+
+ For encoding, if iCCP is present, gAMA and cHRM are recommended to be added as well with values that match the ICC
+ profile as closely as possible, if you wish to do this you should provide the correct values for gAMA and cHRM and
+ enable their '_defined' flags since LodePNG will not automatically compute them from the ICC profile.
+
+ For encoding, the ICC profile is required by the PNG specification to be an "RGB" profile for non-gray
+ PNG color types and a "GRAY" profile for gray PNG color types. If you disable auto_convert, you must ensure
+ the ICC profile type matches your requested color type, else the encoder gives an error. If auto_convert is
+ enabled (the default), and the ICC profile is not a good match for the pixel data, this will result in an encoder
+ error if the pixel data has non-gray pixels for a GRAY profile, or a silent less-optimal compression of the pixel
+ data if the pixels could be encoded as grayscale but the ICC profile is RGB.
+
+ To avoid this do not set an ICC profile in the image unless there is a good reason for it, and when doing so
+ make sure you compute it carefully to avoid the above problems.
+ */
+ unsigned iccp_defined; /* Whether an iCCP chunk is present (0 = not present, 1 = present). */
+ char* iccp_name; /* Null terminated string with profile name, 1-79 bytes */
+ /*
+ The ICC profile in iccp_profile_size bytes.
+ Don't allocate this buffer yourself. Use the init/cleanup functions
+ correctly and use lodepng_set_icc and lodepng_clear_icc.
+ */
+ unsigned char* iccp_profile;
+ unsigned iccp_profile_size; /* The size of iccp_profile in bytes */
+
+ /* End of color profile related chunks */
+
+
+ /*
+ unknown chunks: chunks not known by LodePNG, passed on byte for byte.
+
+ There are 3 buffers, one for each position in the PNG where unknown chunks can appear.
+ Each buffer contains all unknown chunks for that position consecutively.
+ The 3 positions are:
+ 0: between IHDR and PLTE, 1: between PLTE and IDAT, 2: between IDAT and IEND.
+
+ For encoding, do not store critical chunks or known chunks that are enabled with a "_defined" flag
+ above in here, since the encoder will blindly follow this and could then encode an invalid PNG file
+ (such as one with two IHDR chunks or the disallowed combination of sRGB with iCCP). But do use
+ this if you wish to store an ancillary chunk that is not supported by LodePNG (such as sPLT or hIST),
+ or any non-standard PNG chunk.
+
Do not allocate or traverse this data yourself. Use the chunk traversing functions declared
later, such as lodepng_chunk_next and lodepng_chunk_append, to read/write this struct.
*/
@@ -489,12 +591,16 @@ void lodepng_info_cleanup(LodePNGInfo* info);
unsigned lodepng_info_copy(LodePNGInfo* dest, const LodePNGInfo* source);
#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
-void lodepng_clear_text(LodePNGInfo* info); /*use this to clear the texts again after you filled them in*/
unsigned lodepng_add_text(LodePNGInfo* info, const char* key, const char* str); /*push back both texts at once*/
+void lodepng_clear_text(LodePNGInfo* info); /*use this to clear the texts again after you filled them in*/
-void lodepng_clear_itext(LodePNGInfo* info); /*use this to clear the itexts again after you filled them in*/
unsigned lodepng_add_itext(LodePNGInfo* info, const char* key, const char* langtag,
const char* transkey, const char* str); /*push back the 4 texts of 1 chunk at once*/
+void lodepng_clear_itext(LodePNGInfo* info); /*use this to clear the itexts again after you filled them in*/
+
+/*replaces if exists*/
+unsigned lodepng_set_icc(LodePNGInfo* info, const char* name, const unsigned char* profile, unsigned profile_size);
+void lodepng_clear_icc(LodePNGInfo* info); /*use this to clear the texts again after you filled them in*/
#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
/*
@@ -517,14 +623,17 @@ unsigned lodepng_convert(unsigned char* out, const unsigned char* in,
Settings for the decoder. This contains settings for the PNG and the Zlib
decoder, but not the Info settings from the Info structs.
*/
-typedef struct LodePNGDecoderSettings
-{
+typedef struct LodePNGDecoderSettings {
LodePNGDecompressSettings zlibsettings; /*in here is the setting to ignore Adler32 checksums*/
- /* Check LodePNGDecompressSettings for more ignorable errors */
+ /* Check LodePNGDecompressSettings for more ignorable errors such as ignore_adler32 */
unsigned ignore_crc; /*ignore CRC checksums*/
unsigned ignore_critical; /*ignore unknown critical chunks*/
unsigned ignore_end; /*ignore issues at end of file if possible (missing IEND chunk, too large chunk, ...)*/
+ /* TODO: make a system involving warnings with levels and a strict mode instead. Other potentially recoverable
+ errors: srgb rendering intent value, size of content of ancillary chunks, more than 79 characters for some
+ strings, placement/combination rules for ancillary chunks, crc of unknown chunks, allowed characters
+ in string keys, etc... */
unsigned color_convert; /*whether to convert the PNG to the color type you want. Default: yes*/
@@ -540,10 +649,14 @@ void lodepng_decoder_settings_init(LodePNGDecoderSettings* settings);
#ifdef LODEPNG_COMPILE_ENCODER
/*automatically use color type with less bits per pixel if losslessly possible. Default: AUTO*/
-typedef enum LodePNGFilterStrategy
-{
+typedef enum LodePNGFilterStrategy {
/*every filter at zero*/
- LFS_ZERO,
+ LFS_ZERO = 0,
+ /*every filter at 1, 2, 3 or 4 (paeth), unlike LFS_ZERO not a good choice, but for testing*/
+ LFS_ONE = 1,
+ LFS_TWO = 2,
+ LFS_THREE = 3,
+ LFS_FOUR = 4,
/*Use filter that gives minimum sum, as described in the official PNG filter heuristic.*/
LFS_MINSUM,
/*Use the filter type that gives smallest Shannon entropy for this scanline. Depending
@@ -558,36 +671,36 @@ typedef enum LodePNGFilterStrategy
LFS_PREDEFINED
} LodePNGFilterStrategy;
-/*Gives characteristics about the colors of the image, which helps decide which color model to use for encoding.
+/*Gives characteristics about the integer RGBA colors of the image (count, alpha channel usage, bit depth, ...),
+which helps decide which color model to use for encoding.
Used internally by default if "auto_convert" is enabled. Public because it's useful for custom algorithms.*/
-typedef struct LodePNGColorProfile
-{
- unsigned colored; /*not greyscale*/
+typedef struct LodePNGColorStats {
+ unsigned colored; /*not grayscale*/
unsigned key; /*image is not opaque and color key is possible instead of full alpha*/
unsigned short key_r; /*key values, always as 16-bit, in 8-bit case the byte is duplicated, e.g. 65535 means 255*/
unsigned short key_g;
unsigned short key_b;
unsigned alpha; /*image is not opaque and alpha channel or alpha palette required*/
- unsigned numcolors; /*amount of colors, up to 257. Not valid if bits == 16.*/
- unsigned char palette[1024]; /*Remembers up to the first 256 RGBA colors, in no particular order*/
- unsigned bits; /*bits per channel (not for palette). 1,2 or 4 for greyscale only. 16 if 16-bit per channel required.*/
-} LodePNGColorProfile;
-
-void lodepng_color_profile_init(LodePNGColorProfile* profile);
-
-/*Get a LodePNGColorProfile of the image.*/
-unsigned lodepng_get_color_profile(LodePNGColorProfile* profile,
- const unsigned char* image, unsigned w, unsigned h,
- const LodePNGColorMode* mode_in);
-/*The function LodePNG uses internally to decide the PNG color with auto_convert.
-Chooses an optimal color model, e.g. grey if only grey pixels, palette if < 256 colors, ...*/
-unsigned lodepng_auto_choose_color(LodePNGColorMode* mode_out,
- const unsigned char* image, unsigned w, unsigned h,
- const LodePNGColorMode* mode_in);
+ unsigned numcolors; /*amount of colors, up to 257. Not valid if bits == 16 or allow_palette is disabled.*/
+ unsigned char palette[1024]; /*Remembers up to the first 256 RGBA colors, in no particular order, only valid when numcolors is valid*/
+ unsigned bits; /*bits per channel (not for palette). 1,2 or 4 for grayscale only. 16 if 16-bit per channel required.*/
+ size_t numpixels;
+
+ /*user settings for computing/using the stats*/
+ unsigned allow_palette; /*default 1. if 0, disallow choosing palette colortype in auto_choose_color, and don't count numcolors*/
+ unsigned allow_greyscale; /*default 1. if 0, choose RGB or RGBA even if the image only has gray colors*/
+} LodePNGColorStats;
+
+void lodepng_color_stats_init(LodePNGColorStats* stats);
+
+/*Get a LodePNGColorStats of the image. The stats must already have been inited.
+Returns error code (e.g. alloc fail) or 0 if ok.*/
+unsigned lodepng_compute_color_stats(LodePNGColorStats* stats,
+ const unsigned char* image, unsigned w, unsigned h,
+ const LodePNGColorMode* mode_in);
/*Settings for the encoder.*/
-typedef struct LodePNGEncoderSettings
-{
+typedef struct LodePNGEncoderSettings {
LodePNGCompressSettings zlibsettings; /*settings for the zlib encoder, such as window size, ...*/
unsigned auto_convert; /*automatically choose output PNG color type. Default: true*/
@@ -623,8 +736,7 @@ void lodepng_encoder_settings_init(LodePNGEncoderSettings* settings);
#if defined(LODEPNG_COMPILE_DECODER) || defined(LODEPNG_COMPILE_ENCODER)
/*The settings, state and information for extended encoding and decoding.*/
-typedef struct LodePNGState
-{
+typedef struct LodePNGState {
#ifdef LODEPNG_COMPILE_DECODER
LodePNGDecoderSettings decoder; /*the decoding settings*/
#endif /*LODEPNG_COMPILE_DECODER*/
@@ -634,10 +746,6 @@ typedef struct LodePNGState
LodePNGColorMode info_raw; /*specifies the format in which you would like to get the raw pixel buffer*/
LodePNGInfo info_png; /*info of the PNG image obtained after decoding*/
unsigned error;
-#ifdef LODEPNG_COMPILE_CPP
- /* For the lodepng::State subclass. */
- virtual ~LodePNGState(){}
-#endif
} LodePNGState;
/*init, cleanup and copy functions to use with this struct*/
@@ -657,7 +765,7 @@ unsigned lodepng_decode(unsigned char** out, unsigned* w, unsigned* h,
/*
Read the PNG header, but not the actual data. This returns only the information
-that is in the header chunk of the PNG, such as width, height and color type. The
+that is in the IHDR chunk of the PNG, such as width, height and color type. The
information is placed in the info_png field of the LodePNGState.
*/
unsigned lodepng_inspect(unsigned* w, unsigned* h,
@@ -665,6 +773,20 @@ unsigned lodepng_inspect(unsigned* w, unsigned* h,
const unsigned char* in, size_t insize);
#endif /*LODEPNG_COMPILE_DECODER*/
+/*
+Reads one metadata chunk (other than IHDR) of the PNG file and outputs what it
+read in the state. Returns error code on failure.
+Use lodepng_inspect first with a new state, then e.g. lodepng_chunk_find_const
+to find the desired chunk type, and if non null use lodepng_inspect_chunk (with
+chunk_pointer - start_of_file as pos).
+Supports most metadata chunks from the PNG standard (gAMA, bKGD, tEXt, ...).
+Ignores unsupported, unknown, non-metadata or IHDR chunks (without error).
+Requirements: &in[pos] must point to start of a chunk, must use regular
+lodepng_inspect first since format of most other chunks depends on IHDR, and if
+there is a PLTE chunk, that one must be inspected before tRNS or bKGD.
+*/
+unsigned lodepng_inspect_chunk(LodePNGState* state, size_t pos,
+ const unsigned char* in, size_t insize);
#ifdef LODEPNG_COMPILE_ENCODER
/*This function allocates the out buffer with standard malloc and stores the size in *outsize.*/
@@ -678,11 +800,23 @@ The lodepng_chunk functions are normally not needed, except to traverse the
unknown chunks stored in the LodePNGInfo struct, or add new ones to it.
It also allows traversing the chunks of an encoded PNG file yourself.
-PNG standard chunk naming conventions:
-First byte: uppercase = critical, lowercase = ancillary
-Second byte: uppercase = public, lowercase = private
-Third byte: must be uppercase
-Fourth byte: uppercase = unsafe to copy, lowercase = safe to copy
+The chunk pointer always points to the beginning of the chunk itself, that is
+the first byte of the 4 length bytes.
+
+In the PNG file format, chunks have the following format:
+-4 bytes length: length of the data of the chunk in bytes (chunk itself is 12 bytes longer)
+-4 bytes chunk type (ASCII a-z,A-Z only, see below)
+-length bytes of data (may be 0 bytes if length was 0)
+-4 bytes of CRC, computed on chunk name + data
+
+The first chunk starts at the 8th byte of the PNG file, the entire rest of the file
+exists out of concatenated chunks with the above format.
+
+PNG standard chunk ASCII naming conventions:
+-First byte: uppercase = critical, lowercase = ancillary
+-Second byte: uppercase = public, lowercase = private
+-Third byte: must be uppercase
+-Fourth byte: uppercase = unsafe to copy, lowercase = safe to copy
*/
/*
@@ -717,24 +851,38 @@ unsigned lodepng_chunk_check_crc(const unsigned char* chunk);
/*generates the correct CRC from the data and puts it in the last 4 bytes of the chunk*/
void lodepng_chunk_generate_crc(unsigned char* chunk);
-/*iterate to next chunks. don't use on IEND chunk, as there is no next chunk then*/
-unsigned char* lodepng_chunk_next(unsigned char* chunk);
-const unsigned char* lodepng_chunk_next_const(const unsigned char* chunk);
+/*
+Iterate to next chunks, allows iterating through all chunks of the PNG file.
+Input must be at the beginning of a chunk (result of a previous lodepng_chunk_next call,
+or the 8th byte of a PNG file which always has the first chunk), or alternatively may
+point to the first byte of the PNG file (which is not a chunk but the magic header, the
+function will then skip over it and return the first real chunk).
+Will output pointer to the start of the next chunk, or at or beyond end of the file if there
+is no more chunk after this or possibly if the chunk is corrupt.
+Start this process at the 8th byte of the PNG file.
+In a non-corrupt PNG file, the last chunk should have name "IEND".
+*/
+unsigned char* lodepng_chunk_next(unsigned char* chunk, unsigned char* end);
+const unsigned char* lodepng_chunk_next_const(const unsigned char* chunk, const unsigned char* end);
+
+/*Finds the first chunk with the given type in the range [chunk, end), or returns NULL if not found.*/
+unsigned char* lodepng_chunk_find(unsigned char* chunk, unsigned char* end, const char type[5]);
+const unsigned char* lodepng_chunk_find_const(const unsigned char* chunk, const unsigned char* end, const char type[5]);
/*
Appends chunk to the data in out. The given chunk should already have its chunk header.
-The out variable and outlength are updated to reflect the new reallocated buffer.
+The out variable and outsize are updated to reflect the new reallocated buffer.
Returns error code (0 if it went ok)
*/
-unsigned lodepng_chunk_append(unsigned char** out, size_t* outlength, const unsigned char* chunk);
+unsigned lodepng_chunk_append(unsigned char** out, size_t* outsize, const unsigned char* chunk);
/*
Appends new chunk to out. The chunk to append is given by giving its length, type
and data separately. The type is a 4-letter string.
-The out variable and outlength are updated to reflect the new reallocated buffer.
+The out variable and outsize are updated to reflect the new reallocated buffer.
Returne error code (0 if it went ok)
*/
-unsigned lodepng_chunk_create(unsigned char** out, size_t* outlength, unsigned length,
+unsigned lodepng_chunk_create(unsigned char** out, size_t* outsize, unsigned length,
const char* type, const unsigned char* data);
@@ -818,15 +966,13 @@ unsigned lodepng_save_file(const unsigned char* buffer, size_t buffersize, const
#ifdef LODEPNG_COMPILE_CPP
/* The LodePNG C++ wrapper uses std::vectors instead of manually allocated memory buffers. */
-namespace lodepng
-{
+namespace lodepng {
#ifdef LODEPNG_COMPILE_PNG
-class State : public LodePNGState
-{
+class State : public LodePNGState {
public:
State();
State(const State& other);
- virtual ~State();
+ ~State();
State& operator=(const State& other);
};
@@ -894,16 +1040,21 @@ TODO:
[.] test if there are no memory leaks or security exploits - done a lot but needs to be checked often
[.] check compatibility with various compilers - done but needs to be redone for every newer version
[X] converting color to 16-bit per channel types
-[ ] read all public PNG chunk types (but never let the color profile and gamma ones touch RGB values)
+[X] support color profile chunk types (but never let them touch RGB values by default)
+[ ] support all public PNG chunk types (almost done except sBIT, sPLT and hIST)
[ ] make sure encoder generates no chunks with size > (2^31)-1
[ ] partial decoding (stream processing)
[X] let the "isFullyOpaque" function check color keys and transparent palettes too
[X] better name for the variables "codes", "codesD", "codelengthcodes", "clcl" and "lldl"
-[ ] don't stop decoding on errors like 69, 57, 58 (make warnings)
+[ ] allow treating some errors like warnings, when image is recoverable (e.g. 69, 57, 58)
[ ] make warnings like: oob palette, checksum fail, data after iend, wrong/unknown crit chunk, no null terminator in text, ...
+[ ] error messages with line numbers (and version)
+[ ] errors in state instead of as return code?
+[ ] new errors/warnings like suspiciously big decompressed ztxt or iccp chunk
[ ] let the C++ wrapper catch exceptions coming from the standard library and return LodePNG error codes
[ ] allow user to provide custom color conversion functions, e.g. for premultiplied alpha, padding bits or not, ...
[ ] allow user to give data (void*) to custom allocator
+[X] provide alternatives for C library functions not present on some platforms (memcpy, ...)
*/
#endif /*LODEPNG_H inclusion guard*/
@@ -998,8 +1149,10 @@ The following features are supported by the decoder:
*) zlib decompression (inflate)
*) zlib compression (deflate)
*) CRC32 and ADLER32 checksums
+*) colorimetric color profile conversions: currently experimentally available in lodepng_util.cpp only,
+ plus alternatively ability to pass on chroma/gamma/ICC profile information to other color management system.
*) handling of unknown chunks, allowing making a PNG editor that stores custom and unknown chunks.
-*) the following chunks are supported (generated/interpreted) by both encoder and decoder:
+*) the following chunks are supported by both encoder and decoder:
IHDR: header information
PLTE: color palette
IDAT: pixel data
@@ -1011,6 +1164,10 @@ The following features are supported by the decoder:
bKGD: suggested background color
pHYs: physical dimensions
tIME: modification time
+ cHRM: RGB chromaticities
+ gAMA: RGB gamma correction
+ iCCP: ICC color profile
+ sRGB: rendering intent
1.2. features not supported
---------------------------
@@ -1019,10 +1176,10 @@ The following features are _not_ supported:
*) some features needed to make a conformant PNG-Editor might be still missing.
*) partial loading/stream processing. All data must be available and is processed in one call.
-*) The following public chunks are not supported but treated as unknown chunks by LodePNG
- cHRM, gAMA, iCCP, sRGB, sBIT, hIST, sPLT
- Some of these are not supported on purpose: LodePNG wants to provide the RGB values
- stored in the pixels, not values modified by system dependent gamma or color models.
+*) The following public chunks are not (yet) supported but treated as unknown chunks by LodePNG:
+ sBIT
+ hIST
+ sPLT
2. C and C++ version
@@ -1096,7 +1253,7 @@ LodePNGColorMode info_raw
When decoding, here you can specify which color type you want
the resulting raw image to be. If this is different from the colortype of the
PNG, then the decoder will automatically convert the result. This conversion
-always works, except if you want it to convert a color PNG to greyscale or to
+always works, except if you want it to convert a color PNG to grayscale or to
a palette with missing colors.
By default, 32-bit color is used for the result.
@@ -1192,7 +1349,7 @@ can encode the colors of all pixels without information loss.
An important thing to note about LodePNG, is that the color type of the PNG, and
the color type of the raw image, are completely independent. By default, when
you decode a PNG, you get the result as a raw image in the color type you want,
-no matter whether the PNG was encoded with a palette, greyscale or RGBA color.
+no matter whether the PNG was encoded with a palette, grayscale or RGBA color.
And if you encode an image, by default LodePNG will automatically choose the PNG
color type that gives good compression based on the values of colors and amount
of colors in the image. It can be configured to let you control it instead as
@@ -1200,10 +1357,10 @@ well, though.
To be able to do this, LodePNG does conversions from one color mode to another.
It can convert from almost any color type to any other color type, except the
-following conversions: RGB to greyscale is not supported, and converting to a
+following conversions: RGB to grayscale is not supported, and converting to a
palette when the palette doesn't have a required color is not supported. This is
not supported on purpose: this is information loss which requires a color
-reduction algorithm that is beyong the scope of a PNG encoder (yes, RGB to grey
+reduction algorithm that is beyond the scope of a PNG encoder (yes, RGB to gray
is easy, but there are multiple ways if you want to give some channels more
weight).
@@ -1224,10 +1381,10 @@ decoding to have another color type, a conversion is done by LodePNG.
The PNG specification gives the following color types:
-0: greyscale, bit depths 1, 2, 4, 8, 16
+0: grayscale, bit depths 1, 2, 4, 8, 16
2: RGB, bit depths 8 and 16
3: palette, bit depths 1, 2, 4 and 8
-4: greyscale with alpha, bit depths 8 and 16
+4: grayscale with alpha, bit depths 8 and 16
6: RGBA, bit depths 8 and 16
Bit depth is the amount of bits per pixel per color channel. So the total amount
@@ -1276,15 +1433,22 @@ To avoid some confusion:
the raw image correctly before encoding.
-both encoder and decoder use the same color converter.
+The function lodepng_convert does the color conversion. It is available in the
+interface but normally isn't needed since the encoder and decoder already call
+it.
+
Non supported color conversions:
--color to greyscale: no error is thrown, but the result will look ugly because
-only the red channel is taken
--anything to palette when that palette does not have that color in it: in this
-case an error is thrown
+-color to grayscale when non-gray pixels are present: no error is thrown, but
+the result will look ugly because only the red channel is taken (it assumes all
+three channels are the same in this case so ignores green and blue). The reason
+no error is given is to allow converting from three-channel grayscale images to
+one-channel even if there are numerical imprecisions.
+-anything to palette when the palette does not have an exact match for a from-color
+in it: in this case an error is thrown
Supported color conversions:
-anything to 8-bit RGB, 8-bit RGBA, 16-bit RGB, 16-bit RGBA
--any grey or grey+alpha, to grey or grey+alpha
+-any gray or gray+alpha, to gray or gray+alpha
-anything to a palette, as long as the palette has the requested colors in it
-removing alpha channel
-higher to smaller bitdepth, and vice versa
@@ -1297,10 +1461,6 @@ false.
as the PNG has, by setting the color_convert setting to false. Settings in
info_raw are then ignored.
-The function lodepng_convert does the color conversion. It is available in the
-interface but normally isn't needed since the encoder and decoder already call
-it.
-
6.3. padding bits
-----------------
@@ -1309,7 +1469,7 @@ have a bit amount that isn't a multiple of 8, then padding bits are used so that
scanline starts at a fresh byte. But that is NOT true for the LodePNG raw input and output.
The raw input image you give to the encoder, and the raw output image you get from the decoder
will NOT have these padding bits, e.g. in the case of a 1-bit image with a width
-of 7 pixels, the first pixel of the second scanline will the the 8th bit of the first byte,
+of 7 pixels, the first pixel of the second scanline will the 8th bit of the first byte,
not the first bit of a new byte.
6.4. A note about 16-bits per channel and endianness
@@ -1410,12 +1570,12 @@ Iterate to the next chunk. This works if you have a buffer with consecutive chun
functions do no boundary checking of the allocated data whatsoever, so make sure there is enough
data available in the buffer to be able to go to the next chunk.
-unsigned lodepng_chunk_append(unsigned char** out, size_t* outlength, const unsigned char* chunk):
-unsigned lodepng_chunk_create(unsigned char** out, size_t* outlength, unsigned length,
+unsigned lodepng_chunk_append(unsigned char** out, size_t* outsize, const unsigned char* chunk):
+unsigned lodepng_chunk_create(unsigned char** out, size_t* outsize, unsigned length,
const char* type, const unsigned char* data):
These functions are used to create new chunks that are appended to the data in *out that has
-length *outlength. The append function appends an existing chunk to the new data. The create
+length *outsize. The append function appends an existing chunk to the new data. The create
function creates a new chunk with the given parameters and appends it. Type is the 4-letter
name of the chunk.
@@ -1426,7 +1586,7 @@ The LodePNGInfo struct contains fields with the unknown chunk in it. It has 3
buffers (each with size) to contain 3 types of unknown chunks:
the ones that come before the PLTE chunk, the ones that come between the PLTE
and the IDAT chunks, and the ones that come after the IDAT chunks.
-It's necessary to make the distionction between these 3 cases because the PNG
+It's necessary to make the distinction between these 3 cases because the PNG
standard forces to keep the ordering of unknown chunks compared to the critical
chunks, but does not force any other ordering rules.
@@ -1509,7 +1669,7 @@ C and C++.
*) Other Compilers
If you encounter problems on any compilers, feel free to let me know and I may
-try to fix it if the compiler is modern and standards complient.
+try to fix it if the compiler is modern and standards compliant.
10. examples
@@ -1524,8 +1684,7 @@ examples can be found on the LodePNG website.
#include "lodepng.h"
#include <iostream>
-int main(int argc, char *argv[])
-{
+int main(int argc, char *argv[]) {
const char* filename = argc > 1 ? argv[1] : "test.png";
//load and decode
@@ -1544,8 +1703,7 @@ int main(int argc, char *argv[])
#include "lodepng.h"
-int main(int argc, char *argv[])
-{
+int main(int argc, char *argv[]) {
unsigned error;
unsigned char* image;
size_t width, height;
@@ -1614,6 +1772,23 @@ yyyymmdd.
Some changes aren't backwards compatible. Those are indicated with a (!)
symbol.
+Not all changes are listed here, the commit history in github lists more:
+https://github.com/lvandeve/lodepng
+
+*) 06 mar 2020: simplified some of the dynamic memory allocations.
+*) 12 jan 2020: (!) added 'end' argument to lodepng_chunk_next to allow correct
+ overflow checks.
+*) 14 aug 2019: around 25% faster decoding thanks to huffman lookup tables.
+*) 15 jun 2019: (!) auto_choose_color API changed (for bugfix: don't use palette
+ if gray ICC profile) and non-ICC LodePNGColorProfile renamed to
+ LodePNGColorStats.
+*) 30 dec 2018: code style changes only: removed newlines before opening braces.
+*) 10 sep 2018: added way to inspect metadata chunks without full decoding.
+*) 19 aug 2018: (!) fixed color mode bKGD is encoded with and made it use
+ palette index in case of palette.
+*) 10 aug 2018: (!) added support for gAMA, cHRM, sRGB and iCCP chunks. This
+ change is backwards compatible unless you relied on unknown_chunks for those.
+*) 11 jun 2018: less restrictive check for pixel size integer overflow
*) 14 jan 2018: allow optionally ignoring a few more recoverable errors
*) 17 sep 2017: fix memory leak for some encoder input error cases
*) 27 nov 2016: grey+alpha auto color model detection bugfix
@@ -1623,6 +1798,7 @@ symbol.
*) 08 dec 2015: Made load_file function return error if file can't be opened.
*) 24 okt 2015: Bugfix with decoding to palette output.
*) 18 apr 2015: Boundary PM instead of just package-merge for faster encoding.
+*) 24 aug 2014: Moved to github
*) 23 aug 2014: Reduced needless memory usage of decoder.
*) 28 jun 2014: Removed fix_png setting, always support palette OOB for
simplicity. Made ColorProfile public.
@@ -1630,25 +1806,25 @@ symbol.
*) 22 dec 2013: Power of two windowsize required for optimization.
*) 15 apr 2013: Fixed bug with LAC_ALPHA and color key.
*) 25 mar 2013: Added an optional feature to ignore some PNG errors (fix_png).
-*) 11 mar 2013 (!): Bugfix with custom free. Changed from "my" to "lodepng_"
+*) 11 mar 2013: (!) Bugfix with custom free. Changed from "my" to "lodepng_"
prefix for the custom allocators and made it possible with a new #define to
use custom ones in your project without needing to change lodepng's code.
*) 28 jan 2013: Bugfix with color key.
*) 27 okt 2012: Tweaks in text chunk keyword length error handling.
-*) 8 okt 2012 (!): Added new filter strategy (entropy) and new auto color mode.
+*) 8 okt 2012: (!) Added new filter strategy (entropy) and new auto color mode.
(no palette). Better deflate tree encoding. New compression tweak settings.
Faster color conversions while decoding. Some internal cleanups.
*) 23 sep 2012: Reduced warnings in Visual Studio a little bit.
-*) 1 sep 2012 (!): Removed #define's for giving custom (de)compression functions
+*) 1 sep 2012: (!) Removed #define's for giving custom (de)compression functions
and made it work with function pointers instead.
*) 23 jun 2012: Added more filter strategies. Made it easier to use custom alloc
and free functions and toggle #defines from compiler flags. Small fixes.
-*) 6 may 2012 (!): Made plugging in custom zlib/deflate functions more flexible.
-*) 22 apr 2012 (!): Made interface more consistent, renaming a lot. Removed
+*) 6 may 2012: (!) Made plugging in custom zlib/deflate functions more flexible.
+*) 22 apr 2012: (!) Made interface more consistent, renaming a lot. Removed
redundant C++ codec classes. Reduced amount of structs. Everything changed,
but it is cleaner now imho and functionality remains the same. Also fixed
several bugs and shrunk the implementation code. Made new samples.
-*) 6 nov 2011 (!): By default, the encoder now automatically chooses the best
+*) 6 nov 2011: (!) By default, the encoder now automatically chooses the best
PNG color model and bit depth, based on the amount and type of colors of the
raw image. For this, autoLeaveOutAlphaChannel replaced by auto_choose_color.
*) 9 okt 2011: simpler hash chain implementation for the encoder.
@@ -1657,7 +1833,7 @@ symbol.
A bug with the PNG filtertype heuristic was fixed, so that it chooses much
better ones (it's quite significant). A setting to do an experimental, slow,
brute force search for PNG filter types is added.
-*) 17 aug 2011 (!): changed some C zlib related function names.
+*) 17 aug 2011: (!) changed some C zlib related function names.
*) 16 aug 2011: made the code less wide (max 120 characters per line).
*) 17 apr 2011: code cleanup. Bugfixes. Convert low to 16-bit per sample colors.
*) 21 feb 2011: fixed compiling for C90. Fixed compiling with sections disabled.
@@ -1765,5 +1941,5 @@ Domain: gmail dot com.
Account: lode dot vandevenne.
-Copyright (c) 2005-2017 Lode Vandevenne
+Copyright (c) 2005-2020 Lode Vandevenne
*/