Flutter Engine
The Flutter Engine
Static Public Member Functions | List of all members
SkJpegGainmapEncoder Class Reference

#include <SkJpegGainmapEncoder.h>

Static Public Member Functions

static bool EncodeHDRGM (SkWStream *dst, const SkPixmap &base, const SkJpegEncoder::Options &baseOptions, const SkPixmap &gainmap, const SkJpegEncoder::Options &gainmapOptions, const SkGainmapInfo &gainmapInfo)
 
static bool MakeMPF (SkWStream *dst, const SkData **images, size_t imageCount)
 

Detailed Description

Definition at line 17 of file SkJpegGainmapEncoder.h.

Member Function Documentation

◆ EncodeHDRGM()

bool SkJpegGainmapEncoder::EncodeHDRGM ( SkWStream dst,
const SkPixmap base,
const SkJpegEncoder::Options baseOptions,
const SkPixmap gainmap,
const SkJpegEncoder::Options gainmapOptions,
const SkGainmapInfo gainmapInfo 
)
static

Encode an UltraHDR image to |dst|.

The base image is specified by |base|, and |baseOptions| controls the encoding behavior for the base image.

The gainmap image is specified by |gainmap|, and |gainmapOptions| controls the encoding behavior for the gainmap image.

The rendering behavior of the gainmap image is provided in |gainmapInfo|.

If |baseOptions| or |gainmapOptions| specify XMP metadata, then that metadata will be overwritten.

Returns true on success. Returns false on an invalid or unsupported |src|.

Definition at line 239 of file SkJpegGainmapEncoder.cpp.

244 {
245 bool includeUltraHDRv1 = gainmapInfo.isUltraHDRv1Compatible();
246
247 // All images will have the same minimial Exif metadata.
248 auto exif_params = get_exif_params();
249
250 // Encode the gainmap image.
251 sk_sp<SkData> gainmapData;
252 {
253 SkJpegMetadataEncoder::SegmentList metadataSegments;
254
255 // Start with Exif metadata.
256 metadataSegments.emplace_back(kExifMarker, exif_params);
257
258 // MPF segment will be inserted after this.
259
260 // Add XMP metadata.
261 if (includeUltraHDRv1) {
263 metadataSegments, get_gainmap_image_xmp_metadata(gainmapInfo).get());
264 }
265
266 // Include the ICC profile of the alternate color space, if it is used.
267 if (gainmapInfo.fGainmapMathColorSpace) {
269 metadataSegments, gainmapOptions, gainmapInfo.fGainmapMathColorSpace.get());
270 }
271
272 // Add the ISO 21946-1 metadata.
273 metadataSegments.emplace_back(kISOGainmapMarker,
275
276 // Encode the gainmap image.
277 gainmapData = encode_to_data(gainmap, gainmapOptions, metadataSegments);
278 if (!gainmapData) {
279 SkCodecPrintf("Failed to encode gainmap image.\n");
280 return false;
281 }
282 }
283
284 // Encode the base image.
285 sk_sp<SkData> baseData;
286 {
287 SkJpegMetadataEncoder::SegmentList metadataSegments;
288
289 // Start with Exif metadata.
290 metadataSegments.emplace_back(kExifMarker, exif_params);
291
292 // MPF segment will be inserted after this.
293
294 // Include XMP.
295 if (includeUltraHDRv1) {
296 // Add to the gainmap image size the size of the MPF segment for image 1 of a 2-image
297 // file.
299 size_t gainmapImageSize = gainmapData->size() + get_mpf_segment(mpParams, 1)->size();
301 metadataSegments,
302 get_base_image_xmp_metadata(static_cast<int32_t>(gainmapImageSize)).get());
303 }
304
305 // Include ICC profile metadata.
306 SkJpegMetadataEncoder::AppendICC(metadataSegments, baseOptions, base.colorSpace());
307
308 // Include the ISO 21946-1 version metadata.
309 metadataSegments.emplace_back(
312
313 // Encode the base image.
314 baseData = encode_to_data(base, baseOptions, metadataSegments);
315 if (!baseData) {
316 SkCodecPrintf("Failed to encode base image.\n");
317 return false;
318 }
319 }
320
321 // Combine them into an MPF.
322 const SkData* images[] = {
323 baseData.get(),
324 gainmapData.get(),
325 };
326 return MakeMPF(dst, images, 2);
327}
#define SkCodecPrintf(...)
Definition: SkCodecPriv.h:23
static constexpr uint32_t kExifMarker
static constexpr uint32_t kISOGainmapMarker
static sk_sp< SkData > get_base_image_xmp_metadata(size_t gainmapItemLength)
sk_sp< SkData > get_gainmap_image_xmp_metadata(const SkGainmapInfo &gainmapInfo)
static sk_sp< SkData > get_exif_params()
static sk_sp< SkData > encode_to_data(const SkPixmap &pm, const SkJpegEncoder::Options &options, const SkJpegMetadataEncoder::SegmentList &metadataSegments)
static sk_sp< SkData > get_iso_gainmap_segment_params(sk_sp< SkData > data)
static sk_sp< SkData > get_mpf_segment(const SkJpegMultiPictureParameters &mpParams, size_t imageNumber)
Definition: SkData.h:25
size_t size() const
Definition: SkData.h:30
static bool MakeMPF(SkWStream *dst, const SkData **images, size_t imageCount)
T * get() const
Definition: SkRefCnt.h:303
std::array< MockImage, 3 > images
Definition: mock_vulkan.cc:41
void AppendICC(SegmentList &segmentList, const SkJpegEncoder::Options &options, const SkColorSpace *colorSpace)
void AppendXMPStandard(SegmentList &segmentList, const SkData *xmpMetadata)
std::vector< Segment > SegmentList
dst
Definition: cp.py:12
const myers::Point & get(const myers::Segment &)
bool isUltraHDRv1Compatible() const
sk_sp< SkData > serialize() const
sk_sp< SkColorSpace > fGainmapMathColorSpace
Definition: SkGainmapInfo.h:95
static sk_sp< SkData > SerializeVersion()

◆ MakeMPF()

bool SkJpegGainmapEncoder::MakeMPF ( SkWStream dst,
const SkData **  images,
size_t  imageCount 
)
static

Write a Multi Picture Format containing the |imageCount| images specified by |images|.

Definition at line 362 of file SkJpegGainmapEncoder.cpp.

362 {
363 if (imageCount < 1) {
364 return true;
365 }
366
367 // The offset into each image at which the MP segment will be written.
368 std::vector<size_t> mpSegmentOffsets(imageCount);
369
370 // Populate the MP parameters (image sizes and offsets).
371 SkJpegMultiPictureParameters mpParams(imageCount);
372 size_t cumulativeSize = 0;
373 for (size_t i = 0; i < imageCount; ++i) {
374 // Compute the offset into the each image where we will write the MP parameters.
375 mpSegmentOffsets[i] = mp_segment_offset(images[i]);
376 if (!mpSegmentOffsets[i]) {
377 return false;
378 }
379
380 // Add the size of the MPF segment to image size. Note that the contents of
381 // get_mpf_segment() are incorrect (because we don't have the right offset values), but
382 // the size is correct.
383 const size_t imageSize = images[i]->size() + get_mpf_segment(mpParams, i)->size();
384 mpParams.images[i].dataOffset = SkJpegMultiPictureParameters::GetImageDataOffset(
385 cumulativeSize, mpSegmentOffsets[0]);
386 mpParams.images[i].size = static_cast<uint32_t>(imageSize);
387 cumulativeSize += imageSize;
388 }
389
390 // Write the images.
391 for (size_t i = 0; i < imageCount; ++i) {
392 // Write up to the MP segment.
393 if (!dst->write(images[i]->bytes(), mpSegmentOffsets[i])) {
394 SkCodecPrintf("Failed to write image header.\n");
395 return false;
396 }
397
398 // Write the MP segment.
399 auto mpfSegment = get_mpf_segment(mpParams, i);
400 if (!dst->write(mpfSegment->data(), mpfSegment->size())) {
401 SkCodecPrintf("Failed to write MPF segment.\n");
402 return false;
403 }
404
405 // Write the rest of the image.
406 if (!dst->write(images[i]->bytes() + mpSegmentOffsets[i],
407 images[i]->size() - mpSegmentOffsets[i])) {
408 SkCodecPrintf("Failed to write image body.\n");
409 return false;
410 }
411 }
412
413 return true;
414}
static size_t mp_segment_offset(const SkData *image)
static uint32_t GetImageDataOffset(size_t imageAbsoluteOffset, size_t mpSegmentOffset)

The documentation for this class was generated from the following files: