18#define FOURCC(c1, c2, c3, c4) \
19 ((c1) << 24 | (c2) << 16 | (c3) << 8 | (c4))
29 const uint32_t* ptr = (
const uint32_t*)
buffer;
33 if (chunkType !=
FOURCC(
'f',
't',
'y',
'p')) {
44 auto* chunkSizePtr = SkTAddOffset<const uint64_t>(
buffer,
offset);
51 }
else if (chunkSize < 8) {
56 if (chunkSize > bytesRead) {
57 chunkSize = bytesRead;
59 int64_t chunkDataSize = chunkSize -
offset;
62 if (chunkDataSize < 8) {
66 uint32_t numCompatibleBrands = (chunkDataSize - 8) / 4;
68 for (
size_t i = 0;
i < numCompatibleBrands + 2; ++
i) {
74 auto* brandPtr = SkTAddOffset<const uint32_t>(
buffer,
offset + 4 *
i);
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')) {
84 if (brand ==
FOURCC(
'a',
'v',
'i',
'f')
85 || brand ==
FOURCC(
'a',
'v',
'i',
's')) {
122 return fStream->rewind();
125 bool seek(
size_t position)
override {
126 return fStream->seek(position);
130 return fStream->hasLength();
134 return fStream->getLength();
138 std::unique_ptr<SkStream> fStream;
142 delete reinterpret_cast<std::vector<uint8_t>*
>(context);
153 if (heifDecoder ==
nullptr) {
161 if (0 == bytesRead) {
166 SkCodecPrintf(
"Encoded image data could not peek or rewind to determine format!\n");
174 SkCodecPrintf(
"Failed to get format despite earlier detecting it");
185 size_t frameCount = 1;
188 if (heifDecoder->getSequenceInfo(&sequenceInfo, &frameCount) &&
190 heifInfo = std::move(sequenceInfo);
194 std::unique_ptr<SkEncodedInfo::ICCProfile>
profile =
nullptr;
196 auto iccData =
new std::vector<uint8_t>(std::move(heifInfo.
mIccData));
205 uint8_t colorDepth = heifDecoder->getColorDepth();
209 8, std::move(
profile), colorDepth);
214 std::move(
info), heifDecoder.release(), orientation, frameCount > 1,
format));
217SkHeifCodec::SkHeifCodec(
224 , fHeifDecoder(heifDecoder)
225 , fSwizzleSrcRow(nullptr)
226 , fColorXformSrcRow(nullptr)
227 , fUseAnimation(useAnimation)
232 bool needsColorXform) {
240 SkCodecPrintf(
"Warning: an opaque image should be decoded as opaque "
241 "- it is being decoded as non-opaque, which will draw slower\n");
244 uint8_t colorDepth = fHeifDecoder->getColorDepth();
256 if (needsColorXform) {
268 if (srcIsOpaque && colorDepth == 10) {
281int SkHeifCodec::readRows(
const SkImageInfo& dstInfo,
void*
dst,
size_t rowBytes,
int count,
282 const Options& opts) {
290 uint8_t* decodeDst = (uint8_t*)
dst;
291 uint32_t* swizzleDst = (uint32_t*)
dst;
292 size_t decodeDstRowBytes = rowBytes;
293 size_t swizzleDstRowBytes = rowBytes;
294 int dstWidth = opts.fSubset ? opts.fSubset->width() :
dstInfo.
width();
295 if (fSwizzleSrcRow && fColorXformSrcRow) {
296 decodeDst = fSwizzleSrcRow;
297 swizzleDst = fColorXformSrcRow;
298 decodeDstRowBytes = 0;
299 swizzleDstRowBytes = 0;
300 dstWidth = fSwizzler->swizzleWidth();
301 }
else if (fColorXformSrcRow) {
302 decodeDst = (uint8_t*) fColorXformSrcRow;
303 swizzleDst = fColorXformSrcRow;
304 decodeDstRowBytes = 0;
305 swizzleDstRowBytes = 0;
306 }
else if (fSwizzleSrcRow) {
307 decodeDst = fSwizzleSrcRow;
308 decodeDstRowBytes = 0;
309 dstWidth = fSwizzler->swizzleWidth();
313 if (!fHeifDecoder->getScanline(decodeDst)) {
318 fSwizzler->swizzle(swizzleDst, decodeDst);
323 dst = SkTAddOffset<void>(
dst, rowBytes);
326 decodeDst = SkTAddOffset<uint8_t>(decodeDst, decodeDstRowBytes);
327 swizzleDst = SkTAddOffset<uint32_t>(swizzleDst, swizzleDstRowBytes);
334 if (!fUseAnimation) {
338 if (fFrameHolder.size() == 0) {
341 if (!fHeifDecoder->getSequenceInfo(&frameInfo, &frameCount)
342 || frameCount <= 1) {
343 fUseAnimation =
false;
346 fFrameHolder.reserve(frameCount);
347 for (
size_t i = 0;
i < frameCount;
i++) {
348 Frame*
frame = fFrameHolder.appendNewFrame();
356 frame->setHasAlpha(
false);
360 return fFrameHolder.size();
363const SkFrame* SkHeifCodec::FrameHolder::onGetFrame(
int i)
const {
367SkHeifCodec::Frame* SkHeifCodec::FrameHolder::appendNewFrame() {
368 const int i = this->
size();
369 fFrames.emplace_back(
i);
378SkHeifCodec::Frame* SkHeifCodec::FrameHolder::editFrameAt(
int i) {
384 if (
i >= fFrameHolder.size()) {
388 const Frame*
frame = fFrameHolder.frame(
i);
394 frame->fillIn(frameInfo,
true);
408 void*
dst,
size_t dstRowBytes,
424 success = fHeifDecoder->decode(&fFrameInfo);
431 fSwizzler.reset(
nullptr);
432 this->allocateStorage(
dstInfo);
443void SkHeifCodec::allocateStorage(
const SkImageInfo& dstInfo) {
446 size_t swizzleBytes = 0;
449 dstWidth = fSwizzler->swizzleWidth();
453 size_t xformBytes = 0;
456 xformBytes = dstWidth *
sizeof(uint32_t);
459 size_t totalBytes = swizzleBytes + xformBytes;
460 fStorage.
reset(totalBytes);
461 if (totalBytes > 0) {
462 fSwizzleSrcRow = (swizzleBytes > 0) ? fStorage.
get() :
nullptr;
463 fColorXformSrcRow = (xformBytes > 0) ?
464 SkTAddOffset<uint32_t>(fStorage.
get(), swizzleBytes) :
nullptr;
468void SkHeifCodec::initializeSwizzler(
491SkSampler* SkHeifCodec::getSampler(
bool createIfNecessary) {
492 if (!createIfNecessary || fSwizzler) {
493 SkASSERT(!fSwizzler || (fSwizzleSrcRow && fStorage.
get() == fSwizzleSrcRow));
494 return fSwizzler.get();
498 this->allocateStorage(this->
dstInfo());
499 return fSwizzler.get();
503 fSwizzler.reset(
nullptr);
504 fSwizzleSrcRow =
nullptr;
505 fColorXformSrcRow =
nullptr;
516 if (!fHeifDecoder->decode(&fFrameInfo)) {
523 fSwizzler.reset(
nullptr);
526 this->allocateStorage(
dstInfo);
531int SkHeifCodec::onGetScanlines(
void*
dst,
int count,
size_t dstRowBytes) {
535bool SkHeifCodec::onSkipScanlines(
int count) {
550 outResult = &resultStorage;
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
static constexpr bool SkIsAlign4(T x)
@ kUnknown_SkAlphaType
uninitialized
@ kOpaque_SkAlphaType
pixel is opaque
#define SkCodecPrintf(...)
@ kBGRA_8888_SkColorType
pixel with 8 bits for blue, green, red, alpha; in 32-bit word
@ kRGBA_F16_SkColorType
pixel with half floats for red, green, blue, alpha;
@ kRGB_565_SkColorType
pixel with 5 bits red, 6 bits green, 5 bits blue, in 16-bit word
@ kRGBA_8888_SkColorType
pixel with 8 bits for red, green, blue, alpha; in 32-bit word
@ kRGBA_1010102_SkColorType
10 bits for red, green, blue; 2 bits for alpha; in 32-bit word
@ kBottomRight_SkEncodedOrigin
@ kTopLeft_SkEncodedOrigin
@ kLeftBottom_SkEncodedOrigin
@ kDefault_SkEncodedOrigin
@ kRightTop_SkEncodedOrigin
#define SkEndian_SwapBE32(n)
#define SkEndian_SwapBE64(n)
#define FOURCC(c1, c2, c3, c4)
static SkEncodedOrigin get_orientation(const HeifFrameInfo &frameInfo)
static void releaseProc(const void *ptr, void *context)
#define INHERITED(method,...)
static HeifDecoder * createHeifDecoder()
@ kHeifColorFormat_RGBA_1010102
@ kHeifColorFormat_RGB565
@ kHeifColorFormat_BGRA_8888
@ kHeifColorFormat_RGBA_8888
const SkImageInfo & dstInfo() const
void applyColorXform(void *dst, const void *src, int count) const
static constexpr size_t MinBufferedBytesNeeded()
void setSrcXformFormat(XformFormat pixelFormat)
static constexpr int kRepetitionCountInfinite
static constexpr int kNoFrame
XformFormat getSrcXformFormat() const
const Options & options() const
static sk_sp< SkData > MakeWithProc(const void *ptr, size_t length, ReleaseProc proc, void *ctx)
static std::unique_ptr< ICCProfile > Make(sk_sp< SkData >)
int onGetFrameCount() override
static bool IsSupported(const void *, size_t, SkEncodedImageFormat *format)
int onGetRepetitionCount() override
bool conversionSupported(const SkImageInfo &, bool, bool) override
static std::unique_ptr< SkCodec > MakeFromStream(std::unique_ptr< SkStream >, SkCodec::SelectionPolicy selectionPolicy, Result *)
bool onGetFrameInfo(int, FrameInfo *) const override
Result onGetPixels(const SkImageInfo &dstInfo, void *dst, size_t dstRowBytes, const Options &options, int *rowsDecoded) override
static std::unique_ptr< SkMemoryStream > Make(sk_sp< SkData > data)
virtual size_t peek(void *, size_t) const
virtual size_t read(void *buffer, size_t size)=0
static std::unique_ptr< SkSwizzler > MakeSimple(int srcBPP, const SkImageInfo &dstInfo, const SkCodec::Options &)
T * reset(size_t count=0)
uint32_t uint32_t * format
SK_API bool IsHeif(const void *, size_t)
SK_API std::unique_ptr< SkCodec > Decode(std::unique_ptr< SkStream >, SkCodec::Result *, SkCodecs::DecodeContext=nullptr)
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network policy
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
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
@ skcms_PixelFormat_RGBA_1010102
@ skcms_PixelFormat_RGBA_8888
std::vector< uint8_t > mIccData
static SkEncodedInfo Make(int width, int height, Color color, Alpha alpha, int bitsPerComponent)
size_t getLength() const override
~SkHeifStreamWrapper() override
size_t read(void *buffer, size_t size) override
bool seek(size_t position) override
bool hasLength() const override
SkHeifStreamWrapper(SkStream *stream)
SkAlphaType alphaType() const
SkColorType colorType() const
SkImageInfo makeColorType(SkColorType newColorType) const
std::shared_ptr< const fml::Mapping > data