1 /*
2 * Copyright 2023 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8 #include "include/core/SkTypes.h"
9
10 #if defined(SK_XML)
11 #include "include/core/SkColor.h"
12 #include "include/core/SkData.h"
13 #include "include/core/SkRefCnt.h"
14 #include "include/private/SkGainmapInfo.h"
15 #include "include/private/SkXmp.h"
16 #include "tests/Test.h"
17
18 #include <cstddef>
19 #include <memory>
20
DEF_TEST(SkXmp_invalidXml,r)21 DEF_TEST(SkXmp_invalidXml, r) {
22 // Invalid truncated xml.
23 const char xmpData[] = R"(
24 <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="XMP Core 6.0.0">
25 <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
26 xmlns:)";
27
28 sk_sp<SkData> app1Param = SkData::MakeWithoutCopy(xmpData, sizeof(xmpData) - 1);
29
30 auto xmp = SkXmp::Make(app1Param);
31 REPORTER_ASSERT(r, xmp == nullptr);
32 }
33
34 DEF_TEST(SkXmp_xmpHdrgmAsFieldValue, r) {
35 // Expose HDRM values as fields. Also place the HDRGM namespace in the rdf:RDF node.
36 const char xmpData[] = R"(
37 <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="XMP Core 6.0.0">
38 <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
39 xmlns:hdrgm="http://ns.adobe.com/hdr-gain-map/1.0/">
40 <rdf:Description rdf:about="">
41 <hdrgm:Version>1.0</hdrgm:Version>
42 <hdrgm:GainMapMax>3</hdrgm:GainMapMax>
43 <hdrgm:HDRCapacityMax>4</hdrgm:HDRCapacityMax>
44 </rdf:Description>
45 </rdf:RDF>
46 </x:xmpmeta>)";
47
48 sk_sp<SkData> app1Param = SkData::MakeWithoutCopy(xmpData, sizeof(xmpData) - 1);
49
50 auto xmp = SkXmp::Make(app1Param);
51 REPORTER_ASSERT(r, xmp);
52
53 SkGainmapInfo info;
54 REPORTER_ASSERT(r, xmp->getGainmapInfoHDRGM(&info));
55 REPORTER_ASSERT(r, info.fGainmapRatioMax.fR == 8.f);
56 REPORTER_ASSERT(r, info.fDisplayRatioHdr == 16.f);
57 }
58
59 DEF_TEST(SkXmp_xmpHdrgmRequiresVersion, r) {
60 // Same as the above, except with Version being absent.
61 const char xmpData[] = R"(
62 <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="XMP Core 6.0.0">
63 <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
64 xmlns:hdrgm="http://ns.adobe.com/hdr-gain-map/1.0/">
65 <rdf:Description rdf:about="">
66 <hdrgm:GainMapMax>3</hdrgm:GainMapMax>
67 <hdrgm:HDRCapacityMax>4</hdrgm:HDRCapacityMax>
68 </rdf:Description>
69 </rdf:RDF>
70 </x:xmpmeta>)";
71
72 sk_sp<SkData> app1Param = SkData::MakeWithoutCopy(xmpData, sizeof(xmpData) - 1);
73
74 auto xmp = SkXmp::Make(app1Param);
75 REPORTER_ASSERT(r, xmp);
76
77 SkGainmapInfo info;
78 REPORTER_ASSERT(r, !xmp->getGainmapInfoHDRGM(&info));
79 }
80
81 DEF_TEST(SkXmp_xmpHdrgmAsDescriptionPropertyAttributes, r) {
82 // Expose HDRGM values as attributes on an rdf:Description node.
83 const char xmpData[] = R"(
84 <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="XMP Core 6.0.0">
85 <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
86 <rdf:Description rdf:about=""
87 xmlns:hdrgm="http://ns.adobe.com/hdr-gain-map/1.0/"
88 hdrgm:Version="1.0"
89 hdrgm:GainMapMax="3"
90 hdrgm:HDRCapacityMax="4"/>
91 </rdf:RDF>
92 </x:xmpmeta>)";
93
94 sk_sp<SkData> app1Param = SkData::MakeWithoutCopy(xmpData, sizeof(xmpData) - 1);
95
96 auto xmp = SkXmp::Make(app1Param);
97 REPORTER_ASSERT(r, xmp);
98
99 SkGainmapInfo info;
100 REPORTER_ASSERT(r, xmp->getGainmapInfoHDRGM(&info));
101 REPORTER_ASSERT(r, info.fGainmapRatioMax.fR == 8.f);
102 REPORTER_ASSERT(r, info.fDisplayRatioHdr == 16.f);
103 }
104
105 // Test mixed list and non-list entries.
106 DEF_TEST(SkXmp_xmpHdrgmList, r) {
107 const char xmpData[] = R"(
108 <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="XMP Core 6.0.0">
109 <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
110 xmlns:hdrgm="http://ns.adobe.com/hdr-gain-map/1.0/">
111 <rdf:Description rdf:about=""
112 hdrgm:Version="1.0"
113 hdrgm:GainMapMin="2.0"
114 hdrgm:OffsetSDR="0.1">
115 <hdrgm:GainMapMax>
116 <rdf:Seq>
117 <rdf:li>3</rdf:li>
118 <rdf:li>4</rdf:li>
119 <rdf:li>5</rdf:li>
120 </rdf:Seq>
121 </hdrgm:GainMapMax>
122 <hdrgm:Gamma>
123 1.2
124 </hdrgm:Gamma>
125 <hdrgm:OffsetHDR>
126 <rdf:Seq>
127 <rdf:li>
128 0.2
129 </rdf:li>
130 <rdf:li>
131 0.3
132 </rdf:li>
133 <rdf:li>
134 0.4
135 </rdf:li>
136 </rdf:Seq>
137 </hdrgm:OffsetHDR>
138 </rdf:Description>
139 </rdf:RDF>
140 </x:xmpmeta>)";
141
142 sk_sp<SkData> app1Param = SkData::MakeWithoutCopy(xmpData, sizeof(xmpData) - 1);
143
144 auto xmp = SkXmp::Make(app1Param);
145 REPORTER_ASSERT(r, xmp);
146
147 SkGainmapInfo info;
148 REPORTER_ASSERT(r, xmp->getGainmapInfoHDRGM(&info));
149 REPORTER_ASSERT(r, info.fGainmapRatioMin.fR == 4.f);
150 REPORTER_ASSERT(r, info.fGainmapRatioMin.fG == 4.f);
151 REPORTER_ASSERT(r, info.fGainmapRatioMin.fB == 4.f);
152 REPORTER_ASSERT(r, info.fGainmapRatioMax.fR == 8.f);
153 REPORTER_ASSERT(r, info.fGainmapRatioMax.fG == 16.f);
154 REPORTER_ASSERT(r, info.fGainmapRatioMax.fB == 32.f);
155
156 REPORTER_ASSERT(r, info.fGainmapGamma.fR == 1.f/1.2f);
157 REPORTER_ASSERT(r, info.fGainmapGamma.fG == 1.f/1.2f);
158 REPORTER_ASSERT(r, info.fGainmapGamma.fB == 1.f/1.2f);
159
160 REPORTER_ASSERT(r, info.fEpsilonSdr.fR == 0.1f);
161 REPORTER_ASSERT(r, info.fEpsilonSdr.fG == 0.1f);
162 REPORTER_ASSERT(r, info.fEpsilonSdr.fB == 0.1f);
163
164 REPORTER_ASSERT(r, info.fEpsilonHdr.fR == 0.2f);
165 REPORTER_ASSERT(r, info.fEpsilonHdr.fG == 0.3f);
166 REPORTER_ASSERT(r, info.fEpsilonHdr.fB == 0.4f);
167 }
168
169 DEF_TEST(SkXmp_xmpContainerTypedNode, r) {
170 // Container and Item using a node of type Container:Item.
171 const char xmpData[] = R"(
172 <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="XMP Core 5.5.0">
173 <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
174 <rdf:Description rdf:about=""
175 xmlns:Container="http://ns.google.com/photos/1.0/container/"
176 xmlns:Item="http://ns.google.com/photos/1.0/container/item/">
177 <Container:Directory>
178 <rdf:Seq>
179 <rdf:li rdf:parseType="Resource">
180 <Container:Item>
181 <Item:Mime>image/jpeg</Item:Mime>
182 <Item:Semantic>Primary</Item:Semantic>
183 </Container:Item>
184 </rdf:li>
185 <rdf:li rdf:parseType="Resource">
186 <Container:Item
187 Item:Semantic="GainMap"
188 Item:Mime="image/jpeg"
189 Item:Length="49035"/>
190 </rdf:li>
191 </rdf:Seq>
192 </Container:Directory>
193 </rdf:Description>
194 </rdf:RDF>
195 </x:xmpmeta>)";
196 sk_sp<SkData> app1Param = SkData::MakeWithoutCopy(xmpData, sizeof(xmpData) - 1);
197
198 auto xmp = SkXmp::Make(app1Param);
199 REPORTER_ASSERT(r, xmp);
200
201 size_t offset = 999;
202 size_t size = 999;
203 REPORTER_ASSERT(r, xmp->getContainerGainmapLocation(&offset, &size));
204 REPORTER_ASSERT(r, size == 49035);
205 }
206
207 DEF_TEST(SkXmp_xmpContainerTypedNodeRdfEquivalent, r) {
208 // Container and Item using rdf:value and rdf:type pairs.
209 const char xmpData[] = R"(
210 <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="XMP Core 5.5.0">
211 <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
212 <rdf:Description rdf:about=""
213 xmlns:Container="http://ns.google.com/photos/1.0/container/"
214 xmlns:Item="http://ns.google.com/photos/1.0/container/item/">
215 <Container:Directory>
216 <rdf:Seq>
217 <rdf:li rdf:parseType="Resource">
218 <rdf:value rdf:parseType="Resource">
219 <Item:Mime>image/jpeg</Item:Mime>
220 <Item:Semantic>Primary</Item:Semantic>
221 </rdf:value>
222 <rdf:type rdf:resource="Item"/>
223 </rdf:li>
224 <rdf:li rdf:parseType="Resource">
225 <rdf:value rdf:parseType="Resource">
226 <Item:Semantic>GainMap</Item:Semantic>
227 <Item:Mime>image/jpeg</Item:Mime>
228 <Item:Length>49035</Item:Length>
229 </rdf:value>
230 <rdf:type rdf:resource="Item"/>
231 </rdf:li>
232 </rdf:Seq>
233 </Container:Directory>
234 </rdf:Description>
235 </rdf:RDF>
236 </x:xmpmeta>)";
237 sk_sp<SkData> app1Param = SkData::MakeWithoutCopy(xmpData, sizeof(xmpData) - 1);
238
239 auto xmp = SkXmp::Make(app1Param);
240 REPORTER_ASSERT(r, xmp);
241
242 size_t offset = 999;
243 size_t size = 999;
244 REPORTER_ASSERT(r, xmp->getContainerGainmapLocation(&offset, &size));
245 REPORTER_ASSERT(r, size == 49035);
246 }
247 #endif // SK_XML
248