[libpng16] fix: Update the cICP support for better compliance with PNG-3

Apply the following corrections and improvements:
 * Add a validity check in `png_set_cICP`.
 * Fix the ordering check in `png_handle_cICP`.
 * Add a multiplicity check in `png_handle_cICP`.
 * Optimize the implementation of `png_write_cICP`.
 * Remove an unnecessary preprocessor guard from pngtest.c.
 * Update the dependency declaration in pnglibconf.dfa.
 * Fix the indentation where necessary.

This is a cherry-pick of commit c2a02691df1ecf51b7c97142752a7034350cb1f6
from branch 'libpng18'.
This commit is contained in:
Cosmin Truta 2024-12-31 22:05:03 +02:00
parent 75748d93ce
commit 823c2d80dc
8 changed files with 78 additions and 66 deletions

View File

@ -2057,6 +2057,13 @@ png_handle_cICP(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) if ((png_ptr->mode & PNG_HAVE_IHDR) == 0)
png_chunk_error(png_ptr, "missing IHDR"); 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;
}
else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_cICP) != 0) else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_cICP) != 0)
{ {
png_crc_finish(png_ptr, length); png_crc_finish(png_ptr, length);
@ -2064,10 +2071,7 @@ png_handle_cICP(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
return; return;
} }
if ((png_ptr->mode & PNG_HAVE_IDAT) != 0) else if (length != 4)
png_ptr->mode |= PNG_AFTER_IDAT;
if (length != 4)
{ {
png_crc_finish(png_ptr, length); png_crc_finish(png_ptr, length);
png_chunk_benign_error(png_ptr, "invalid"); png_chunk_benign_error(png_ptr, "invalid");

View File

@ -135,10 +135,9 @@ png_set_cHRM_XYZ(png_const_structrp png_ptr, png_inforp info_ptr, double red_X,
#ifdef PNG_cICP_SUPPORTED #ifdef PNG_cICP_SUPPORTED
void PNGAPI void PNGAPI
png_set_cICP(png_const_structrp png_ptr, png_set_cICP(png_const_structrp png_ptr, png_inforp info_ptr,
png_inforp info_ptr, png_byte colour_primaries, png_byte colour_primaries, png_byte transfer_function,
png_byte transfer_function, png_byte matrix_coefficients, png_byte matrix_coefficients, png_byte video_full_range_flag)
png_byte video_full_range_flag)
{ {
png_debug1(1, "in %s storage function", "cICP"); png_debug1(1, "in %s storage function", "cICP");
@ -149,6 +148,13 @@ png_set_cICP(png_const_structrp png_ptr,
info_ptr->cicp_transfer_function = transfer_function; info_ptr->cicp_transfer_function = transfer_function;
info_ptr->cicp_matrix_coefficients = matrix_coefficients; info_ptr->cicp_matrix_coefficients = matrix_coefficients;
info_ptr->cicp_video_full_range_flag = video_full_range_flag; info_ptr->cicp_video_full_range_flag = video_full_range_flag;
if (info_ptr->cicp_matrix_coefficients != 0)
{
png_warning(png_ptr, "Invalid cICP matrix coefficients");
return;
}
info_ptr->valid |= PNG_INFO_cICP; info_ptr->valid |= PNG_INFO_cICP;
} }
#endif /* cICP */ #endif /* cICP */

View File

@ -1212,14 +1212,12 @@ test_one_file(const char *inname, const char *outname)
png_byte matrix_coefficients; png_byte matrix_coefficients;
png_byte video_full_range_flag; png_byte video_full_range_flag;
if (png_get_cICP(read_ptr, read_info_ptr, &colour_primaries, if (png_get_cICP(read_ptr, read_info_ptr,
&transfer_function, &matrix_coefficients, &colour_primaries, &transfer_function,
&video_full_range_flag) != 0) &matrix_coefficients, &video_full_range_flag) != 0)
#ifdef PNG_WRITE_cICP_SUPPORTED png_set_cICP(write_ptr, write_info_ptr,
png_set_cICP(write_ptr, write_info_ptr, colour_primaries, colour_primaries, transfer_function,
transfer_function, matrix_coefficients, matrix_coefficients, video_full_range_flag);
video_full_range_flag);
#endif
} }
#endif #endif
#ifdef PNG_READ_eXIf_SUPPORTED #ifdef PNG_READ_eXIf_SUPPORTED

View File

@ -239,7 +239,8 @@ png_write_info(png_structrp png_ptr, png_const_inforp info_ptr)
#ifdef PNG_WRITE_cICP_SUPPORTED #ifdef PNG_WRITE_cICP_SUPPORTED
if ((info_ptr->valid & PNG_INFO_cICP) != 0) if ((info_ptr->valid & PNG_INFO_cICP) != 0)
{ {
png_write_cICP(png_ptr, info_ptr->cicp_colour_primaries, png_write_cICP(png_ptr,
info_ptr->cicp_colour_primaries,
info_ptr->cicp_transfer_function, info_ptr->cicp_transfer_function,
info_ptr->cicp_matrix_coefficients, info_ptr->cicp_matrix_coefficients,
info_ptr->cicp_video_full_range_flag); info_ptr->cicp_video_full_range_flag);

View File

@ -1495,14 +1495,17 @@ png_write_cICP(png_structrp png_ptr,
png_byte colour_primaries, png_byte transfer_function, png_byte colour_primaries, png_byte transfer_function,
png_byte matrix_coefficients, png_byte video_full_range_flag) png_byte matrix_coefficients, png_byte video_full_range_flag)
{ {
png_byte buf[4];
png_debug(1, "in png_write_cICP"); png_debug(1, "in png_write_cICP");
png_write_chunk_header(png_ptr, png_cICP, 4); png_write_chunk_header(png_ptr, png_cICP, 4);
png_write_chunk_data(png_ptr, &colour_primaries, 1); buf[0] = colour_primaries;
png_write_chunk_data(png_ptr, &transfer_function, 1); buf[1] = transfer_function;
png_write_chunk_data(png_ptr, &matrix_coefficients, 1); buf[2] = matrix_coefficients;
png_write_chunk_data(png_ptr, &video_full_range_flag, 1); buf[3] = video_full_range_flag;
png_write_chunk_data(png_ptr, buf, 4);
png_write_chunk_end(png_ptr); png_write_chunk_end(png_ptr);
} }

View File

@ -846,7 +846,7 @@ setting IDAT_READ_SIZE default PNG_ZBUF_SIZE
# Ancillary chunks # Ancillary chunks
chunk bKGD chunk bKGD
chunk cHRM enables COLORSPACE chunk cHRM enables COLORSPACE
chunk cICP chunk cICP enables COLORSPACE, GAMMA
chunk eXIf chunk eXIf
chunk gAMA enables GAMMA chunk gAMA enables GAMMA
chunk hIST chunk hIST