[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

@ -312,8 +312,8 @@ png_push_read_chunk(png_structrp png_ptr, png_inforp info_ptr)
#ifdef PNG_READ_cICP_SUPPORTED
else if (png_ptr->chunk_name == png_cICP)
{
PNG_PUSH_SAVE_BUFFER_IF_FULL
png_handle_cICP(png_ptr, info_ptr, png_ptr->push_length);
PNG_PUSH_SAVE_BUFFER_IF_FULL
png_handle_cICP(png_ptr, info_ptr, png_ptr->push_length);
}
#endif

View File

@ -175,7 +175,7 @@ png_read_info(png_structrp png_ptr, png_inforp info_ptr)
#endif
#ifdef PNG_READ_cICP_SUPPORTED
else if (chunk_name == png_cICP)
png_handle_cICP(png_ptr, info_ptr, length);
png_handle_cICP(png_ptr, info_ptr, length);
#endif
#ifdef PNG_READ_eXIf_SUPPORTED

View File

@ -2050,36 +2050,40 @@ png_handle_bKGD(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
void /* PRIVATE */
png_handle_cICP(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
{
png_byte buf[4];
png_byte buf[4];
png_debug(1, "in png_handle_cICP");
png_debug(1, "in png_handle_cICP");
if ((png_ptr->mode & PNG_HAVE_IHDR) == 0)
png_chunk_error(png_ptr, "missing IHDR");
if ((png_ptr->mode & PNG_HAVE_IHDR) == 0)
png_chunk_error(png_ptr, "missing IHDR");
else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_cICP) != 0)
{
png_crc_finish(png_ptr, length);
png_chunk_benign_error(png_ptr, "duplicate");
return;
}
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 ((png_ptr->mode & PNG_HAVE_IDAT) != 0)
png_ptr->mode |= PNG_AFTER_IDAT;
else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_cICP) != 0)
{
png_crc_finish(png_ptr, length);
png_chunk_benign_error(png_ptr, "duplicate");
return;
}
if (length != 4)
{
png_crc_finish(png_ptr, length);
png_chunk_benign_error(png_ptr, "invalid");
return;
}
else if (length != 4)
{
png_crc_finish(png_ptr, length);
png_chunk_benign_error(png_ptr, "invalid");
return;
}
png_crc_read(png_ptr, buf, 4);
png_crc_read(png_ptr, buf, 4);
if (png_crc_finish(png_ptr, 0) != 0)
return;
if (png_crc_finish(png_ptr, 0) != 0)
return;
png_set_cICP(png_ptr, info_ptr, buf[0], buf[1], buf[2], buf[3]);
png_set_cICP(png_ptr, info_ptr, buf[0], buf[1], buf[2], buf[3]);
}
#endif

View File

@ -135,21 +135,27 @@ png_set_cHRM_XYZ(png_const_structrp png_ptr, png_inforp info_ptr, double red_X,
#ifdef PNG_cICP_SUPPORTED
void PNGAPI
png_set_cICP(png_const_structrp png_ptr,
png_inforp info_ptr, png_byte colour_primaries,
png_byte transfer_function, png_byte matrix_coefficients,
png_byte video_full_range_flag)
png_set_cICP(png_const_structrp png_ptr, png_inforp info_ptr,
png_byte colour_primaries, png_byte transfer_function,
png_byte matrix_coefficients, png_byte video_full_range_flag)
{
png_debug1(1, "in %s storage function", "cICP");
png_debug1(1, "in %s storage function", "cICP");
if (png_ptr == NULL || info_ptr == NULL)
return;
if (png_ptr == NULL || info_ptr == NULL)
return;
info_ptr->cicp_colour_primaries = colour_primaries;
info_ptr->cicp_transfer_function = transfer_function;
info_ptr->cicp_matrix_coefficients = matrix_coefficients;
info_ptr->cicp_video_full_range_flag = video_full_range_flag;
info_ptr->valid |= PNG_INFO_cICP;
info_ptr->cicp_colour_primaries = colour_primaries;
info_ptr->cicp_transfer_function = transfer_function;
info_ptr->cicp_matrix_coefficients = matrix_coefficients;
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;
}
#endif /* cICP */

View File

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

View File

@ -237,13 +237,14 @@ png_write_info(png_structrp png_ptr, png_const_inforp info_ptr)
#endif
#ifdef PNG_WRITE_cICP_SUPPORTED
if ((info_ptr->valid & PNG_INFO_cICP) != 0)
{
png_write_cICP(png_ptr, info_ptr->cicp_colour_primaries,
info_ptr->cicp_transfer_function,
info_ptr->cicp_matrix_coefficients,
info_ptr->cicp_video_full_range_flag);
}
if ((info_ptr->valid & PNG_INFO_cICP) != 0)
{
png_write_cICP(png_ptr,
info_ptr->cicp_colour_primaries,
info_ptr->cicp_transfer_function,
info_ptr->cicp_matrix_coefficients,
info_ptr->cicp_video_full_range_flag);
}
#endif
#ifdef PNG_WRITE_eXIf_SUPPORTED

View File

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

View File

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