Embed an sRGB profile if PNG had an sRGB chunk

This commit is contained in:
Kornel
2017-05-11 00:35:07 +01:00
parent 78e3171864
commit 88e99ac246

39
rdpng.c
View File

@@ -43,6 +43,27 @@ METHODDEF(void) error_input_png(png_structp png_ptr, png_const_charp msg) {
ERREXITS(cinfo, JERR_PNG_ERROR, msg);
}
/* This is a small ICC profile for sRGB */
static unsigned char tiny_srgb[] = {0,0,2,24,108,99,109,115,2,16,0,0,109,110,
116,114,82,71,66,32,88,89,90,32,7,220,0,1,0,25,0,3,0,41,0,57,97,99,115,112,65,
80,80,76,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,214,0,1,0,0,0,
0,211,45,108,99,109,115,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,100,101,115,99,0,0,0,252,0,0,0,106,
99,112,114,116,0,0,1,104,0,0,0,11,119,116,112,116,0,0,1,116,0,0,0,20,98,107,
112,116,0,0,1,136,0,0,0,20,114,88,89,90,0,0,1,156,0,0,0,20,103,88,89,90,0,0,1,
176,0,0,0,20,98,88,89,90,0,0,1,196,0,0,0,20,114,84,82,67,0,0,1,216,0,0,0,64,98,
84,82,67,0,0,1,216,0,0,0,64,103,84,82,67,0,0,1,216,0,0,0,64,100,101,115,99,0,0,
0,0,0,0,0,13,115,82,71,66,32,77,111,122,74,80,69,71,0,0,0,0,0,0,0,0,1,0,0,0,0,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,116,101,120,
116,0,0,0,0,80,68,0,0,88,89,90,32,0,0,0,0,0,0,246,214,0,1,0,0,0,0,211,45,88,89,
90,32,0,0,0,0,0,0,3,22,0,0,3,51,0,0,2,164,88,89,90,32,0,0,0,0,0,0,111,162,0,0,
56,245,0,0,3,144,88,89,90,32,0,0,0,0,0,0,98,153,0,0,183,133,0,0,24,218,88,89,
90,32,0,0,0,0,0,0,36,160,0,0,15,132,0,0,182,207,99,117,114,118,0,0,0,0,0,0,0,
26,0,0,0,203,1,201,3,99,5,146,8,107,11,246,16,63,21,81,27,52,33,241,41,144,50,
24,59,146,70,5,81,119,93,237,107,112,122,5,137,177,154,124,172,105,191,125,211,
195,233,48,255,255,};
METHODDEF(void)
start_input_png (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
{
@@ -90,8 +111,10 @@ start_input_png (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
cinfo->image_width = width;
cinfo->image_height = height;
int has_srgb_chunk = png_get_valid(source->png_ptr, source->info_ptr, PNG_INFO_sRGB);
double gamma = 0.45455;
if (!png_get_valid(source->png_ptr, source->info_ptr, PNG_INFO_sRGB)) {
if (!has_srgb_chunk) {
png_get_gAMA(source->png_ptr, source->info_ptr, &gamma);
}
cinfo->input_gamma = gamma;
@@ -102,8 +125,18 @@ start_input_png (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
png_charp unused1 = NULL;
int unused2 = 0;
png_uint_32 proflen = 0;
if (png_get_iCCP(source->png_ptr, source->info_ptr, &unused1, &unused2, &profile, &proflen) && /* your libpng is out of date if you get a warning here */
profile && proflen) {
int has_profile = 0;
if (has_srgb_chunk) {
/* PNG can declare use of an sRGB profile without embedding an ICC file, but JPEG doesn't have such feature */
has_profile = 1;
profile = tiny_srgb;
proflen = sizeof(tiny_srgb);
} else {
has_profile = png_get_iCCP(source->png_ptr, source->info_ptr, &unused1, &unused2, &profile, &proflen); /* your libpng is out of date if you get a warning here */
}
if (has_profile && profile && proflen) {
if (proflen < 65535-14) {
size_t datalen = proflen + 14;
JOCTET *dataptr = (*cinfo->mem->alloc_small)((j_common_ptr)cinfo, JPOOL_IMAGE, datalen);