diff options
author | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2023-06-12 23:17:58 +0000 |
---|---|---|
committer | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2023-06-12 23:17:58 +0000 |
commit | 9705e6bf75e14e26b4ec56da75000e47cf4da1b0 (patch) | |
tree | 6b4cd16464b9bd971bc5b022665e62ddcca1b66d | |
parent | f91486202b3046279ddf200ed90df921c1ebba80 (diff) | |
parent | 6b9ad739c33975e0ec73bf116c834d5e86616c8e (diff) | |
download | skia-9705e6bf75e14e26b4ec56da75000e47cf4da1b0.tar.gz |
Snap for 10306978 from 6b9ad739c33975e0ec73bf116c834d5e86616c8e to udc-releaseandroid-security-14.0.0_r1
Change-Id: Iea5b686b985a90b31c160372b3d4d2cc01a30250
-rw-r--r-- | src/codec/SkJpegCodec.cpp | 20 | ||||
-rw-r--r-- | src/codec/SkJpegXmp.cpp | 27 | ||||
-rw-r--r-- | tests/JpegGainmapTest.cpp | 52 |
3 files changed, 96 insertions, 3 deletions
diff --git a/src/codec/SkJpegCodec.cpp b/src/codec/SkJpegCodec.cpp index df4b394f07..ac0bbf08c2 100644 --- a/src/codec/SkJpegCodec.cpp +++ b/src/codec/SkJpegCodec.cpp @@ -1153,6 +1153,7 @@ static std::unique_ptr<SkJpegMultiPictureParameters> find_mp_params( static bool extract_gainmap(SkJpegSourceMgr* decoderSource, size_t offset, size_t size, + bool base_image_has_hdrgm, SkGainmapInfo* outInfo, std::unique_ptr<SkStream>* outGainmapImageStream) { // Extract the SkData for this image. @@ -1189,8 +1190,19 @@ static bool extract_gainmap(SkJpegSourceMgr* decoderSource, } // Check if this image identifies itself as a gainmap. + bool did_populate_info = false; SkGainmapInfo info; - if (!xmp->getGainmapInfoHDRGM(&info) && !xmp->getGainmapInfoHDRGainMap(&info)) { + + // Check for HDRGM only if the base image specified hdrgm:Version="1.0". + did_populate_info = base_image_has_hdrgm && xmp->getGainmapInfoHDRGM(&info); + + // Next, check HDRGainMap. This does not require anything specific from the base image. + if (!did_populate_info) { + did_populate_info = xmp->getGainmapInfoHDRGainMap(&info); + } + + // If none of the formats identified itself as a gainmap and populated |info| then fail. + if (!did_populate_info) { return false; } @@ -1211,6 +1223,10 @@ bool SkJpegCodec::onGetGainmapInfo(SkGainmapInfo* info, // The GContainer and APP15-based HDRGM formats require XMP metadata. Extract it now. std::unique_ptr<SkJpegXmp> xmp = get_xmp_metadata(fDecoderMgr.get()); + // Set |base_image_has_hdrgm| to be true if the base image has HDRGM XMP metadata that includes + // the a Version 1.0 attribute. + const bool base_image_has_hdrgm = xmp && xmp->getGainmapInfoHDRGM(nullptr); + // Attempt to locate the gainmap from the container XMP. size_t containerGainmapOffset = 0; size_t containerGainmapSize = 0; @@ -1238,6 +1254,7 @@ bool SkJpegCodec::onGetGainmapInfo(SkGainmapInfo* info, if (extract_gainmap(fDecoderMgr->getSourceMgr(), mpImageOffset, mpImageSize, + base_image_has_hdrgm, info, gainmapImageStream)) { // If the GContainer also suggested an offset and size, assert that we found the @@ -1256,6 +1273,7 @@ bool SkJpegCodec::onGetGainmapInfo(SkGainmapInfo* info, if (extract_gainmap(fDecoderMgr->getSourceMgr(), containerGainmapOffset, containerGainmapSize, + base_image_has_hdrgm, info, gainmapImageStream)) { return true; diff --git a/src/codec/SkJpegXmp.cpp b/src/codec/SkJpegXmp.cpp index eff09a794d..dd3ba21faa 100644 --- a/src/codec/SkJpegXmp.cpp +++ b/src/codec/SkJpegXmp.cpp @@ -746,6 +746,23 @@ bool SkJpegXmp::getGainmapInfoHDRGM(SkGainmapInfo* outGainmapInfo) const { } const char* hdrgmPrefix = get_namespace_prefix(namespaces[0]); + // Require that hdrgm:Version="1.0" be present. + const char* version = get_attr(dom, node, hdrgmPrefix, "Version"); + if (!version) { + SkCodecPrintf("Version attribute is absent.\n"); + return false; + } + if (strcmp(version, "1.0") != 0) { + SkCodecPrintf("Version is \"%s\", not \"1.0\".\n", version); + return false; + } + + // If |outGainmapInfo| was not specified, then this function only verifies that the + // Version field be 1.0. It does not verify that GainMapMax or HDRCapacityMax be present. + if (!outGainmapInfo) { + return true; + } + // Initialize the parameters to their defaults. bool baseRenditionIsHDR = false; SkColor4f gainMapMin = {1.f, 1.f, 1.f, 1.f}; @@ -759,12 +776,18 @@ bool SkJpegXmp::getGainmapInfoHDRGM(SkGainmapInfo* outGainmapInfo) const { // Read all parameters that are present. get_attr_bool(dom, node, hdrgmPrefix, "BaseRenditionIsHDR", &baseRenditionIsHDR); get_attr_float3(dom, node, hdrgmPrefix, "GainMapMin", &gainMapMin); - get_attr_float3(dom, node, hdrgmPrefix, "GainMapMax", &gainMapMax); + if (!get_attr_float3(dom, node, hdrgmPrefix, "GainMapMax", &gainMapMax)) { + SkCodecPrintf("GainMapMax attribute is absent.\n"); + return false; + } get_attr_float3(dom, node, hdrgmPrefix, "Gamma", &gamma); get_attr_float3(dom, node, hdrgmPrefix, "OffsetSDR", &offsetSdr); get_attr_float3(dom, node, hdrgmPrefix, "OffsetHDR", &offsetHdr); get_attr_float(dom, node, hdrgmPrefix, "HDRCapacityMin", &hdrCapacityMin); - get_attr_float(dom, node, hdrgmPrefix, "HDRCapacityMax", &hdrCapacityMax); + if (!get_attr_float(dom, node, hdrgmPrefix, "HDRCapacityMax", &hdrCapacityMax)) { + SkCodecPrintf("HDRCapacityMax attribute is absent.\n"); + return false; + } // Translate all parameters to SkGainmapInfo's expected format. const float kLog2 = sk_float_log(2.f); diff --git a/tests/JpegGainmapTest.cpp b/tests/JpegGainmapTest.cpp index 385506e381..9bc7f93438 100644 --- a/tests/JpegGainmapTest.cpp +++ b/tests/JpegGainmapTest.cpp @@ -460,6 +460,57 @@ DEF_TEST(AndroidCodec_xmpHdrgmAsFieldValue, r) { REPORTER_ASSERT(r, info.fDisplayRatioHdr == 16.f); } +DEF_TEST(AndroidCodec_xmpHdrgmRequiresVersion, r) { + // Same as the above, except with Version being absent. + const char xmpData[] = + "http://ns.adobe.com/xap/1.0/\0" + "<x:xmpmeta xmlns:x=\"adobe:ns:meta/\" x:xmptk=\"XMP Core 6.0.0\">\n" + " <rdf:RDF xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\"\n" + " xmlns:hdrgm=\"http://ns.adobe.com/hdr-gain-map/1.0/\">\n" + " <rdf:Description rdf:about=\"\">\n" + " <hdrgm:GainMapMax>3</hdrgm:GainMapMax>\n" + " <hdrgm:HDRCapacityMax>4</hdrgm:HDRCapacityMax>\n" + " </rdf:Description>\n" + " </rdf:RDF>\n" + "</x:xmpmeta>\n"; + + std::vector<sk_sp<SkData>> app1Params; + app1Params.push_back(SkData::MakeWithoutCopy(xmpData, sizeof(xmpData) - 1)); + + auto xmp = SkJpegXmp::Make(app1Params); + REPORTER_ASSERT(r, xmp); + + SkGainmapInfo info; + REPORTER_ASSERT(r, !xmp->getGainmapInfoHDRGM(&info)); +} + +DEF_TEST(AndroidCodec_xmpHdrgmRequiresHdrCapacityMax, r) { + // Same as the above, except with HDRCapacityMax being absent. + const char xmpData[] = + "http://ns.adobe.com/xap/1.0/\0" + "<x:xmpmeta xmlns:x=\"adobe:ns:meta/\" x:xmptk=\"XMP Core 6.0.0\">\n" + " <rdf:RDF xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\"\n" + " xmlns:hdrgm=\"http://ns.adobe.com/hdr-gain-map/1.0/\">\n" + " <rdf:Description rdf:about=\"\">\n" + " <hdrgm:Version>1.0</hdrgm:Version>\n" + " <hdrgm:GainMapMax>3</hdrgm:GainMapMax>\n" + " </rdf:Description>\n" + " </rdf:RDF>\n" + "</x:xmpmeta>\n"; + + std::vector<sk_sp<SkData>> app1Params; + app1Params.push_back(SkData::MakeWithoutCopy(xmpData, sizeof(xmpData) - 1)); + + auto xmp = SkJpegXmp::Make(app1Params); + REPORTER_ASSERT(r, xmp); + + SkGainmapInfo info; + // The version check works. + REPORTER_ASSERT(r, xmp->getGainmapInfoHDRGM(nullptr)); + // Populating the gainmap metadata doesn't. + REPORTER_ASSERT(r, !xmp->getGainmapInfoHDRGM(&info)); +} + DEF_TEST(AndroidCodec_xmpHdrgmAsDescriptionPropertyAttributes, r) { // Expose HDRGM values as attributes on an rdf:Description node. const char xmpData[] = @@ -495,6 +546,7 @@ DEF_TEST(AndroidCodec_xmpHdrgmList, r) { " xmlns:hdrgm=\"http://ns.adobe.com/hdr-gain-map/1.0/\">\n" " <rdf:Description rdf:about=\"\"\n" " hdrgm:Version=\"1.0\"\n" + " hdrgm:HDRCapacityMax=\"4\"\n" " hdrgm:GainMapMin=\"2.0\"\n" " hdrgm:OffsetSDR=\"0.1\">\n" " <hdrgm:GainMapMax>\n" |