Flutter Engine
The Flutter Engine
Functions
SkJpegGainmapEncoder.cpp File Reference
#include "include/private/SkJpegGainmapEncoder.h"
#include "include/core/SkBitmap.h"
#include "include/core/SkPixmap.h"
#include "include/core/SkStream.h"
#include "include/encode/SkEncoder.h"
#include "include/encode/SkJpegEncoder.h"
#include "include/private/SkGainmapInfo.h"
#include "src/codec/SkCodecPriv.h"
#include "src/codec/SkJpegConstants.h"
#include "src/codec/SkJpegMultiPicture.h"
#include "src/codec/SkJpegPriv.h"
#include "src/codec/SkJpegSegmentScan.h"
#include "src/codec/SkTiffUtility.h"
#include "src/core/SkStreamPriv.h"
#include "src/encode/SkJpegEncoderImpl.h"
#include <vector>

Go to the source code of this file.

Functions

static bool is_single_channel (SkColor4f c)
 
sk_sp< SkDataget_gainmap_image_xmp_metadata (const SkGainmapInfo &gainmapInfo)
 
static sk_sp< SkDataget_base_image_xmp_metadata (size_t gainmapItemLength)
 
static sk_sp< SkDataencode_to_data (const SkPixmap &pm, const SkJpegEncoder::Options &options, const SkJpegMetadataEncoder::SegmentList &metadataSegments)
 
static sk_sp< SkDataget_exif_params ()
 
static sk_sp< SkDataget_mpf_segment (const SkJpegMultiPictureParameters &mpParams, size_t imageNumber)
 
static sk_sp< SkDataget_iso_gainmap_segment_params (sk_sp< SkData > data)
 
static size_t mp_segment_offset (const SkData *image)
 

Function Documentation

◆ encode_to_data()

static sk_sp< SkData > encode_to_data ( const SkPixmap pm,
const SkJpegEncoder::Options options,
const SkJpegMetadataEncoder::SegmentList metadataSegments 
)
static

Definition at line 162 of file SkJpegGainmapEncoder.cpp.

164 {
165 SkDynamicMemoryWStream encodeStream;
166 auto encoder = SkJpegEncoderImpl::MakeRGB(&encodeStream, pm, options, metadataSegments);
167 if (!encoder || !encoder->encodeRows(pm.height())) {
168 return nullptr;
169 }
170 return encodeStream.detachAsData();
171}
const char * options
sk_sp< SkData > detachAsData()
Definition: SkStream.cpp:707
static std::unique_ptr< SkEncoder > MakeRGB(SkWStream *dst, const SkPixmap &src, const SkJpegEncoder::Options &options, const SkJpegMetadataEncoder::SegmentList &metadata)
int height() const
Definition: SkPixmap.h:166

◆ get_base_image_xmp_metadata()

static sk_sp< SkData > get_base_image_xmp_metadata ( size_t  gainmapItemLength)
static

Definition at line 128 of file SkJpegGainmapEncoder.cpp.

128 {
130 s.writeText(
131 "<x:xmpmeta xmlns:x=\"adobe:ns:meta/\" x:xmptk=\"Adobe XMP Core 5.1.2\">\n"
132 " <rdf:RDF xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\">\n"
133 " <rdf:Description\n"
134 " xmlns:Container=\"http://ns.google.com/photos/1.0/container/\"\n"
135 " xmlns:Item=\"http://ns.google.com/photos/1.0/container/item/\"\n"
136 " xmlns:hdrgm=\"http://ns.adobe.com/hdr-gain-map/1.0/\"\n"
137 " hdrgm:Version=\"1.0\">\n"
138 " <Container:Directory>\n"
139 " <rdf:Seq>\n"
140 " <rdf:li rdf:parseType=\"Resource\">\n"
141 " <Container:Item\n"
142 " Item:Semantic=\"Primary\"\n"
143 " Item:Mime=\"image/jpeg\"/>\n"
144 " </rdf:li>\n"
145 " <rdf:li rdf:parseType=\"Resource\">\n"
146 " <Container:Item\n"
147 " Item:Semantic=\"GainMap\"\n"
148 " Item:Mime=\"image/jpeg\"\n"
149 " Item:Length=\"");
150 s.writeDecAsText(gainmapItemLength);
151 s.writeText(
152 "\"/>\n"
153 " </rdf:li>\n"
154 " </rdf:Seq>\n"
155 " </Container:Directory>\n"
156 " </rdf:Description>\n"
157 " </rdf:RDF>\n"
158 "</x:xmpmeta>\n");
159 return s.detachAsData();
160}
struct MyStruct s

◆ get_exif_params()

static sk_sp< SkData > get_exif_params ( )
static

Definition at line 173 of file SkJpegGainmapEncoder.cpp.

173 {
175
176 s.write(kExifSig, sizeof(kExifSig));
177 s.write8(0);
178
180 SkWStreamWriteU32BE(&s, 8); // Offset of index IFD
181
182 // Write the index IFD.
183 {
184 constexpr uint16_t kIndexIfdNumberOfTags = 1;
185 SkWStreamWriteU16BE(&s, kIndexIfdNumberOfTags);
186
187 constexpr uint16_t kSubIFDOffsetTag = 0x8769;
188 constexpr uint32_t kSubIfdCount = 1;
189 constexpr uint32_t kSubIfdOffset = 26;
192 SkWStreamWriteU32BE(&s, kSubIfdCount);
193 SkWStreamWriteU32BE(&s, kSubIfdOffset);
194
195 constexpr uint32_t kIndexIfdNextIfdOffset = 0;
196 SkWStreamWriteU32BE(&s, kIndexIfdNextIfdOffset);
197 }
198
199 // Write the sub-IFD.
200 {
201 constexpr uint16_t kSubIfdNumberOfTags = 1;
202 SkWStreamWriteU16BE(&s, kSubIfdNumberOfTags);
203
204 constexpr uint16_t kVersionTag = 0x9000;
205 constexpr uint32_t kVersionCount = 4;
206 constexpr uint8_t kVersion[kVersionCount] = {'0', '2', '3', '2'};
210 s.write(kVersion, sizeof(kVersion));
211
212 constexpr uint32_t kSubIfdNextIfdOffset = 0;
213 SkWStreamWriteU32BE(&s, kSubIfdNextIfdOffset);
214 }
215
216 return s.detachAsData();
217}
constexpr uint8_t kExifSig[]
constexpr uint16_t kVersionTag
constexpr uint32_t kVersionCount
bool SkWStreamWriteU32BE(SkWStream *s, uint32_t value)
Definition: SkStreamPriv.h:54
bool SkWStreamWriteU16BE(SkWStream *s, uint16_t value)
Definition: SkStreamPriv.h:49
constexpr uint16_t kSubIFDOffsetTag
Definition: SkExif.cpp:22
constexpr uint8_t kEndianBig[kEndianSize]
Definition: SkTiffUtility.h:22
constexpr uint16_t kTypeUnsignedLong
Definition: SkTiffUtility.h:29
constexpr uint16_t kTypeUndefined
Definition: SkTiffUtility.h:32

◆ get_gainmap_image_xmp_metadata()

sk_sp< SkData > get_gainmap_image_xmp_metadata ( const SkGainmapInfo gainmapInfo)

Definition at line 33 of file SkJpegGainmapEncoder.cpp.

33 {
35 const float kLog2 = std::log(2.f);
36 const SkColor4f gainMapMin = {std::log(gainmapInfo.fGainmapRatioMin.fR) / kLog2,
37 std::log(gainmapInfo.fGainmapRatioMin.fG) / kLog2,
38 std::log(gainmapInfo.fGainmapRatioMin.fB) / kLog2,
39 1.f};
40 const SkColor4f gainMapMax = {std::log(gainmapInfo.fGainmapRatioMax.fR) / kLog2,
41 std::log(gainmapInfo.fGainmapRatioMax.fG) / kLog2,
42 std::log(gainmapInfo.fGainmapRatioMax.fB) / kLog2,
43 1.f};
44 const SkColor4f gamma = {1.f / gainmapInfo.fGainmapGamma.fR,
45 1.f / gainmapInfo.fGainmapGamma.fG,
46 1.f / gainmapInfo.fGainmapGamma.fB,
47 1.f};
48 // Write a scalar attribute.
49 auto write_scalar_attr = [&s](const char* attrib, SkScalar value) {
50 s.writeText(" ");
51 s.writeText(attrib);
52 s.writeText("=\"");
53 s.writeScalarAsText(value);
54 s.writeText("\"\n");
55 };
56
57 // Write a scalar attribute only if all channels of |value| are equal (otherwise, write
58 // nothing).
59 auto maybe_write_scalar_attr = [&write_scalar_attr](const char* attrib, SkColor4f value) {
61 return;
62 }
63 write_scalar_attr(attrib, value.fR);
64 };
65
66 // Write a float3 attribute as a list ony if not all channels of |value| are equal (otherwise,
67 // write nothing).
68 auto maybe_write_float3_attr = [&s](const char* attrib, SkColor4f value) {
70 return;
71 }
72 s.writeText(" <");
73 s.writeText(attrib);
74 s.writeText(">\n");
75 s.writeText(" <rdf:Seq>\n");
76 s.writeText(" <rdf:li>");
77 s.writeScalarAsText(value.fR);
78 s.writeText("</rdf:li>\n");
79 s.writeText(" <rdf:li>");
80 s.writeScalarAsText(value.fG);
81 s.writeText("</rdf:li>\n");
82 s.writeText(" <rdf:li>");
83 s.writeScalarAsText(value.fB);
84 s.writeText("</rdf:li>\n");
85 s.writeText(" </rdf:Seq>\n");
86 s.writeText(" </");
87 s.writeText(attrib);
88 s.writeText(">\n");
89 };
90
91 s.writeText(
92 "<x:xmpmeta xmlns:x=\"adobe:ns:meta/\" x:xmptk=\"XMP Core 5.5.0\">\n"
93 " <rdf:RDF xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\">\n"
94 " <rdf:Description rdf:about=\"\"\n"
95 " xmlns:hdrgm=\"http://ns.adobe.com/hdr-gain-map/1.0/\"\n"
96 " hdrgm:Version=\"1.0\"\n");
97 maybe_write_scalar_attr("hdrgm:GainMapMin", gainMapMin);
98 maybe_write_scalar_attr("hdrgm:GainMapMax", gainMapMax);
99 maybe_write_scalar_attr("hdrgm:Gamma", gamma);
100 maybe_write_scalar_attr("hdrgm:OffsetSDR", gainmapInfo.fEpsilonSdr);
101 maybe_write_scalar_attr("hdrgm:OffsetHDR", gainmapInfo.fEpsilonHdr);
102 write_scalar_attr("hdrgm:HDRCapacityMin", std::log(gainmapInfo.fDisplayRatioSdr) / kLog2);
103 write_scalar_attr("hdrgm:HDRCapacityMax", std::log(gainmapInfo.fDisplayRatioHdr) / kLog2);
104 switch (gainmapInfo.fBaseImageType) {
106 s.writeText(" hdrgm:BaseRenditionIsHDR=\"False\">\n");
107 break;
109 s.writeText(" hdrgm:BaseRenditionIsHDR=\"True\">\n");
110 break;
111 }
112
113 // Write any of the vector parameters that cannot be represented as scalars (and thus cannot
114 // be written inline as above).
115 maybe_write_float3_attr("hdrgm:GainMapMin", gainMapMin);
116 maybe_write_float3_attr("hdrgm:GainMapMax", gainMapMax);
117 maybe_write_float3_attr("hdrgm:Gamma", gamma);
118 maybe_write_float3_attr("hdrgm:OffsetSDR", gainmapInfo.fEpsilonSdr);
119 maybe_write_float3_attr("hdrgm:OffsetHDR", gainmapInfo.fEpsilonHdr);
120 s.writeText(
121 " </rdf:Description>\n"
122 " </rdf:RDF>\n"
123 "</x:xmpmeta>");
124 return s.detachAsData();
125}
static bool is_single_channel(SkColor4f c)
float SkScalar
Definition: extension.cpp:12
uint8_t value
SkColor4f fGainmapRatioMax
Definition: SkGainmapInfo.h:49
SkColor4f fEpsilonSdr
Definition: SkGainmapInfo.h:55
SkColor4f fGainmapGamma
Definition: SkGainmapInfo.h:50
SkColor4f fGainmapRatioMin
Definition: SkGainmapInfo.h:48
BaseImageType fBaseImageType
Definition: SkGainmapInfo.h:75
float fDisplayRatioSdr
Definition: SkGainmapInfo.h:65
SkColor4f fEpsilonHdr
Definition: SkGainmapInfo.h:56
float fDisplayRatioHdr
Definition: SkGainmapInfo.h:66

◆ get_iso_gainmap_segment_params()

static sk_sp< SkData > get_iso_gainmap_segment_params ( sk_sp< SkData data)
static

Definition at line 232 of file SkJpegGainmapEncoder.cpp.

232 {
234 s.write(kISOGainmapSig, sizeof(kISOGainmapSig));
235 s.write(data->data(), data->size());
236 return s.detachAsData();
237}
static constexpr uint8_t kISOGainmapSig[]
std::shared_ptr< const fml::Mapping > data
Definition: texture_gles.cc:63

◆ get_mpf_segment()

static sk_sp< SkData > get_mpf_segment ( const SkJpegMultiPictureParameters mpParams,
size_t  imageNumber 
)
static

Definition at line 219 of file SkJpegGainmapEncoder.cpp.

220 {
222 auto segmentParameters = mpParams.serialize(static_cast<uint32_t>(imageNumber));
223 const size_t mpParameterLength = kJpegSegmentParameterLengthSize + segmentParameters->size();
224 s.write8(0xFF);
225 s.write8(kMpfMarker);
226 s.write8(mpParameterLength / 256);
227 s.write8(mpParameterLength % 256);
228 s.write(segmentParameters->data(), segmentParameters->size());
229 return s.detachAsData();
230}
static constexpr uint32_t kMpfMarker
static constexpr size_t kJpegSegmentParameterLengthSize
sk_sp< SkData > serialize(uint32_t individualImageNumber) const

◆ is_single_channel()

static bool is_single_channel ( SkColor4f  c)
static

Definition at line 27 of file SkJpegGainmapEncoder.cpp.

27{ return c.fR == c.fG && c.fG == c.fB; };

◆ mp_segment_offset()

static size_t mp_segment_offset ( const SkData image)
static

Definition at line 330 of file SkJpegGainmapEncoder.cpp.

330 {
331 // Scan the image until StartOfScan marker.
333 scan.onBytes(image->data(), image->size());
334 if (!scan.isDone()) {
335 SkCodecPrintf("Failed to scan image header.\n");
336 return 0;
337 }
338 const auto& segments = scan.getSegments();
339
340 // Search for the Exif segment and place the MP parameters immediately after. See 5.1.
341 // Basic MP File Structure, which indicates "The MP Extensions are specified in the APP2
342 // marker segment which follows immediately after the Exif Attributes in the APP1 marker
343 // segment except as specified in section 7".
344 for (size_t segmentIndex = 0; segmentIndex < segments.size() - 1; ++segmentIndex) {
345 const auto& segment = segments[segmentIndex];
346 if (segment.marker != kExifMarker) {
347 continue;
348 }
350 if (params->size() < sizeof(kExifSig) ||
351 memcmp(params->data(), kExifSig, sizeof(kExifSig)) != 0) {
352 continue;
353 }
354 // Insert the MPF segment at the offset of the next segment.
355 return segments[segmentIndex + 1].offset;
356 }
357
358 // If there is no Exif segment, then insert the MPF segment just before the StartOfScan.
359 return segments.back().offset;
360}
#define SkCodecPrintf(...)
Definition: SkCodecPriv.h:23
static constexpr uint32_t kExifMarker
static constexpr uint8_t kJpegMarkerStartOfScan
static sk_sp< SkData > GetParameters(const SkData *scannedData, const SkJpegSegment &segment)
const EmbeddedViewParams * params
sk_sp< const SkImage > image
Definition: SkRecords.h:269