From 9dae38279b7da440aa443df6c09a2e2079b39c64 Mon Sep 17 00:00:00 2001 From: maryla-uc Date: Tue, 21 Nov 2023 14:16:19 +0100 Subject: [PATCH] Use default yuv format and depth for the gain map when converting jpegs. (#1789) When converting jpeg files with gain maps, the same depth and pixelFormat were used as for the main image. However, increasing the gain map's bit depth or changing its pixelFormat would be rarely needed, and retaining gain map's actual depth (8 ) and pixelFormat (i.e. 400 if it's grayscale) is a more sensible default. Different input paramters could also be added to allow finer control if needed. --- apps/avifgainmaputil/program_command.h | 3 +- apps/shared/avifjpeg.c | 29 +++++++------------ ...is_exif_xmp_gainmap_bigendian.jpg.avif.xml | 19 +++++++----- ...exif_xmp_gainmap_littleendian.jpg.avif.xml | 19 +++++++----- 4 files changed, 33 insertions(+), 37 deletions(-) diff --git a/apps/avifgainmaputil/program_command.h b/apps/avifgainmaputil/program_command.h index af8ad38d75..e1af1cd202 100644 --- a/apps/avifgainmaputil/program_command.h +++ b/apps/avifgainmaputil/program_command.h @@ -105,8 +105,7 @@ struct ImageReadArgs { void Init(argparse::ArgumentParser& argparse) { argparse .add_argument(pixel_format, "--yuv", "-y") - .help("Output YUV format for avif") - .default_value("444"); + .help("Output YUV format for avif (default = automatic)"); argparse.add_argument(depth, "--depth", "-d") .choices({"0", "8", "10", "12"}) .help("Output depth (0 = automatic)"); diff --git a/apps/shared/avifjpeg.c b/apps/shared/avifjpeg.c index 8a931e4cec..85cbc4db63 100644 --- a/apps/shared/avifjpeg.c +++ b/apps/shared/avifjpeg.c @@ -669,13 +669,7 @@ avifBool avifJPEGParseGainMapXMP(const uint8_t * xmpData, size_t xmpSize, avifGa // See CIPA DC-007-Translation-2021 Multi-Picture Format at https://www.cipa.jp/e/std/std-sec.html // and https://helpx.adobe.com/camera-raw/using/gain-map.html in particular Figures 1 to 6. // Returns AVIF_FALSE if no gain map was found. -static avifBool avifJPEGExtractGainMapImageFromMpf(FILE * f, - const char * inputFilename, - const avifROData * segmentData, - avifImage * avif, - avifPixelFormat requestedFormat, - uint32_t requestedDepth, - avifChromaDownsampling chromaDownsampling) +static avifBool avifJPEGExtractGainMapImageFromMpf(FILE * f, const avifROData * segmentData, avifImage * avif, avifChromaDownsampling chromaDownsampling) { uint32_t offset = 0; @@ -768,10 +762,10 @@ static avifBool avifJPEGExtractGainMapImageFromMpf(FILE * f, // be gain maps. This could be fixed by having a helper function to get just the XMP without // decoding the whole image. if (!avifJPEGReadInternal(f, - inputFilename, + "gain map", avif, - requestedFormat, - requestedDepth, + /*requestedFormat=*/AVIF_PIXEL_FORMAT_NONE, // automatic + /*requestedDepth=*/0, // automatic chromaDownsampling, /*ignoreColorProfile=*/AVIF_TRUE, /*ignoreExif=*/AVIF_TRUE, @@ -793,13 +787,7 @@ static avifBool avifJPEGExtractGainMapImageFromMpf(FILE * f, // See CIPA DC-007-Translation-2021 Multi-Picture Format at https://www.cipa.jp/e/std/std-sec.html // and https://helpx.adobe.com/camera-raw/using/gain-map.html // Returns AVIF_TRUE if a gain map was found. -static avifBool avifJPEGExtractGainMapImage(FILE * f, - const char * inputFilename, - struct jpeg_decompress_struct * cinfo, - avifGainMap * gainMap, - avifPixelFormat requestedFormat, - uint32_t requestedDepth, - avifChromaDownsampling chromaDownsampling) +static avifBool avifJPEGExtractGainMapImage(FILE * f, struct jpeg_decompress_struct * cinfo, avifGainMap * gainMap, avifChromaDownsampling chromaDownsampling) { const avifROData tagMpf = { (const uint8_t *)AVIF_JPEG_MPF_HEADER, AVIF_JPEG_MPF_HEADER_LENGTH }; for (jpeg_saved_marker_ptr marker = cinfo->marker_list; marker != NULL; marker = marker->next) { @@ -809,9 +797,12 @@ static avifBool avifJPEGExtractGainMapImage(FILE * f, if ((marker->marker == (JPEG_APP0 + 2)) && (marker->data_length > tagMpf.size) && !memcmp(marker->data, tagMpf.data, tagMpf.size)) { avifImage * image = avifImageCreateEmpty(); + // Set jpeg native matrix coefficients to allow copying YUV values directly. + image->matrixCoefficients = AVIF_MATRIX_COEFFICIENTS_BT601; + assert(avifJPEGHasCompatibleMatrixCoefficients(image->matrixCoefficients)); const avifROData mpfData = { (const uint8_t *)marker->data + tagMpf.size, marker->data_length - tagMpf.size }; - if (!avifJPEGExtractGainMapImageFromMpf(f, inputFilename, &mpfData, image, requestedFormat, requestedDepth, chromaDownsampling)) { + if (!avifJPEGExtractGainMapImageFromMpf(f, &mpfData, image, chromaDownsampling)) { fprintf(stderr, "Note: XMP metadata indicated the presence of a gain map, but it could not be found or decoded\n"); avifImageDestroy(image); return AVIF_FALSE; @@ -1145,7 +1136,7 @@ static avifBool avifJPEGReadInternal(FILE * f, // The primary XMP block (for the main image) must contain a node with an hdrgm:Version field if and only if a gain map is present. if (!ignoreGainMap && avifJPEGHasGainMapXMPNode(avif->xmp.data, avif->xmp.size)) { // Ignore the return value: continue even if we fail to find/parse/decode the gain map. - avifJPEGExtractGainMapImage(f, inputFilename, &cinfo, &avif->gainMap, requestedFormat, requestedDepth, chromaDownsampling); + avifJPEGExtractGainMapImage(f, &cinfo, &avif->gainMap, chromaDownsampling); } if (avif->xmp.size > 0 && ignoreXMP) { diff --git a/tests/data/goldens/paris_exif_xmp_gainmap_bigendian.jpg.avif.xml b/tests/data/goldens/paris_exif_xmp_gainmap_bigendian.jpg.avif.xml index 2b6efaba04..4dd7ef26d0 100644 --- a/tests/data/goldens/paris_exif_xmp_gainmap_bigendian.jpg.avif.xml +++ b/tests/data/goldens/paris_exif_xmp_gainmap_bigendian.jpg.avif.xml @@ -8,7 +8,7 @@ - + @@ -54,8 +54,8 @@ - - + + @@ -71,11 +71,14 @@ + + + - + - + @@ -92,9 +95,9 @@ - - - + + + diff --git a/tests/data/goldens/paris_exif_xmp_gainmap_littleendian.jpg.avif.xml b/tests/data/goldens/paris_exif_xmp_gainmap_littleendian.jpg.avif.xml index 7136636859..b5faabfaba 100644 --- a/tests/data/goldens/paris_exif_xmp_gainmap_littleendian.jpg.avif.xml +++ b/tests/data/goldens/paris_exif_xmp_gainmap_littleendian.jpg.avif.xml @@ -8,7 +8,7 @@ - + @@ -54,8 +54,8 @@ - - + + @@ -71,11 +71,14 @@ + + + - + - + @@ -92,9 +95,9 @@ - - - + + +