Skip to content

Commit

Permalink
AVIF: add ICC profile get/set
Browse files Browse the repository at this point in the history
  • Loading branch information
rouault committed Aug 21, 2024
1 parent 8d17561 commit 18f0c9a
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 0 deletions.
13 changes: 13 additions & 0 deletions doc/source/drivers/raster/avif.rst
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,14 @@ Driver capabilities
.. supports_createcopy
Color Profile Metadata
----------------------

GDAL can deal with the following color profile
metadata in the COLOR_PROFILE domain:

- SOURCE_ICC_PROFILE (Base64 encoded ICC profile embedded in file.)

Creation options
----------------

Expand Down Expand Up @@ -72,6 +80,11 @@ The following creation options are supported:

Number of worker threads for compression.

- .. co:: SOURCE_ICC_PROFILE

ICC profile encoded in Base64. Can also be
set to empty string to avoid the ICC profile from the source dataset to be used.

- .. co:: WRITE_EXIF_METADATA
:choices: YES, NO
:default: YES
Expand Down
43 changes: 43 additions & 0 deletions frmts/avif/avifdataset.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -518,6 +518,20 @@ bool GDALAVIFDataset::Init(GDALOpenInfo *poOpenInfo)
GDALDataset::SetMetadata(const_cast<char **>(apszMD), "xml:XMP");
}

if (m_decoder->image->icc.size > 0)
{
// Escape the profile.
char *pszBase64Profile =
CPLBase64Encode(static_cast<int>(m_decoder->image->icc.size),
m_decoder->image->icc.data);

// Set ICC profile metadata.
SetMetadataItem("SOURCE_ICC_PROFILE", pszBase64Profile,
"COLOR_PROFILE");

CPLFree(pszBase64Profile);
}

// Initialize any PAM information.
if (m_decoder->imageCount > 1)
{
Expand Down Expand Up @@ -849,6 +863,25 @@ GDALDataset *GDALAVIFDataset::CreateCopy(const char *pszFilename,
}
}

#if AVIF_VERSION_MAJOR >= 1
const char *pszICCProfile =
CSLFetchNameValue(papszOptions, "SOURCE_ICC_PROFILE");
if (pszICCProfile == nullptr)
{
pszICCProfile =
poSrcDS->GetMetadataItem("SOURCE_ICC_PROFILE", "COLOR_PROFILE");
}
if (pszICCProfile && pszICCProfile[0] != '\0')
{
char *pEmbedBuffer = CPLStrdup(pszICCProfile);
const GInt32 nEmbedLen =
CPLBase64DecodeInPlace(reinterpret_cast<GByte *>(pEmbedBuffer));
CPL_IGNORE_RET_VAL(avifImageSetProfileICC(
image, reinterpret_cast<const uint8_t *>(pEmbedBuffer), nEmbedLen));
CPLFree(pEmbedBuffer);
}
#endif

avifErr =
avifEncoderAddImage(encoder, image, 1, AVIF_ADD_IMAGE_FLAG_SINGLE);
if (avifErr != AVIF_RESULT_OK)
Expand Down Expand Up @@ -1039,6 +1072,16 @@ void GDALAVIFDriver::InitMetadata()
CPLAddXMLAttributeAndValue(psOption, "default", "YES");
}

#if AVIF_VERSION_MAJOR >= 1
{
auto psOption = CPLCreateXMLNode(oTree.get(), CXT_Element, "Option");
CPLAddXMLAttributeAndValue(psOption, "name", "SOURCE_ICC_PROFILE");
CPLAddXMLAttributeAndValue(psOption, "type", "string");
CPLAddXMLAttributeAndValue(psOption, "description",
"ICC profile encoded in Base64");
}
#endif

{
auto psOption = CPLCreateXMLNode(oTree.get(), CXT_Element, "Option");
CPLAddXMLAttributeAndValue(psOption, "name", "NBITS");
Expand Down

0 comments on commit 18f0c9a

Please sign in to comment.