34#if !defined(SK_DISABLE_LEGACY_INIT_DECODERS)
37#if defined(SK_CODEC_DECODES_AVIF)
41#if defined(SK_CODEC_DECODES_BMP)
45#if defined(SK_CODEC_DECODES_GIF) || defined(SK_HAS_WUFFS_LIBRARY)
49#if defined(SK_HAS_HEIF_LIBRARY)
53#if defined(SK_CODEC_DECODES_ICO)
57#if defined(SK_CODEC_DECODES_JPEG)
61#if defined(SK_CODEC_DECODES_JPEGXL)
65#if defined(SK_CODEC_DECODES_PNG)
69#if defined(SK_CODEC_DECODES_RAW)
73#if defined(SK_CODEC_DECODES_WBMP)
77#if defined(SK_CODEC_DECODES_WEBP)
87#if !defined(SK_DISABLE_LEGACY_INIT_DECODERS)
90 if (decoders->empty()) {
91#if defined(SK_CODEC_DECODES_PNG)
92 decoders->push_back(SkPngDecoder::Decoder());
94#if defined(SK_CODEC_DECODES_JPEG)
95 decoders->push_back(SkJpegDecoder::Decoder());
97#if defined(SK_CODEC_DECODES_WEBP)
98 decoders->push_back(SkWebpDecoder::Decoder());
100#if defined(SK_CODEC_DECODES_GIF) || defined(SK_HAS_WUFFS_LIBRARY)
101 decoders->push_back(SkGifDecoder::Decoder());
103#if defined(SK_CODEC_DECODES_ICO)
104 decoders->push_back(SkIcoDecoder::Decoder());
106#if defined(SK_CODEC_DECODES_BMP)
107 decoders->push_back(SkBmpDecoder::Decoder());
109#if defined(SK_CODEC_DECODES_WBMP)
110 decoders->push_back(SkWbmpDecoder::Decoder());
112#if defined(SK_CODEC_DECODES_AVIF)
113 decoders->push_back(SkAvifDecoder::Decoder());
115#if defined(SK_CODEC_DECODES_JPEGXL)
116 decoders->push_back(SkJpegxlDecoder::Decoder());
118#if defined(SK_HAS_HEIF_LIBRARY)
119 decoders->push_back(SkHeifDecoder::Decoder());
121#if defined(SK_CODEC_DECODES_RAW)
122 decoders->push_back(SkRawDecoder::Decoder());
127 return decoders.
get();
135void Register(Decoder
d) {
137 for (
size_t i = 0; i < decoders->size(); i++) {
138 if ((*decoders)[i].
id ==
d.id) {
143 decoders->push_back(
d);
147 for (
const SkCodecs::Decoder& decoder :
get_decoders()) {
148 if (decoder.id ==
id) {
158 std::unique_ptr<SkStream> stream,
Result* outResult,
161 chunkReader, selectionPolicy);
168 outResult = &resultStorage;
194 if (0 == bytesRead) {
204 SkCodecPrintf(
"Encoded image data could not peek or rewind to determine format!\n");
210 SkCodecs::MakeFromStreamCallback rawFallback =
nullptr;
211 for (
const SkCodecs::Decoder& proc : decoders) {
212 if (proc.isFormat(
buffer, bytesRead)) {
214 if (proc.id ==
"png") {
215 return proc.makeFromStream(std::move(
stream), outResult, chunkReader);
216 }
else if (proc.id ==
"heif" || proc.id ==
"gif") {
217 return proc.makeFromStream(std::move(
stream), outResult, &selectionPolicy);
218 }
else if (proc.id ==
"raw") {
219 rawFallback = proc.makeFromStream;
222 return proc.makeFromStream(std::move(
stream), outResult,
nullptr);
225 if (rawFallback !=
nullptr) {
227 return rawFallback(std::move(
stream), outResult,
nullptr);
230 if (bytesRead < bytesToRead) {
252 std::unique_ptr<SkStream> stream,
254 : fEncodedInfo(
std::move(
info))
255 , fSrcXformFormat(srcFormat)
256 , fStream(
std::move(stream))
264 fSrcXformFormat = pixelFormat;
269 if (!yuvaPixmapInfo) {
291 switch (dst.colorType()) {
314 const bool needsRewind = fNeedsRewind;
323 fStartedIncrementalDecode =
false;
327 if (fStream && !fStream->rewind()) {
346 if (dimensions != srcDimensions) {
351 if (!map.mapRect(&asRect)) {
364 const size_t offset = prevRect.
x() * bpp + prevRect.
y() * rowBytes;
365 void* eraseDst = SkTAddOffset<void>(pixels,
offset);
371 const Options&
options, GetPixelsCallback getPixelsFn) {
375 fUsingCallbackForHandleFrameIndex =
true;
376 }
else if (fUsingCallbackForHandleFrameIndex) {
386 return this->initializeColorXform(
info, fEncodedInfo.
alpha(), fEncodedInfo.
opaque())
407 const auto*
frame = frameHolder->getFrame(index);
410 const int requiredFrame =
frame->getRequiredFrame();
413 const SkFrame* preppedFrame =
nullptr;
422 Options prevFrameOptions(
options);
423 prevFrameOptions.fFrameIndex = requiredFrame;
429 preppedFrame = frameHolder->getFrame(requiredFrame);
451 if (preppedFrame->
frameId() == requiredFrame) {
463 return this->initializeColorXform(
info,
frame->reportedAlpha(), !
frame->hasAlpha())
472 if (
nullptr == pixels) {
475 if (rowBytes <
info.minRowBytes()) {
494 const Result frameIndexResult = this->handleFrameIndex(
info, pixels, rowBytes,
497 return frameIndexResult;
502 if (!this->dimensionsSupported(
info.dimensions())) {
572 return this->
getImage(info,
nullptr);
577 fStartedIncrementalDecode =
false;
582 if (
nullptr == pixels) {
599 if (top < 0 || top >=
info.height() || top >= bottom || bottom >
info.height()) {
605 const Result frameIndexResult = this->handleFrameIndex(
info, pixels, rowBytes,
608 return frameIndexResult;
611 if (!this->dimensionsSupported(
info.dimensions())) {
620 fStartedIncrementalDecode =
true;
629 fNeedsRewind =
false;
664 const Result frameIndexResult = this->handleFrameIndex(
info,
nullptr, 0, *
options);
666 return frameIndexResult;
670 if (!this->dimensionsSupported(
info.dimensions())) {
685 SkASSERT(fUsingCallbackForHandleFrameIndex || fNeedsRewind);
695 if (fCurrScanline < 0) {
700 if (countLines <= 0 || fCurrScanline + countLines > fDstInfo.
height()) {
704 const int linesDecoded = this->
onGetScanlines(dst, countLines, rowBytes);
705 if (linesDecoded < countLines) {
706 this->fillIncompleteImage(this->
dstInfo(), dst, rowBytes, this->
options().fZeroInitialized,
707 countLines, linesDecoded);
709 fCurrScanline += countLines;
714 if (fCurrScanline < 0) {
719 if (countLines < 0 || fCurrScanline + countLines > fDstInfo.
height()) {
727 fCurrScanline += countLines;
732 SkASSERT(0 <= inputScanline && inputScanline < fEncodedInfo.
height());
739 return inputScanline;
741 return fEncodedInfo.
height() - inputScanline - 1;
749void SkCodec::fillIncompleteImage(
const SkImageInfo&
info,
void* dst,
size_t rowBytes,
750 ZeroInitialized zeroInit,
int linesRequested,
int linesDecoded) {
755 const int linesRemaining = linesRequested - linesDecoded;
758 const int fillWidth = sampler ? sampler->
fillWidth() :
762 SkTAddOffset<void>(dst, linesDecoded * rowBytes);
763 const auto fillInfo =
info.makeWH(fillWidth, linesRemaining);
780#if defined(SK_PMCOLOR_IS_RGBA)
806 fXformTime = kNo_XformTime;
807 bool needsColorXform =
false;
811 needsColorXform =
true;
816 const auto* srcProfile = fEncodedInfo.
profile();
821 const auto* srcProfile = fEncodedInfo.
profile();
826 needsColorXform =
true;
835 if (needsColorXform) {
838 ? kDecodeRow_XformTime : kPalette_XformTime;
855 const auto* srcProfile = fEncodedInfo.
profile();
857 dst, fDstXformFormat, fDstXformAlphaFormat, &fDstProfile,
864 if (frameCount <= 0) {
865 return std::vector<FrameInfo>{};
870 return std::vector<FrameInfo>{};
873 std::vector<FrameInfo>
result(frameCount);
874 for (
int i = 0; i < frameCount; ++i) {
885 return "incomplete input";
887 return "error in input";
889 return "invalid conversion";
891 return "invalid scale";
893 return "invalid parameters";
895 return "invalid input";
897 return "could not rewind";
899 return "internal error";
901 return "unimplemented";
904 return "bogus result value";
918 frameInfo->
fBlend = fBlend;
977 const int i =
frame->frameId();
979 frame->setHasAlpha(reportsAlpha || frameRect != screenRect);
986 if ((!reportsAlpha || !blendWithPrevFrame) && frameRect == screenRect) {
987 frame->setHasAlpha(reportsAlpha);
994 const int prevId = prevFrame->
frameId();
996 frame->setHasAlpha(
true);
1001 prevFrame = this->
getFrame(prevId - 1);
1004 const bool clearPrevFrame =
restore_bg(*prevFrame);
1007 if (clearPrevFrame) {
1008 if (prevFrameRect == screenRect ||
independent(*prevFrame)) {
1009 frame->setHasAlpha(
true);
1015 if (reportsAlpha && blendWithPrevFrame) {
1021 frame->setHasAlpha(prevFrame->
hasAlpha() || clearPrevFrame);
1025 while (frameRect.contains(prevFrameRect)) {
1029 frame->setHasAlpha(
true);
1033 prevFrame = this->
getFrame(prevRequiredFrame);
1039 frame->setHasAlpha(
true);
1043 frame->setHasAlpha(prevFrame->
hasAlpha() || (reportsAlpha && !blendWithPrevFrame));
1051 return fStream->duplicate();
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
@ kOpaque_SkAlphaType
pixel is opaque
@ kPremul_SkAlphaType
pixel components are premultiplied by alpha
#define SkAssertResult(cond)
static bool valid_alpha(SkAlphaType dstAlpha, bool srcIsOpaque)
#define SkCodecPrintf(...)
bool zero_rect(const SkImageInfo &dstInfo, void *pixels, size_t rowBytes, SkISize srcDimensions, SkIRect prevRect)
static bool restore_bg(const SkFrame &frame)
static SkIRect frame_rect_on_screen(SkIRect frameRect, const SkIRect &screenRect)
bool sk_select_xform_format(SkColorType colorType, bool forColorTable, skcms_PixelFormat *outFormat)
static bool independent(const SkFrame &frame)
@ 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;
@ kAlpha_8_SkColorType
pixel with alpha in 8-bit byte
@ kGray_8_SkColorType
pixel with grayscale level in 8-bit byte
@ kRGB_565_SkColorType
pixel with 5 bits red, 6 bits green, 5 bits blue, in 16-bit word
@ kBGRA_10101010_XR_SkColorType
pixel with 10 bits each for blue, green, red, alpha; in 64-bit word, extended range
@ kRGBA_8888_SkColorType
pixel with 8 bits for red, green, blue, alpha; in 32-bit word
@ kBGR_101010x_XR_SkColorType
pixel with 10 bits each for blue, green, red; in 32-bit word, extended range
@ kUnknown_SkColorType
uninitialized
static bool SkEncodedOriginSwapsWidthHeight(SkEncodedOrigin origin)
static SkColorType colorType(AImageDecoder *decoder, const AImageDecoderHeaderInfo *headerInfo)
const SkPixmap & pixmap() const
bool tryAllocPixels(const SkImageInfo &info, size_t rowBytes)
virtual Result onGetPixels(const SkImageInfo &info, void *pixels, size_t rowBytes, const Options &, int *rowsDecoded)=0
int getScanlines(void *dst, int countLines, size_t rowBytes)
virtual int onOutputScanline(int inputScanline) const
static std::unique_ptr< SkCodec > MakeFromStream(std::unique_ptr< SkStream >, SkSpan< const SkCodecs::Decoder > decoders, Result *=nullptr, SkPngChunkReader *=nullptr, SelectionPolicy selectionPolicy=SelectionPolicy::kPreferStillImage)
virtual Result onStartScanlineDecode(const SkImageInfo &, const Options &)
virtual std::unique_ptr< SkStream > getEncodedData() const
virtual bool conversionSupported(const SkImageInfo &dst, bool srcIsOpaque, bool needsColorXform)
SkISize dimensions() const
Result getYUVAPlanes(const SkYUVAPixmaps &yuvaPixmaps)
const SkImageInfo & dstInfo() const
virtual bool onGetFrameInfo(int, FrameInfo *) const
static std::unique_ptr< SkCodec > MakeFromData(sk_sp< SkData >, SkSpan< const SkCodecs::Decoder > decoders, SkPngChunkReader *=nullptr)
bool queryYUVAInfo(const SkYUVAPixmapInfo::SupportedDataTypes &supportedDataTypes, SkYUVAPixmapInfo *yuvaPixmapInfo) const
void applyColorXform(void *dst, const void *src, int count) const
Result startScanlineDecode(const SkImageInfo &dstInfo, const Options *options)
static constexpr size_t MinBufferedBytesNeeded()
std::vector< FrameInfo > getFrameInfo()
virtual Result onGetYUVAPlanes(const SkYUVAPixmaps &)
virtual Result onStartIncrementalDecode(const SkImageInfo &, void *, size_t, const Options &)
SkCodec(SkEncodedInfo &&, XformFormat srcFormat, std::unique_ptr< SkStream >, SkEncodedOrigin=kTopLeft_SkEncodedOrigin)
@ kBottomUp_SkScanlineOrder
@ kTopDown_SkScanlineOrder
virtual bool onSkipScanlines(int)
Result getPixels(const SkImageInfo &info, void *pixels, size_t rowBytes, const Options *)
virtual int onGetFrameCount()
std::tuple< sk_sp< SkImage >, SkCodec::Result > getImage()
void setSrcXformFormat(XformFormat pixelFormat)
SkScanlineOrder getScanlineOrder() const
virtual SkSampler * getSampler(bool)
Result startIncrementalDecode(const SkImageInfo &dstInfo, void *dst, size_t rowBytes, const Options *)
static const char * ResultToString(Result)
virtual const SkFrameHolder * getFrameHolder() const
virtual bool usesColorXform() const
virtual bool onQueryYUVAInfo(const SkYUVAPixmapInfo::SupportedDataTypes &, SkYUVAPixmapInfo *) const
int outputScanline(int inputScanline) const
virtual int onGetScanlines(void *, int, size_t)
SkEncodedOrigin getOrigin() const
virtual bool onGetValidSubset(SkIRect *) const
static constexpr int kNoFrame
bool skipScanlines(int countLines)
SkImageInfo getInfo() const
const Options & options() const
void toProfile(skcms_ICCProfile *) const
const SkFrame * getFrame(int i) const
void setAlphaAndRequiredFrame(SkFrame *)
SkCodecAnimation::DisposalMethod getDisposalMethod() const
void fillIn(SkCodec::FrameInfo *, bool fullyReceived) const
SkIRect frameRect() const
SkEncodedInfo::Alpha reportedAlpha() const
int getRequiredFrame() const
static SkMatrix RectToRect(const SkRect &src, const SkRect &dst, ScaleToFit mode=kFill_ScaleToFit)
static std::unique_ptr< SkMemoryStream > Make(sk_sp< SkData > data)
virtual int fillWidth() const =0
static void Fill(const SkImageInfo &info, void *dst, size_t rowBytes, SkCodec::ZeroInitialized zeroInit)
virtual size_t peek(void *, size_t) const
virtual size_t read(void *buffer, size_t size)=0
bool isSupported(const SupportedDataTypes &) const
VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE auto & d
static const uint8_t buffer[]
bool HasDecoder(std::string_view id)
const std::vector< Decoder > & get_decoders()
static std::vector< Decoder > * get_decoders_for_editing()
SK_API sk_sp< SkImage > RasterFromBitmap(const SkBitmap &bitmap)
SK_API bool Orient(const SkPixmap &dst, const SkPixmap &src, SkEncodedOrigin origin)
SK_API SkImageInfo SwapWidthHeight(const SkImageInfo &info)
static DecodeResult decode(std::string path)
bool skcms_Transform(const void *src, skcms_PixelFormat srcFmt, skcms_AlphaFormat srcAlpha, const skcms_ICCProfile *srcProfile, void *dst, skcms_PixelFormat dstFmt, skcms_AlphaFormat dstAlpha, const skcms_ICCProfile *dstProfile, size_t nz)
const skcms_ICCProfile * skcms_sRGB_profile()
bool skcms_ApproximatelyEqualProfiles(const skcms_ICCProfile *A, const skcms_ICCProfile *B)
@ skcms_PixelFormat_BGR_101010x_XR
@ skcms_PixelFormat_BGRA_8888
@ skcms_PixelFormat_RGBA_hhhh
@ skcms_PixelFormat_RGBA_8888
@ skcms_PixelFormat_BGR_565
@ skcms_AlphaFormat_Unpremul
@ skcms_AlphaFormat_PremulAsEncoded
SkCodecAnimation::DisposalMethod fDisposalMethod
SkCodecAnimation::Blend fBlend
bool fHasAlphaWithinBounds
ZeroInitialized fZeroInitialized
const skcms_ICCProfile * profile() const
constexpr int32_t x() const
constexpr int32_t y() const
bool intersect(const SkIRect &r)
constexpr int32_t top() const
constexpr SkISize size() const
constexpr int32_t bottom() const
constexpr int32_t height() const
static constexpr SkIRect MakeSize(const SkISize &size)
static constexpr SkIRect MakeEmpty()
constexpr int32_t width() const
static constexpr SkIRect MakeWH(int32_t w, int32_t h)
SkImageInfo makeDimensions(SkISize newSize) const
SkColorSpace * colorSpace() const
int bytesPerPixel() const
SkISize dimensions() const
SkAlphaType alphaType() const
SkColorType colorType() const
static SkRect Make(const SkISize &size)
void roundOut(SkIRect *dst) const