Flutter Engine
The Flutter Engine
Classes | Static Public Member Functions | Protected Member Functions | List of all members
SkHeifCodec Class Reference

#include <SkHeifCodec.h>

Inheritance diagram for SkHeifCodec:
SkCodec SkNoncopyable

Static Public Member Functions

static bool IsSupported (const void *, size_t, SkEncodedImageFormat *format)
 
static std::unique_ptr< SkCodecMakeFromStream (std::unique_ptr< SkStream >, SkCodec::SelectionPolicy selectionPolicy, Result *)
 
- Static Public Member Functions inherited from SkCodec
static constexpr size_t MinBufferedBytesNeeded ()
 
static const char * ResultToString (Result)
 
static std::unique_ptr< SkCodecMakeFromStream (std::unique_ptr< SkStream >, SkSpan< const SkCodecs::Decoder > decoders, Result *=nullptr, SkPngChunkReader *=nullptr, SelectionPolicy selectionPolicy=SelectionPolicy::kPreferStillImage)
 
static std::unique_ptr< SkCodecMakeFromStream (std::unique_ptr< SkStream >, Result *=nullptr, SkPngChunkReader *=nullptr, SelectionPolicy selectionPolicy=SelectionPolicy::kPreferStillImage)
 
static std::unique_ptr< SkCodecMakeFromData (sk_sp< SkData >, SkSpan< const SkCodecs::Decoder > decoders, SkPngChunkReader *=nullptr)
 
static std::unique_ptr< SkCodecMakeFromData (sk_sp< SkData >, SkPngChunkReader *=nullptr)
 
static void Register (bool(*peek)(const void *, size_t), std::unique_ptr< SkCodec >(*make)(std::unique_ptr< SkStream >, SkCodec::Result *))
 

Protected Member Functions

Result onGetPixels (const SkImageInfo &dstInfo, void *dst, size_t dstRowBytes, const Options &options, int *rowsDecoded) override
 
SkEncodedImageFormat onGetEncodedFormat () const override
 
int onGetFrameCount () override
 
bool onGetFrameInfo (int, FrameInfo *) const override
 
int onGetRepetitionCount () override
 
const SkFrameHoldergetFrameHolder () const override
 
bool conversionSupported (const SkImageInfo &, bool, bool) override
 
bool onRewind () override
 
- Protected Member Functions inherited from SkCodec
const SkEncodedInfogetEncodedInfo () const
 
 SkCodec (SkEncodedInfo &&, XformFormat srcFormat, std::unique_ptr< SkStream >, SkEncodedOrigin=kTopLeft_SkEncodedOrigin)
 
void setSrcXformFormat (XformFormat pixelFormat)
 
XformFormat getSrcXformFormat () const
 
virtual bool onGetGainmapInfo (SkGainmapInfo *, std::unique_ptr< SkStream > *)
 
virtual SkISize onGetScaledDimensions (float) const
 
virtual bool onDimensionsSupported (const SkISize &)
 
virtual SkEncodedImageFormat onGetEncodedFormat () const =0
 
virtual Result onGetPixels (const SkImageInfo &info, void *pixels, size_t rowBytes, const Options &, int *rowsDecoded)=0
 
virtual bool onQueryYUVAInfo (const SkYUVAPixmapInfo::SupportedDataTypes &, SkYUVAPixmapInfo *) const
 
virtual Result onGetYUVAPlanes (const SkYUVAPixmaps &)
 
virtual bool onGetValidSubset (SkIRect *) const
 
bool rewindIfNeeded ()
 
virtual bool onRewind ()
 
SkStreamstream ()
 
virtual SkScanlineOrder onGetScanlineOrder () const
 
const SkImageInfodstInfo () const
 
const Optionsoptions () const
 
int currScanline () const
 
virtual int onOutputScanline (int inputScanline) const
 
virtual bool conversionSupported (const SkImageInfo &dst, bool srcIsOpaque, bool needsColorXform)
 
virtual bool usesColorXform () const
 
void applyColorXform (void *dst, const void *src, int count) const
 
bool colorXform () const
 
bool xformOnDecode () const
 
virtual int onGetFrameCount ()
 
virtual bool onGetFrameInfo (int, FrameInfo *) const
 
virtual int onGetRepetitionCount ()
 

Additional Inherited Members

- Public Types inherited from SkCodec
enum  Result {
  kSuccess , kIncompleteInput , kErrorInInput , kInvalidConversion ,
  kInvalidScale , kInvalidParameters , kInvalidInput , kCouldNotRewind ,
  kInternalError , kUnimplemented
}
 
enum class  SelectionPolicy { kPreferStillImage , kPreferAnimation }
 
enum  ZeroInitialized { kYes_ZeroInitialized , kNo_ZeroInitialized }
 
enum  SkScanlineOrder { kTopDown_SkScanlineOrder , kBottomUp_SkScanlineOrder }
 
- Public Member Functions inherited from SkCodec
virtual ~SkCodec ()
 
SkImageInfo getInfo () const
 
SkISize dimensions () const
 
SkIRect bounds () const
 
const skcms_ICCProfilegetICCProfile () const
 
SkEncodedOrigin getOrigin () const
 
SkISize getScaledDimensions (float desiredScale) const
 
bool getValidSubset (SkIRect *desiredSubset) const
 
SkEncodedImageFormat getEncodedFormat () const
 
virtual std::unique_ptr< SkStreamgetEncodedData () const
 
Result getPixels (const SkImageInfo &info, void *pixels, size_t rowBytes, const Options *)
 
Result getPixels (const SkImageInfo &info, void *pixels, size_t rowBytes)
 
Result getPixels (const SkPixmap &pm, const Options *opts=nullptr)
 
std::tuple< sk_sp< SkImage >, SkCodec::ResultgetImage (const SkImageInfo &info, const Options *opts=nullptr)
 
std::tuple< sk_sp< SkImage >, SkCodec::ResultgetImage ()
 
bool queryYUVAInfo (const SkYUVAPixmapInfo::SupportedDataTypes &supportedDataTypes, SkYUVAPixmapInfo *yuvaPixmapInfo) const
 
Result getYUVAPlanes (const SkYUVAPixmaps &yuvaPixmaps)
 
Result startIncrementalDecode (const SkImageInfo &dstInfo, void *dst, size_t rowBytes, const Options *)
 
Result startIncrementalDecode (const SkImageInfo &dstInfo, void *dst, size_t rowBytes)
 
Result incrementalDecode (int *rowsDecoded=nullptr)
 
Result startScanlineDecode (const SkImageInfo &dstInfo, const Options *options)
 
Result startScanlineDecode (const SkImageInfo &dstInfo)
 
int getScanlines (void *dst, int countLines, size_t rowBytes)
 
bool skipScanlines (int countLines)
 
SkScanlineOrder getScanlineOrder () const
 
int nextScanline () const
 
int outputScanline (int inputScanline) const
 
int getFrameCount ()
 
bool getFrameInfo (int index, FrameInfo *info) const
 
std::vector< FrameInfogetFrameInfo ()
 
int getRepetitionCount ()
 
- Static Public Attributes inherited from SkCodec
static constexpr int kNoFrame = -1
 
static constexpr int kRepetitionCountInfinite = -1
 
- Protected Types inherited from SkCodec
using XformFormat = skcms_PixelFormat
 

Detailed Description

Definition at line 25 of file SkHeifCodec.h.

Member Function Documentation

◆ conversionSupported()

bool SkHeifCodec::conversionSupported ( const SkImageInfo dst,
bool  srcIsOpaque,
bool  needsColorXform 
)
overrideprotectedvirtual

Return whether we can convert to dst.

Will be called for the appropriate frame, prior to initializing the colorXform.

Reimplemented from SkCodec.

Definition at line 231 of file SkHeifCodec.cpp.

232 {
233 SkASSERT(srcIsOpaque);
234
236 return false;
237 }
238
240 SkCodecPrintf("Warning: an opaque image should be decoded as opaque "
241 "- it is being decoded as non-opaque, which will draw slower\n");
242 }
243
244 uint8_t colorDepth = fHeifDecoder->getColorDepth();
245 switch (dstInfo.colorType()) {
248 return fHeifDecoder->setOutputColor(kHeifColorFormat_RGBA_8888);
249
252 return fHeifDecoder->setOutputColor(kHeifColorFormat_BGRA_8888);
253
256 if (needsColorXform) {
257 return fHeifDecoder->setOutputColor(kHeifColorFormat_RGBA_8888);
258 } else {
259 return fHeifDecoder->setOutputColor(kHeifColorFormat_RGB565);
260 }
261
264 return fHeifDecoder->setOutputColor(kHeifColorFormat_RGBA_1010102);
265
267 SkASSERT(needsColorXform);
268 if (srcIsOpaque && colorDepth == 10) {
270 return fHeifDecoder->setOutputColor(kHeifColorFormat_RGBA_1010102);
271 } else {
273 return fHeifDecoder->setOutputColor(kHeifColorFormat_RGBA_8888);
274 }
275
276 default:
277 return false;
278 }
279}
@ kUnknown_SkAlphaType
uninitialized
Definition: SkAlphaType.h:27
@ kOpaque_SkAlphaType
pixel is opaque
Definition: SkAlphaType.h:28
#define SkASSERT(cond)
Definition: SkAssert.h:116
#define SkCodecPrintf(...)
Definition: SkCodecPriv.h:23
@ kBGRA_8888_SkColorType
pixel with 8 bits for blue, green, red, alpha; in 32-bit word
Definition: SkColorType.h:26
@ kRGBA_F16_SkColorType
pixel with half floats for red, green, blue, alpha;
Definition: SkColorType.h:38
@ kRGB_565_SkColorType
pixel with 5 bits red, 6 bits green, 5 bits blue, in 16-bit word
Definition: SkColorType.h:22
@ kRGBA_8888_SkColorType
pixel with 8 bits for red, green, blue, alpha; in 32-bit word
Definition: SkColorType.h:24
@ kRGBA_1010102_SkColorType
10 bits for red, green, blue; 2 bits for alpha; in 32-bit word
Definition: SkColorType.h:27
@ kHeifColorFormat_RGBA_1010102
@ kHeifColorFormat_RGB565
@ kHeifColorFormat_BGRA_8888
@ kHeifColorFormat_RGBA_8888
const SkImageInfo & dstInfo() const
Definition: SkCodec.h:878
void setSrcXformFormat(XformFormat pixelFormat)
Definition: SkCodec.cpp:263
@ skcms_PixelFormat_RGBA_1010102
Definition: skcms_public.h:292
@ skcms_PixelFormat_RGBA_8888
Definition: skcms_public.h:287
SkAlphaType alphaType() const
Definition: SkImageInfo.h:375
SkColorType colorType() const
Definition: SkImageInfo.h:373

◆ getFrameHolder()

const SkFrameHolder * SkHeifCodec::getFrameHolder ( ) const
inlineoverrideprotectedvirtual

For multi-framed images, return the object with information about the frames.

Reimplemented from SkCodec.

Definition at line 56 of file SkHeifCodec.h.

56 {
57 return &fFrameHolder;
58 }

◆ IsSupported()

bool SkHeifCodec::IsSupported ( const void *  buffer,
size_t  bytesRead,
SkEncodedImageFormat format 
)
static

Definition at line 21 of file SkHeifCodec.cpp.

22 {
23 // Parse the ftyp box up to bytesRead to determine if this is HEIF or AVIF.
24 // Any valid ftyp box should have at least 8 bytes.
25 if (bytesRead < 8) {
26 return false;
27 }
28
29 const uint32_t* ptr = (const uint32_t*)buffer;
30 uint64_t chunkSize = SkEndian_SwapBE32(ptr[0]);
31 uint32_t chunkType = SkEndian_SwapBE32(ptr[1]);
32
33 if (chunkType != FOURCC('f', 't', 'y', 'p')) {
34 return false;
35 }
36
37 int64_t offset = 8;
38 if (chunkSize == 1) {
39 // This indicates that the next 8 bytes represent the chunk size,
40 // and chunk data comes after that.
41 if (bytesRead < 16) {
42 return false;
43 }
44 auto* chunkSizePtr = SkTAddOffset<const uint64_t>(buffer, offset);
45 chunkSize = SkEndian_SwapBE64(*chunkSizePtr);
46 if (chunkSize < 16) {
47 // The smallest valid chunk is 16 bytes long in this case.
48 return false;
49 }
50 offset += 8;
51 } else if (chunkSize < 8) {
52 // The smallest valid chunk is 8 bytes long.
53 return false;
54 }
55
56 if (chunkSize > bytesRead) {
57 chunkSize = bytesRead;
58 }
59 int64_t chunkDataSize = chunkSize - offset;
60 // It should at least have major brand (4-byte) and minor version (4-bytes).
61 // The rest of the chunk (if any) is a list of (4-byte) compatible brands.
62 if (chunkDataSize < 8) {
63 return false;
64 }
65
66 uint32_t numCompatibleBrands = (chunkDataSize - 8) / 4;
67 bool isHeif = false;
68 for (size_t i = 0; i < numCompatibleBrands + 2; ++i) {
69 if (i == 1) {
70 // Skip this index, it refers to the minorVersion,
71 // not a brand.
72 continue;
73 }
74 auto* brandPtr = SkTAddOffset<const uint32_t>(buffer, offset + 4 * i);
75 uint32_t brand = SkEndian_SwapBE32(*brandPtr);
76 if (brand == FOURCC('m', 'i', 'f', '1') || brand == FOURCC('h', 'e', 'i', 'c')
77 || brand == FOURCC('m', 's', 'f', '1') || brand == FOURCC('h', 'e', 'v', 'c')
78 || brand == FOURCC('a', 'v', 'i', 'f') || brand == FOURCC('a', 'v', 'i', 's')) {
79 // AVIF files could have "mif1" as the major brand. So we cannot
80 // distinguish whether the image is AVIF or HEIC just based on the
81 // "mif1" brand. So wait until we see a specific avif brand to
82 // determine whether it is AVIF or HEIC.
83 isHeif = true;
84 if (brand == FOURCC('a', 'v', 'i', 'f')
85 || brand == FOURCC('a', 'v', 'i', 's')) {
86 if (format != nullptr) {
88 }
89 return true;
90 }
91 }
92 }
93 if (isHeif) {
94 if (format != nullptr) {
96 }
97 return true;
98 }
99 return false;
100}
#define SkEndian_SwapBE32(n)
Definition: SkEndian.h:136
#define SkEndian_SwapBE64(n)
Definition: SkEndian.h:137
#define FOURCC(c1, c2, c3, c4)
Definition: SkHeifCodec.cpp:18
uint32_t uint32_t * format
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not defaults to or::depending on whether ipv6 is specified vm service A custom Dart VM Service port The default is to pick a randomly available open port disable vm Disable the Dart VM Service The Dart VM Service is never available in release mode disable vm service Disable mDNS Dart VM Service publication Bind to the IPv6 localhost address for the Dart VM Service Ignored if vm service host is set endless trace buffer
Definition: switches.h:126
SeparatedVector2 offset

◆ MakeFromStream()

std::unique_ptr< SkCodec > SkHeifCodec::MakeFromStream ( std::unique_ptr< SkStream stream,
SkCodec::SelectionPolicy  selectionPolicy,
Result result 
)
static

Definition at line 145 of file SkHeifCodec.cpp.

146 {
148 if (!stream) {
150 return nullptr;
151 }
152 std::unique_ptr<HeifDecoder> heifDecoder(createHeifDecoder());
153 if (heifDecoder == nullptr) {
155 return nullptr;
156 }
157
158 constexpr size_t bytesToRead = MinBufferedBytesNeeded();
159 char buffer[bytesToRead];
160 size_t bytesRead = stream->peek(buffer, bytesToRead);
161 if (0 == bytesRead) {
162 // It is possible the stream does not support peeking, but does support rewinding.
163 // Attempt to read() and pass the actual amount read to the decoder.
164 bytesRead = stream->read(buffer, bytesToRead);
165 if (!stream->rewind()) {
166 SkCodecPrintf("Encoded image data could not peek or rewind to determine format!\n");
168 return nullptr;
169 }
170 }
171
173 if (!SkHeifCodec::IsSupported(buffer, bytesRead, &format)) {
174 SkCodecPrintf("Failed to get format despite earlier detecting it");
176 return nullptr;
177 }
178
179 HeifFrameInfo heifInfo;
180 if (!heifDecoder->init(new SkHeifStreamWrapper(stream.release()), &heifInfo)) {
182 return nullptr;
183 }
184
185 size_t frameCount = 1;
186 if (selectionPolicy == SkCodec::SelectionPolicy::kPreferAnimation) {
187 HeifFrameInfo sequenceInfo;
188 if (heifDecoder->getSequenceInfo(&sequenceInfo, &frameCount) &&
189 frameCount > 1) {
190 heifInfo = std::move(sequenceInfo);
191 }
192 }
193
194 std::unique_ptr<SkEncodedInfo::ICCProfile> profile = nullptr;
195 if (heifInfo.mIccData.size() > 0) {
196 auto iccData = new std::vector<uint8_t>(std::move(heifInfo.mIccData));
197 auto icc = SkData::MakeWithProc(iccData->data(), iccData->size(), releaseProc, iccData);
199 }
200 if (profile && profile->profile()->data_color_space != skcms_Signature_RGB) {
201 // This will result in sRGB.
202 profile = nullptr;
203 }
204
205 uint8_t colorDepth = heifDecoder->getColorDepth();
206
209 /*bitsPerComponent*/ 8, std::move(profile), colorDepth);
210 SkEncodedOrigin orientation = get_orientation(heifInfo);
211
213 return std::unique_ptr<SkCodec>(new SkHeifCodec(
214 std::move(info), heifDecoder.release(), orientation, frameCount > 1, format));
215}
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
Definition: DM.cpp:213
SkEncodedImageFormat
SkEncodedOrigin
static SkEncodedOrigin get_orientation(const HeifFrameInfo &frameInfo)
static void releaseProc(const void *ptr, void *context)
static HeifDecoder * createHeifDecoder()
SkStream * stream()
Definition: SkCodec.h:865
static constexpr size_t MinBufferedBytesNeeded()
Definition: SkCodec.h:71
@ kInvalidInput
Definition: SkCodec.h:109
@ kInternalError
Definition: SkCodec.h:118
@ kCouldNotRewind
Definition: SkCodec.h:114
@ kSuccess
Definition: SkCodec.h:80
static sk_sp< SkData > MakeWithProc(const void *ptr, size_t length, ReleaseProc proc, void *ctx)
Definition: SkData.cpp:128
static std::unique_ptr< ICCProfile > Make(sk_sp< SkData >)
static bool IsSupported(const void *, size_t, SkEncodedImageFormat *format)
Definition: SkHeifCodec.cpp:21
virtual bool rewind()
Definition: SkStream.h:100
virtual size_t peek(void *, size_t) const
Definition: SkStream.h:68
virtual size_t read(void *buffer, size_t size)=0
GAsyncResult * result
@ skcms_Signature_RGB
Definition: skcms_public.h:266
std::vector< uint8_t > mIccData
static SkEncodedInfo Make(int width, int height, Color color, Alpha alpha, int bitsPerComponent)

◆ onGetEncodedFormat()

SkEncodedImageFormat SkHeifCodec::onGetEncodedFormat ( ) const
inlineoverrideprotectedvirtual

Implements SkCodec.

Definition at line 49 of file SkHeifCodec.h.

49 {
50 return fFormat;
51 }

◆ onGetFrameCount()

int SkHeifCodec::onGetFrameCount ( )
overrideprotectedvirtual

Reimplemented from SkCodec.

Definition at line 333 of file SkHeifCodec.cpp.

333 {
334 if (!fUseAnimation) {
335 return 1;
336 }
337
338 if (fFrameHolder.size() == 0) {
339 size_t frameCount;
340 HeifFrameInfo frameInfo;
341 if (!fHeifDecoder->getSequenceInfo(&frameInfo, &frameCount)
342 || frameCount <= 1) {
343 fUseAnimation = false;
344 return 1;
345 }
346 fFrameHolder.reserve(frameCount);
347 for (size_t i = 0; i < frameCount; i++) {
348 Frame* frame = fFrameHolder.appendNewFrame();
349 frame->setXYWH(0, 0, frameInfo.mWidth, frameInfo.mHeight);
351 // Currently we don't know the duration until the frame is actually
352 // decoded (onGetFrameInfo is also called before frame is decoded).
353 // For now, fill it base on the value reported for the sequence.
354 frame->setDuration(frameInfo.mDurationUs / 1000);
355 frame->setRequiredFrame(SkCodec::kNoFrame);
356 frame->setHasAlpha(false);
357 }
358 }
359
360 return fFrameHolder.size();
361}
static constexpr int kNoFrame
Definition: SkCodec.h:650
double frame
Definition: examples.cpp:31

◆ onGetFrameInfo()

bool SkHeifCodec::onGetFrameInfo ( int  i,
FrameInfo frameInfo 
) const
overrideprotectedvirtual

Reimplemented from SkCodec.

Definition at line 383 of file SkHeifCodec.cpp.

383 {
384 if (i >= fFrameHolder.size()) {
385 return false;
386 }
387
388 const Frame* frame = fFrameHolder.frame(i);
389 if (!frame) {
390 return false;
391 }
392
393 if (frameInfo) {
394 frame->fillIn(frameInfo, true);
395 }
396
397 return true;
398}

◆ onGetPixels()

SkCodec::Result SkHeifCodec::onGetPixels ( const SkImageInfo info,
void *  pixels,
size_t  rowBytes,
const Options ,
int rowsDecoded 
)
overrideprotectedvirtual
Parameters
rowsDecodedWhen the encoded image stream is incomplete, this function will return kIncompleteInput and rowsDecoded will be set to the number of scanlines that were successfully decoded. This will allow getPixels() to fill the uninitialized memory.

Implements SkCodec.

Definition at line 407 of file SkHeifCodec.cpp.

410 {
411 if (options.fSubset) {
412 // Not supporting subsets on this path for now.
413 // TODO: if the heif has tiles, we can support subset here, but
414 // need to retrieve tile config from metadata retriever first.
415 return kUnimplemented;
416 }
417
418 bool success;
419 if (fUseAnimation) {
420 success = fHeifDecoder->decodeSequence(options.fFrameIndex, &fFrameInfo);
421 fFrameHolder.editFrameAt(options.fFrameIndex)->setDuration(
422 fFrameInfo.mDurationUs / 1000);
423 } else {
424 success = fHeifDecoder->decode(&fFrameInfo);
425 }
426
427 if (!success) {
428 return kInvalidInput;
429 }
430
431 fSwizzler.reset(nullptr);
432 this->allocateStorage(dstInfo);
433
434 int rows = this->readRows(dstInfo, dst, dstRowBytes, dstInfo.height(), options);
435 if (rows < dstInfo.height()) {
436 *rowsDecoded = rows;
437 return kIncompleteInput;
438 }
439
440 return kSuccess;
441}
@ kIncompleteInput
Definition: SkCodec.h:84
@ kUnimplemented
Definition: SkCodec.h:123
const Options & options() const
Definition: SkCodec.h:880
dst
Definition: cp.py:12
const SkIRect * fSubset
Definition: SkCodec.h:347
int height() const
Definition: SkImageInfo.h:371

◆ onGetRepetitionCount()

int SkHeifCodec::onGetRepetitionCount ( )
overrideprotectedvirtual

Reimplemented from SkCodec.

Definition at line 400 of file SkHeifCodec.cpp.

400 {
402}
static constexpr int kRepetitionCountInfinite
Definition: SkCodec.h:759

◆ onRewind()

bool SkHeifCodec::onRewind ( )
overrideprotectedvirtual

Called by rewindIfNeeded, if the stream needed to be rewound.

Subclasses should do any set up needed after a rewind.

Reimplemented from SkCodec.

Definition at line 502 of file SkHeifCodec.cpp.

502 {
503 fSwizzler.reset(nullptr);
504 fSwizzleSrcRow = nullptr;
505 fColorXformSrcRow = nullptr;
506 fStorage.reset();
507
508 return true;
509}
T * reset(size_t count=0)
Definition: SkTemplates.h:296

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