diff --git a/png.c b/png.c index d99e2643b8..4849ffba6f 100644 --- a/png.c +++ b/png.c @@ -1150,7 +1150,7 @@ png_colorspace_sync_info(png_const_structrp png_ptr, png_inforp info_ptr) { /* Everything is invalid */ info_ptr->valid &= ~(PNG_INFO_gAMA|PNG_INFO_cHRM|PNG_INFO_sRGB| - PNG_INFO_iCCP); + PNG_INFO_iCCP|PNG_INFO_cLLi|PNG_INFO_mDCv); # ifdef PNG_COLORSPACE_SUPPORTED /* Clean up the iCCP profile now if it won't be used. */ diff --git a/png.h b/png.h index f5aa4c313d..37243b6c57 100644 --- a/png.h +++ b/png.h @@ -608,6 +608,25 @@ typedef png_time * png_timep; typedef const png_time * png_const_timep; typedef png_time * * png_timepp; +#ifdef PNG_mDCv_SUPPORTED +typedef struct png_mdcv_struct +{ + png_uint_16 chromaticity_redx; /* for use in display primaries */ + png_uint_16 chromaticity_redy ; + png_uint_16 chromaticity_greenx; + png_uint_16 chromaticity_greeny; + png_uint_16 chromaticity_bluex; + png_uint_16 chromaticity_bluey; + png_uint_16 chromaticity_whitex; /* for use white point */ + png_uint_16 chromaticity_whitey; + png_uint_32 max_Lum; /* max, min master display luminance */ + png_uint_32 min_Lum; +} png_mdcv; +typedef png_mdcv * png_mdcvp; +typedef const png_mdcv * png_const_mdcvp; +typedef png_mdcv * * png_mdcvpp; +#endif + #if defined(PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED) ||\ defined(PNG_USER_CHUNKS_SUPPORTED) /* png_unknown_chunk is a structure to hold queued chunks for which there is @@ -744,6 +763,8 @@ typedef png_unknown_chunk * * png_unknown_chunkpp; #define PNG_INFO_sCAL 0x4000U /* ESR, 1.0.6 */ #define PNG_INFO_IDAT 0x8000U /* ESR, 1.0.6 */ #define PNG_INFO_eXIf 0x10000U /* GR-P, 1.6.31 */ +#define PNG_INFO_mDCv 0x40000U /* mDCv chunk */ +#define PNG_INFO_cLLi 0x80000U /* cLLi chunk */ /* This is used for the transformation routines, as some of them * change these values for the row. It also should enable using @@ -2093,6 +2114,20 @@ PNG_EXPORT(159, void, png_set_iCCP, (png_const_structrp png_ptr, png_const_bytep profile, png_uint_32 proflen)); #endif +#ifdef PNG_mDCv_SUPPORTED +PNG_EXPORT(250, png_uint_32, png_get_mDCv, (png_const_structrp png_ptr, + png_inforp info_ptr, png_mdcvp *mastering_display_color_volume)); +PNG_EXPORT(251, void, png_set_mDCv, (png_const_structrp png_ptr, + png_inforp info_ptr, png_const_mdcvp mastering_display_color_volume)); +#endif + +#ifdef PNG_cLLi_SUPPORTED +PNG_EXPORT(252, png_uint_32, png_get_cLLi, (png_const_structrp png_ptr, + png_inforp info_ptr, png_uint_32 *max_cll, png_uint_32 *max_fall)); +PNG_EXPORT(253, void, png_set_cLLi, (png_const_structrp png_ptr, + png_inforp info_ptr, png_uint_32 max_cll, png_uint_32 max_fall)); +#endif + #ifdef PNG_sPLT_SUPPORTED PNG_EXPORT(160, int, png_get_sPLT, (png_const_structrp png_ptr, png_inforp info_ptr, png_sPLT_tpp entries)); @@ -3237,7 +3272,7 @@ PNG_EXPORT(244, int, png_set_option, (png_structrp png_ptr, int option, * one to use is one more than this.) */ #ifdef PNG_EXPORT_LAST_ORDINAL - PNG_EXPORT_LAST_ORDINAL(249); + PNG_EXPORT_LAST_ORDINAL(253); #endif #ifdef __cplusplus diff --git a/pngget.c b/pngget.c index fac370d044..b5882cb894 100644 --- a/pngget.c +++ b/pngget.c @@ -767,6 +767,48 @@ png_get_iCCP(png_const_structrp png_ptr, png_inforp info_ptr, } #endif +#ifdef PNG_mDCv_SUPPORTED +png_uint_32 PNGAPI +png_get_mDCv(png_const_structrp png_ptr, png_inforp info_ptr, + png_mdcvp *mastering_display_color_volume) +{ + png_debug1(1, "in %s retrieval function", "mDCv"); + + if (png_ptr != NULL && info_ptr != NULL && + (info_ptr->valid & PNG_INFO_mDCv) != 0 && mastering_display_color_volume != NULL) + { + *mastering_display_color_volume = &(info_ptr->mastering_display_color_volume); + return (PNG_INFO_mDCv); + } + + return (0); +} +#endif /* mDCv */ + +#ifdef PNG_cLLi_SUPPORTED +png_uint_32 PNGAPI +png_get_cLLi(png_const_structrp png_ptr, png_inforp info_ptr, + png_uint_32 *max_cll, png_uint_32 *max_fall) +{ + png_debug1(1, "in %s retrieval function", "cLLi"); + + if (png_ptr != NULL && info_ptr != NULL && + (info_ptr->valid & PNG_INFO_cLLi) != 0) + { + if (max_cll != NULL) + *max_cll = info_ptr->maximum_content_light_level; + + if (max_fall != NULL) + *max_fall = info_ptr->maximum_frame_average_light_level ; + + return (PNG_INFO_cLLi); + } + + return (0); + +} +#endif /* cLLi */ + #ifdef PNG_sPLT_SUPPORTED int PNGAPI png_get_sPLT(png_const_structrp png_ptr, png_inforp info_ptr, diff --git a/pnginfo.h b/pnginfo.h index ea4f115003..d18626ea7f 100644 --- a/pnginfo.h +++ b/pnginfo.h @@ -106,6 +106,20 @@ struct png_info_def png_bytep iccp_profile; /* International Color Consortium profile data */ png_uint_32 iccp_proflen; /* ICC profile data length */ #endif + +#ifdef PNG_mDCv_SUPPORTED + /* The mDCv chunk characterizes the Mastering Display Color Volume (mDCv) + * used at the point of content creation holds the last time the displayed image + * data was modified. See the png_mdcv struct for the contents of this struct. + */ + png_mdcv mastering_display_color_volume; +#endif + +#ifdef PNG_cLLi_SUPPORTED + /* cLLi chunk data. */ + png_uint_32 maximum_content_light_level; + png_uint_32 maximum_frame_average_light_level; +#endif #ifdef PNG_TEXT_SUPPORTED /* The tEXt, and zTXt chunks contain human-readable textual data in diff --git a/pngpread.c b/pngpread.c index 322b0cf9f1..74d51b2c61 100644 --- a/pngpread.c +++ b/pngpread.c @@ -332,6 +332,22 @@ png_push_read_chunk(png_structrp png_ptr, png_inforp info_ptr) png_handle_iCCP(png_ptr, info_ptr, png_ptr->push_length); } +#endif +#ifdef PNG_READ_mDCv_SUPPORTED + else if (png_ptr->chunk_name == png_mDCv) + { + PNG_PUSH_SAVE_BUFFER_IF_FULL + png_handle_mDCv(png_ptr, info_ptr, png_ptr->push_length); + } + +#endif +#ifdef PNG_READ_cLLi_SUPPORTED + else if (png_ptr->chunk_name == png_cLLi) + { + PNG_PUSH_SAVE_BUFFER_IF_FULL + png_handle_cLLi(png_ptr, info_ptr, png_ptr->push_length); + } + #endif #ifdef PNG_READ_sPLT_SUPPORTED else if (chunk_name == png_sPLT) diff --git a/pngpriv.h b/pngpriv.h index 62615bee88..dd575de05f 100644 --- a/pngpriv.h +++ b/pngpriv.h @@ -842,6 +842,8 @@ #define png_gIFx PNG_U32(103, 73, 70, 120) #define png_hIST PNG_U32(104, 73, 83, 84) #define png_iCCP PNG_U32(105, 67, 67, 80) +#define png_mDCv PNG_U32(109, 68, 67, 118) /* mDCv */ +#define png_cLLi PNG_U32( 99, 76, 76, 105) /* cLLi */ #define png_iTXt PNG_U32(105, 84, 88, 116) #define png_oFFs PNG_U32(111, 70, 70, 115) #define png_pCAL PNG_U32(112, 67, 65, 76) @@ -1149,6 +1151,16 @@ PNG_INTERNAL_FUNCTION(void,png_write_iCCP,(png_structrp png_ptr, */ #endif +#ifdef PNG_WRITE_mDCv_SUPPORTED +PNG_INTERNAL_FUNCTION(void,png_write_mDCv,(png_structrp png_ptr, + png_const_mdcvp mastering_display_color_volume), PNG_EMPTY); +#endif + +#ifdef PNG_WRITE_cLLi_SUPPORTED +PNG_INTERNAL_FUNCTION(void,png_write_cLLi,(png_structrp png_ptr, + png_uint_32 maximum_content_light_level, png_uint_32 maximum_frame_average_light_level), PNG_EMPTY); +#endif + #ifdef PNG_WRITE_sPLT_SUPPORTED PNG_INTERNAL_FUNCTION(void,png_write_sPLT,(png_structrp png_ptr, png_const_sPLT_tp palette),PNG_EMPTY); @@ -1493,6 +1505,16 @@ PNG_INTERNAL_FUNCTION(void,png_handle_iCCP,(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); #endif /* READ_iCCP */ +#ifdef PNG_READ_mDCv_SUPPORTED +PNG_INTERNAL_FUNCTION(void,png_handle_mDCv,(png_structrp png_ptr, + png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); +#endif /* READ_mDCv */ + +#ifdef PNG_READ_cLLi_SUPPORTED +PNG_INTERNAL_FUNCTION(void,png_handle_cLLi,(png_structrp png_ptr, + png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); +#endif /* READ_cLLi */ + #ifdef PNG_READ_iTXt_SUPPORTED PNG_INTERNAL_FUNCTION(void,png_handle_iTXt,(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); diff --git a/pngread.c b/pngread.c index b10b426519..3a182f47b3 100644 --- a/pngread.c +++ b/pngread.c @@ -224,6 +224,16 @@ png_read_info(png_structrp png_ptr, png_inforp info_ptr) png_handle_iCCP(png_ptr, info_ptr, length); #endif +#ifdef PNG_READ_mDCv_SUPPORTED + else if (chunk_name == png_mDCv) + png_handle_mDCv(png_ptr, info_ptr, length); +#endif + +#ifdef PNG_READ_cLLi_SUPPORTED + else if (chunk_name == png_cLLi) + png_handle_cLLi(png_ptr, info_ptr, length); +#endif + #ifdef PNG_READ_sPLT_SUPPORTED else if (chunk_name == png_sPLT) png_handle_sPLT(png_ptr, info_ptr, length); @@ -900,6 +910,16 @@ png_read_end(png_structrp png_ptr, png_inforp info_ptr) else if (chunk_name == png_iCCP) png_handle_iCCP(png_ptr, info_ptr, length); #endif + +#ifdef PNG_READ_mDCv_SUPPORTED + else if (chunk_name == png_mDCv) + png_handle_mDCv(png_ptr, info_ptr, length); +#endif + +#ifdef PNG_READ_cLLi_SUPPORTED + else if (chunk_name == png_cLLi) + png_handle_cLLi(png_ptr, info_ptr, length); +#endif #ifdef PNG_READ_sPLT_SUPPORTED else if (chunk_name == png_sPLT) @@ -1638,6 +1658,12 @@ png_image_skip_unused_chunks(png_structrp png_ptr) 103, 65, 77, 65, '\0', /* gAMA */ # ifdef PNG_READ_iCCP_SUPPORTED 105, 67, 67, 80, '\0', /* iCCP */ +# endif +# ifdef PNG_READ_mDCv_SUPPORTED + 109, 68, 67, 118, '\0', /* mDCv */ +# endif +# ifdef PNG_READ_cLLi_SUPPORTED + 99, 76, 76, 105, '\0', /* cLLi */ # endif 115, 66, 73, 84, '\0', /* sBIT */ 115, 82, 71, 66, '\0', /* sRGB */ diff --git a/pngrutil.c b/pngrutil.c index 44b3a68693..4cc6487465 100644 --- a/pngrutil.c +++ b/pngrutil.c @@ -301,6 +301,7 @@ png_crc_error(png_structrp png_ptr) #if defined(PNG_READ_iCCP_SUPPORTED) || defined(PNG_READ_iTXt_SUPPORTED) ||\ defined(PNG_READ_pCAL_SUPPORTED) || defined(PNG_READ_sCAL_SUPPORTED) ||\ defined(PNG_READ_sPLT_SUPPORTED) || defined(PNG_READ_tEXt_SUPPORTED) ||\ + defined(PNG_READ_mDCv_SUPPORTED) || defined(PNG_READ_cLLi_SUPPORTED) ||\ defined(PNG_READ_zTXt_SUPPORTED) || defined(PNG_SEQUENTIAL_READ_SUPPORTED) /* Manage the read buffer; this simply reallocates the buffer if it is not small * enough (or if it is not allocated). The routine returns a pointer to the @@ -1647,6 +1648,94 @@ png_handle_iCCP(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) } #endif /* READ_iCCP */ +#ifdef PNG_READ_mDCv_SUPPORTED +void /* PRIVATE */ +png_handle_mDCv(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) +{ + png_byte buf[24]; + png_mdcv mastering_display_color_volume; + + png_debug(1, "in png_handle_mDCv"); + + if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) + png_chunk_error(png_ptr, "missing IHDR"); + + else if ((png_ptr->mode & (PNG_HAVE_IDAT | PNG_HAVE_PLTE)) != 0) + { + png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "out of place"); + return; + } + + if (length != 24) + { + png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "invalid length"); + return; + } + + png_crc_read(png_ptr, buf, 24); + + if (png_crc_finish(png_ptr, 0) != 0) + return; + + // Extract the information + mastering_display_color_volume.chromaticity_redx = png_get_uint_16(buf); + mastering_display_color_volume.chromaticity_redy = png_get_uint_16(buf + 2); + mastering_display_color_volume.chromaticity_greenx = png_get_uint_16(buf + 4); + mastering_display_color_volume.chromaticity_greeny = png_get_uint_16(buf + 6); + mastering_display_color_volume.chromaticity_bluex = png_get_uint_16(buf + 8); + mastering_display_color_volume.chromaticity_bluey = png_get_uint_16(buf + 10); + mastering_display_color_volume.chromaticity_whitex = png_get_uint_16(buf + 12); + mastering_display_color_volume.chromaticity_whitey = png_get_uint_16(buf + 14); + mastering_display_color_volume.max_Lum = png_get_uint_32(buf + 16); + mastering_display_color_volume.min_Lum = png_get_uint_32(buf + 20); + + png_set_mDCv(png_ptr, info_ptr, &mastering_display_color_volume); + +} +#endif /* READ_mDCv */ + +#ifdef PNG_READ_cLLi_SUPPORTED +void /* PRIVATE */ +png_handle_cLLi(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) +{ + png_byte buf[8]; + png_uint_32 max_cll, max_fall; + + png_debug(1, "in png_handle_cLLi"); + + if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) + png_chunk_error(png_ptr, "missing IHDR"); + + else if ((png_ptr->mode & (PNG_HAVE_IDAT | PNG_HAVE_PLTE)) != 0) + { + png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "out of place"); + return; + } + + if (length != 8) + { + png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "invalid length"); + return; + } + + png_crc_read(png_ptr, buf, 8); + + if (png_crc_finish(png_ptr, 0) != 0) + return; + + // Extract the information + max_cll = png_get_uint_32(buf); + max_fall = png_get_uint_32(buf + 4); + + png_set_cLLi(png_ptr, info_ptr, max_cll, max_fall); + +} +#endif /* READ_cLLi */ + #ifdef PNG_READ_sPLT_SUPPORTED void /* PRIVATE */ png_handle_sPLT(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) diff --git a/pngset.c b/pngset.c index b530f65d1e..6361dcecd9 100644 --- a/pngset.c +++ b/pngset.c @@ -744,6 +744,46 @@ png_set_iCCP(png_const_structrp png_ptr, png_inforp info_ptr, } #endif +#ifdef PNG_mDCv_SUPPORTED +void PNGAPI +png_set_mDCv(png_const_structrp png_ptr, png_inforp info_ptr, + png_const_mdcvp mastering_display_color_volume) +{ + png_debug1(1, "in %s storage function", "mDCv"); + + if (png_ptr == NULL || info_ptr == NULL || mastering_display_color_volume == NULL) + return; + + if (mastering_display_color_volume->chromaticity_redx < 0 || mastering_display_color_volume->chromaticity_redy < 0 || + mastering_display_color_volume->chromaticity_greenx < 0 || mastering_display_color_volume->chromaticity_greeny < 0 || + mastering_display_color_volume->chromaticity_bluex < 0 || mastering_display_color_volume->chromaticity_bluey < 0 || + mastering_display_color_volume->chromaticity_whitex < 0 || mastering_display_color_volume->chromaticity_whitey < 0 || + mastering_display_color_volume->max_Lum < 0 || mastering_display_color_volume->min_Lum < 0) + { + png_warning(png_ptr, "Invalid value"); + return; + } + + info_ptr->mastering_display_color_volume = *mastering_display_color_volume; + info_ptr->valid |= PNG_INFO_mDCv; +} +#endif + +#ifdef PNG_cLLi_SUPPORTED +void PNGAPI +png_set_cLLi(png_const_structrp png_ptr, png_inforp info_ptr, png_uint_32 max_cll, png_uint_32 max_fall) +{ + png_debug1(1, "in %s storage function", "cLLi"); + + if (png_ptr == NULL || info_ptr == NULL) + return; + + info_ptr->maximum_content_light_level = max_cll; + info_ptr->maximum_frame_average_light_level = max_fall; + info_ptr->valid |= PNG_INFO_cLLi; + } +#endif + #ifdef PNG_TEXT_SUPPORTED void PNGAPI png_set_text(png_const_structrp png_ptr, png_inforp info_ptr, @@ -1398,6 +1438,8 @@ png_set_keep_unknown_chunks(png_structrp png_ptr, int keep, 103, 65, 77, 65, '\0', /* gAMA */ 104, 73, 83, 84, '\0', /* hIST */ 105, 67, 67, 80, '\0', /* iCCP */ + 109, 68, 67, 118, '\0', /* mDCv */ + 99, 76, 76, 105, '\0', /* cLLi */ 105, 84, 88, 116, '\0', /* iTXt */ 111, 70, 70, 115, '\0', /* oFFs */ 112, 67, 65, 76, '\0', /* pCAL */ diff --git a/pngstruct.h b/pngstruct.h index 7e919d0a37..2e62d13074 100644 --- a/pngstruct.h +++ b/pngstruct.h @@ -315,6 +315,11 @@ struct png_struct_def png_color_16 trans_color; /* transparent color for non-paletted files */ #endif +#if defined(PNG_READ_cLLi_SUPPORTED) + png_uint_32 maximum_content_light_level; + png_uint_32 maximum_frame_average_light_level; +#endif /* cLLi */ + png_read_status_ptr read_row_fn; /* called after each row is decoded */ png_write_status_ptr write_row_fn; /* called after each row is encoded */ #ifdef PNG_PROGRESSIVE_READ_SUPPORTED diff --git a/pngtest.c b/pngtest.c index bcf0f30b5b..d3e25f4151 100644 --- a/pngtest.c +++ b/pngtest.c @@ -1182,6 +1182,26 @@ test_one_file(const char *inname, const char *outname) } } #endif +#ifdef PNG_mDCv_SUPPORTED + { + png_mdcv mastering_display_color_volume; + + if (png_get_mDCv(read_ptr, read_info_ptr, &mastering_display_color_volume) != 0) +#ifdef PNG_WRITE_mDCv_SUPPORTED + png_set_mDCv(write_ptr, write_info_ptr, &mastering_display_color_volume); +#endif + } +#endif +#ifdef PNG_cLLi_SUPPORTED + { + png_uint_32 max_cll, max_fall; + + if (png_get_cLLi(read_ptr, read_info_ptr, &max_cll, &max_fall) != 0) +#ifdef PNG_WRITE_cLLi_SUPPORTED + png_set_cLLi(write_ptr, write_info_ptr, max_cll, max_fall); +#endif + } +#endif #ifdef PNG_sRGB_SUPPORTED { int intent; diff --git a/pngwrite.c b/pngwrite.c index 0ed6a551a4..d1e2bb48c5 100644 --- a/pngwrite.c +++ b/pngwrite.c @@ -164,6 +164,16 @@ png_write_info_before_PLTE(png_structrp png_ptr, png_const_inforp info_ptr) png_write_sRGB(png_ptr, info_ptr->colorspace.rendering_intent); # endif /* WRITE_sRGB */ #endif /* COLORSPACE */ + +#ifdef PNG_WRITE_mDCv_SUPPORTED + if ((info_ptr->valid & PNG_INFO_mDCv) != 0) + png_write_mDCv(png_ptr, &(info_ptr->mastering_display_color_volume)); +#endif + +#ifdef PNG_WRITE_cLLi_SUPPORTED + if ((info_ptr->valid & PNG_INFO_cLLi) != 0) + png_write_cLLi(png_ptr, info_ptr->maximum_content_light_level, info_ptr->maximum_frame_average_light_level); +#endif #ifdef PNG_WRITE_sBIT_SUPPORTED if ((info_ptr->valid & PNG_INFO_sBIT) != 0) diff --git a/pngwutil.c b/pngwutil.c index abe7b07f96..cf589e3f93 100644 --- a/pngwutil.c +++ b/pngwutil.c @@ -1190,6 +1190,55 @@ png_write_iCCP(png_structrp png_ptr, png_const_charp name, } #endif +#ifdef PNG_WRITE_mDCv_SUPPORTED +/* Write the mDCv chunk */ +void /* PRIVATE */ +png_write_mDCv(png_structrp png_ptr, png_const_mdcvp mastering_display_color_volume) +{ + png_byte buf[24]; + + png_debug(1, "in png_write_mDCv"); + + if (mastering_display_color_volume == NULL) + png_error(png_ptr, "Null mastering display color volume"); + + png_save_uint_16(buf + 0, mastering_display_color_volume->chromaticity_redx); + png_save_uint_16(buf + 2, mastering_display_color_volume->chromaticity_redy); + png_save_uint_16(buf + 4, mastering_display_color_volume->chromaticity_greenx); + png_save_uint_16(buf + 6, mastering_display_color_volume->chromaticity_greeny); + png_save_uint_16(buf + 8, mastering_display_color_volume->chromaticity_bluex); + png_save_uint_16(buf + 10, mastering_display_color_volume->chromaticity_bluey); + png_save_uint_16(buf + 12, mastering_display_color_volume->chromaticity_whitex); + png_save_uint_16(buf + 14, mastering_display_color_volume->chromaticity_whitey); + png_save_uint_32(buf + 16, mastering_display_color_volume->max_Lum); + png_save_uint_32(buf + 20, mastering_display_color_volume->min_Lum); + + png_write_complete_chunk(png_ptr, png_mDCv, buf, 24); + +} +#endif + +#ifdef PNG_WRITE_cLLi_SUPPORTED +/* Write the cLLi chunk */ +void /* PRIVATE */ +png_write_cLLi(png_structrp png_ptr, png_uint_32 max_cll, png_uint_32 max_fall) +{ + png_byte buf[8]; + + png_debug(1, "in png_write_cLLi"); + + /* Check that we have valid input data from the application info */ + if (max_cll < 0 || max_fall < 0) + png_error(png_ptr, "Invalid value"); + + png_save_int_32(buf, max_cll); + png_save_int_32(buf + 4, max_fall); + + png_write_complete_chunk(png_ptr, png_cLLi, buf, 8); + +} +#endif + #ifdef PNG_WRITE_sPLT_SUPPORTED /* Write a sPLT chunk */ void /* PRIVATE */ diff --git a/scripts/pnglibconf.dfa b/scripts/pnglibconf.dfa index fe8e481238..90aaea76fd 100644 --- a/scripts/pnglibconf.dfa +++ b/scripts/pnglibconf.dfa @@ -850,6 +850,8 @@ chunk eXIf chunk gAMA enables GAMMA chunk hIST chunk iCCP enables COLORSPACE, GAMMA +chunk mDCv +chunk cLLi chunk iTXt enables TEXT chunk oFFs chunk pCAL diff --git a/scripts/pnglibconf.h.prebuilt b/scripts/pnglibconf.h.prebuilt index c46f7c4035..e05dc50fd3 100644 --- a/scripts/pnglibconf.h.prebuilt +++ b/scripts/pnglibconf.h.prebuilt @@ -92,6 +92,8 @@ #define PNG_READ_gAMA_SUPPORTED #define PNG_READ_hIST_SUPPORTED #define PNG_READ_iCCP_SUPPORTED +#define PNG_READ_mdCv_SUPPORTED +#define PNG_READ_cLLi_SUPPORTED #define PNG_READ_iTXt_SUPPORTED #define PNG_READ_oFFs_SUPPORTED #define PNG_READ_pCAL_SUPPORTED @@ -162,6 +164,8 @@ #define PNG_WRITE_gAMA_SUPPORTED #define PNG_WRITE_hIST_SUPPORTED #define PNG_WRITE_iCCP_SUPPORTED +#define PNG_WRITE_mdCv_SUPPORTED +#define PNG_WRITE_cLLi_SUPPORTED #define PNG_WRITE_iTXt_SUPPORTED #define PNG_WRITE_oFFs_SUPPORTED #define PNG_WRITE_pCAL_SUPPORTED @@ -180,6 +184,8 @@ #define PNG_gAMA_SUPPORTED #define PNG_hIST_SUPPORTED #define PNG_iCCP_SUPPORTED +#define PNG_mdCv_SUPPORTED +#define PNG_cLLi_SUPPORTED #define PNG_iTXt_SUPPORTED #define PNG_oFFs_SUPPORTED #define PNG_pCAL_SUPPORTED diff --git a/scripts/symbols.def b/scripts/symbols.def index 82494bbf94..2731c6049d 100644 --- a/scripts/symbols.def +++ b/scripts/symbols.def @@ -253,3 +253,7 @@ EXPORTS png_set_eXIf @247 png_get_eXIf_1 @248 png_set_eXIf_1 @249 + png_get_mDCv @250 + png_set_mDCv @251 + png_get_cLLi @252 + png_set_cLLi @253