Copy ICC profile from PNG to JPEG

This commit is contained in:
Kornel
2017-04-30 15:02:27 +01:00
parent 2dd5ae7b83
commit 075a1e1afc
3 changed files with 29 additions and 1 deletions

View File

@@ -126,6 +126,7 @@ JMESSAGE(JERR_UNSUPPORTED_FORMAT, "Unsupported output file format")
#ifdef PNG_SUPPORTED
JMESSAGE(JERR_PNG_ERROR, "Unable to read PNG file: %s")
JMESSAGE(JERR_PNG_PROFILETOOLARGE, "Embedded profile was too large for this tool - dropped.")
#endif
#ifdef JMAKE_ENUM_LIST

View File

@@ -81,6 +81,7 @@ static const char * const cdjpeg_message_table[] = {
static boolean is_targa; /* records user -targa switch */
static boolean is_jpeg;
static boolean copy_markers;
LOCAL(cjpeg_source_ptr)
select_file_type (j_compress_ptr cinfo, FILE *infile)
@@ -115,6 +116,7 @@ select_file_type (j_compress_ptr cinfo, FILE *infile)
#endif
#ifdef PNG_SUPPORTED
case 0x89:
copy_markers = TRUE;
return jinit_read_png(cinfo);
#endif
#ifdef RLE_SUPPORTED
@@ -127,6 +129,7 @@ select_file_type (j_compress_ptr cinfo, FILE *infile)
#endif
case 0xff:
is_jpeg = TRUE;
copy_markers = TRUE;
return jinit_read_jpeg(cinfo);
default:
ERREXIT(cinfo, JERR_UNKNOWN_FORMAT);
@@ -766,7 +769,7 @@ main (int argc, char **argv)
jpeg_start_compress(&cinfo, TRUE);
/* Copy metadata */
if (is_jpeg) {
if (copy_markers) {
jpeg_saved_marker_ptr marker;
/* In the current implementation, we don't actually need to examine the

24
rdpng.c
View File

@@ -97,6 +97,30 @@ start_input_png (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
cinfo->input_gamma = gamma;
sinfo->get_pixel_rows = get_pixel_rows_png;
source->pub.marker_list = NULL;
png_bytep profile = NULL;
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) {
if (proflen < 65535-14) {
size_t datalen = proflen + 14;
JOCTET *dataptr = (*cinfo->mem->alloc_small)((j_common_ptr)cinfo, JPOOL_IMAGE, datalen);
memcpy(dataptr, "ICC_PROFILE\0\x01\x01", 14);
memcpy(dataptr + 14, profile, proflen);
struct jpeg_marker_struct *marker = (*cinfo->mem->alloc_small)((j_common_ptr)cinfo, JPOOL_IMAGE, sizeof(struct jpeg_marker_struct));
marker->next = NULL;
marker->marker = JPEG_APP0+2;
marker->original_length = 0;
marker->data_length = datalen;
marker->data = dataptr;
source->pub.marker_list = marker;
} else {
WARNMS(cinfo, JERR_PNG_PROFILETOOLARGE);
}
}
png_read_update_info(source->png_ptr, source->info_ptr);
png_size_t rowbytes = png_get_rowbytes(source->png_ptr, source->info_ptr);