Skip to content

Commit

Permalink
[libpng16] fix: Update the cICP support for better compliance with PNG-3
Browse files Browse the repository at this point in the history
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'.
  • Loading branch information
ctruta committed Jan 2, 2025
1 parent 75748d9 commit 823c2d8
Show file tree
Hide file tree
Showing 8 changed files with 79 additions and 67 deletions.
4 changes: 2 additions & 2 deletions pngpread.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion pngread.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
48 changes: 26 additions & 22 deletions pngrutil.c
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
30 changes: 18 additions & 12 deletions pngset.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

if (info_ptr->cicp_matrix_coefficients != 0)
{
png_warning(png_ptr, "Invalid cICP matrix coefficients");
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->valid |= PNG_INFO_cICP;
}
#endif /* cICP */

Expand Down
28 changes: 13 additions & 15 deletions pngtest.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

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
}
{
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)
png_set_cICP(write_ptr, write_info_ptr,
colour_primaries, transfer_function,
matrix_coefficients, video_full_range_flag);
}
#endif
#ifdef PNG_READ_eXIf_SUPPORTED
{
Expand Down
15 changes: 8 additions & 7 deletions pngwrite.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
17 changes: 10 additions & 7 deletions pngwutil.c
Original file line number Diff line number Diff line change
Expand Up @@ -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_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);
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);
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);
png_write_chunk_end(png_ptr);
}
#endif

Expand Down
2 changes: 1 addition & 1 deletion scripts/pnglibconf.dfa
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 823c2d8

Please sign in to comment.