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

#include <SkIcoCodec.h>

Inheritance diagram for SkIcoCodec:
SkCodec SkNoncopyable

Static Public Member Functions

static bool IsIco (const void *, size_t)
 
static std::unique_ptr< SkCodecMakeFromStream (std::unique_ptr< SkStream >, 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

SkISize onGetScaledDimensions (float desiredScale) const override
 
bool onDimensionsSupported (const SkISize &) override
 
Result onGetPixels (const SkImageInfo &dstInfo, void *dst, size_t dstRowBytes, const Options &, int *) override
 
SkEncodedImageFormat onGetEncodedFormat () const override
 
SkScanlineOrder onGetScanlineOrder () const override
 
bool conversionSupported (const SkImageInfo &, bool, bool) override
 
bool usesColorXform () const 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 27 of file SkIcoCodec.h.

Member Function Documentation

◆ conversionSupported()

bool SkIcoCodec::conversionSupported ( const SkImageInfo dst,
bool  srcIsOpaque,
bool  needsColorXform 
)
inlineoverrideprotectedvirtual

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 59 of file SkIcoCodec.h.

59 {
60 // This will be checked by the embedded codec.
61 return true;
62 }

◆ IsIco()

bool SkIcoCodec::IsIco ( const void *  buffer,
size_t  bytesRead 
)
static

Definition at line 37 of file SkIcoCodec.cpp.

37 {
38 const char icoSig[] = { '\x00', '\x00', '\x01', '\x00' };
39 const char curSig[] = { '\x00', '\x00', '\x02', '\x00' };
40 return bytesRead >= sizeof(icoSig) &&
41 (!memcmp(buffer, icoSig, sizeof(icoSig)) ||
42 !memcmp(buffer, curSig, sizeof(curSig)));
43}
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

◆ MakeFromStream()

std::unique_ptr< SkCodec > SkIcoCodec::MakeFromStream ( std::unique_ptr< SkStream stream,
Result result 
)
static

Definition at line 45 of file SkIcoCodec.cpp.

46 {
48 if (!stream) {
50 return nullptr;
51 }
52 // It is helpful to have the entire stream in a contiguous buffer. In some cases,
53 // this is already the case anyway, so this method is faster. In others, this is
54 // safer than the old method, which required allocating a block of memory whose
55 // byte size is stored in the stream as a uint32_t, and may result in a large or
56 // failed allocation.
57 sk_sp<SkData> data = nullptr;
58 if (stream->getMemoryBase()) {
59 // It is safe to make without copy because we'll hold onto the stream.
61 } else {
63
64 // If we are forced to copy the stream to a data, we can go ahead and delete the stream.
65 stream.reset(nullptr);
66 }
67
68 // Header size constants
69 constexpr uint32_t kIcoDirectoryBytes = 6;
70 constexpr uint32_t kIcoDirEntryBytes = 16;
71
72 // Read the directory header
73 if (data->size() < kIcoDirectoryBytes) {
74 SkCodecPrintf("Error: unable to read ico directory header.\n");
76 return nullptr;
77 }
78
79 // Process the directory header
80 const uint16_t numImages = get_short(data->bytes(), 4);
81 if (0 == numImages) {
82 SkCodecPrintf("Error: No images embedded in ico.\n");
84 return nullptr;
85 }
86
87 // This structure is used to represent the vital information about entries
88 // in the directory header. We will obtain this information for each
89 // directory entry.
90 struct Entry {
91 uint32_t offset;
92 uint32_t size;
93 };
94 UniqueVoidPtr dirEntryBuffer(sk_malloc_canfail(sizeof(Entry) * numImages));
95 if (!dirEntryBuffer) {
96 SkCodecPrintf("Error: OOM allocating ICO directory for %i images.\n",
97 numImages);
99 return nullptr;
100 }
101 auto* directoryEntries = reinterpret_cast<Entry*>(dirEntryBuffer.get());
102
103 // Iterate over directory entries
104 for (uint32_t i = 0; i < numImages; i++) {
105 const uint8_t* entryBuffer = data->bytes() + kIcoDirectoryBytes + i * kIcoDirEntryBytes;
106 if (data->size() < kIcoDirectoryBytes + (i+1) * kIcoDirEntryBytes) {
107 SkCodecPrintf("Error: Dir entries truncated in ico.\n");
109 return nullptr;
110 }
111
112 // The directory entry contains information such as width, height,
113 // bits per pixel, and number of colors in the color palette. We will
114 // ignore these fields since they are repeated in the header of the
115 // embedded image. In the event of an inconsistency, we would always
116 // defer to the value in the embedded header anyway.
117
118 // Specifies the size of the embedded image, including the header
119 uint32_t size = get_int(entryBuffer, 8);
120
121 // Specifies the offset of the embedded image from the start of file.
122 // It does not indicate the start of the pixel data, but rather the
123 // start of the embedded image header.
124 uint32_t offset = get_int(entryBuffer, 12);
125
126 // Save the vital fields
127 directoryEntries[i].offset = offset;
128 directoryEntries[i].size = size;
129 }
130
131 // Default Result, if no valid embedded codecs are found.
133
134 // It is "customary" that the embedded images will be stored in order of
135 // increasing offset. However, the specification does not indicate that
136 // they must be stored in this order, so we will not trust that this is the
137 // case. Here we sort the embedded images by increasing offset.
138 struct EntryLessThan {
139 bool operator() (Entry a, Entry b) const {
140 return a.offset < b.offset;
141 }
142 };
143 EntryLessThan lessThan;
144 SkTQSort(directoryEntries, directoryEntries + numImages, lessThan);
145
146 // Now will construct a candidate codec for each of the embedded images
147 uint32_t bytesRead = kIcoDirectoryBytes + numImages * kIcoDirEntryBytes;
148 auto codecs = std::make_unique<TArray<std::unique_ptr<SkCodec>>>(numImages);
149 for (uint32_t i = 0; i < numImages; i++) {
150 uint32_t offset = directoryEntries[i].offset;
151 uint32_t size = directoryEntries[i].size;
152
153 // Ensure that the offset is valid
154 if (offset < bytesRead) {
155 SkCodecPrintf("Warning: invalid ico offset.\n");
156 continue;
157 }
158
159 // If we cannot skip, assume we have reached the end of the stream and
160 // stop trying to make codecs
161 if (offset >= data->size()) {
162 SkCodecPrintf("Warning: could not skip to ico offset.\n");
163 break;
164 }
165 bytesRead = offset;
166
167 if (offset + size > data->size()) {
168 SkCodecPrintf("Warning: could not create embedded stream.\n");
170 break;
171 }
172
173 sk_sp<SkData> embeddedData(SkData::MakeSubset(data.get(), offset, size));
174 auto embeddedStream = SkMemoryStream::Make(embeddedData);
175 bytesRead += size;
176
177 // Check if the embedded codec is bmp or png and create the codec
178 std::unique_ptr<SkCodec> codec;
179 Result ignoredResult;
180 if (SkPngCodec::IsPng(embeddedData->bytes(), embeddedData->size())) {
181 codec = SkPngCodec::MakeFromStream(std::move(embeddedStream), &ignoredResult);
182 } else {
183 codec = SkBmpCodec::MakeFromIco(std::move(embeddedStream), &ignoredResult);
184 }
185
186 if (nullptr != codec) {
187 codecs->push_back(std::move(codec));
188 }
189 }
190
191 if (codecs->empty()) {
192 SkCodecPrintf("Error: could not find any valid embedded ico codecs.\n");
193 return nullptr;
194 }
195
196 // Use the largest codec as a "suggestion" for image info
197 size_t maxSize = 0;
198 int maxIndex = 0;
199 for (int i = 0; i < codecs->size(); i++) {
200 SkImageInfo info = codecs->at(i)->getInfo();
201 size_t size = info.computeMinByteSize();
202
203 if (size > maxSize) {
204 maxSize = size;
205 maxIndex = i;
206 }
207 }
208
209 auto maxInfo = codecs->at(maxIndex)->getEncodedInfo().copy();
210
211 *result = kSuccess;
212 return std::unique_ptr<SkCodec>(
213 new SkIcoCodec(std::move(maxInfo), std::move(stream), std::move(codecs)));
214}
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
Definition: DM.cpp:213
#define SkASSERT(cond)
Definition: SkAssert.h:116
static uint32_t get_int(const uint8_t *buffer, uint32_t i)
Definition: SkCodecPriv.h:168
#define SkCodecPrintf(...)
Definition: SkCodecPriv.h:23
static uint16_t get_short(const uint8_t *buffer, uint32_t i)
Definition: SkCodecPriv.h:154
static void * sk_malloc_canfail(size_t size)
Definition: SkMalloc.h:93
sk_sp< SkData > SkCopyStreamToData(SkStream *stream)
Definition: SkStream.cpp:937
void SkTQSort(T *begin, T *end, const C &lessThan)
Definition: SkTSort.h:194
static std::unique_ptr< SkCodec > MakeFromIco(std::unique_ptr< SkStream >, Result *)
Definition: SkBmpCodec.cpp:91
SkStream * stream()
Definition: SkCodec.h:865
friend class SkIcoCodec
Definition: SkCodec.h:1040
Result
Definition: SkCodec.h:76
@ kIncompleteInput
Definition: SkCodec.h:84
@ kInvalidInput
Definition: SkCodec.h:109
@ kInternalError
Definition: SkCodec.h:118
@ kSuccess
Definition: SkCodec.h:80
static sk_sp< SkData > MakeWithoutCopy(const void *data, size_t length)
Definition: SkData.h:116
static sk_sp< SkData > MakeSubset(const SkData *src, size_t offset, size_t length)
Definition: SkData.cpp:173
static std::unique_ptr< SkMemoryStream > Make(sk_sp< SkData > data)
Definition: SkStream.cpp:314
static std::unique_ptr< SkCodec > MakeFromStream(std::unique_ptr< SkStream >, Result *, SkPngChunkReader *=nullptr)
static bool IsPng(const void *, size_t)
Definition: SkPngCodec.cpp:344
virtual size_t getLength() const
Definition: SkStream.h:137
virtual const void * getMemoryBase()
Definition: SkStream.h:141
static bool b
struct MyStruct a[10]
GAsyncResult * result
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
Definition: switches.h:259
std::unique_ptr< void, SkOverloadedFunctionObject< void(void *), sk_free > > UniqueVoidPtr
Definition: SkTemplates.h:431
SeparatedVector2 offset
std::shared_ptr< const fml::Mapping > data
Definition: texture_gles.cc:63

◆ onDimensionsSupported()

bool SkIcoCodec::onDimensionsSupported ( const SkISize )
overrideprotectedvirtual

Subclasses should override if they support dimensions other than the srcInfo's.

Reimplemented from SkCodec.

Definition at line 266 of file SkIcoCodec.cpp.

266 {
267 return this->chooseCodec(dim, 0) >= 0;
268}

◆ onGetEncodedFormat()

SkEncodedImageFormat SkIcoCodec::onGetEncodedFormat ( ) const
inlineoverrideprotectedvirtual

Implements SkCodec.

Definition at line 53 of file SkIcoCodec.h.

◆ onGetPixels()

SkCodec::Result SkIcoCodec::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 273 of file SkIcoCodec.cpp.

276 {
277 if (opts.fSubset) {
278 // Subsets are not supported.
279 return kUnimplemented;
280 }
281
282 int index = 0;
284 while (true) {
285 index = this->chooseCodec(dstInfo.dimensions(), index);
286 if (index < 0) {
287 break;
288 }
289
290 SkCodec* embeddedCodec = fEmbeddedCodecs->at(index).get();
291 result = embeddedCodec->getPixels(dstInfo, dst, dstRowBytes, &opts);
292 switch (result) {
293 case kSuccess:
294 case kIncompleteInput:
295 // The embedded codec will handle filling incomplete images, so we will indicate
296 // that all of the rows are initialized.
297 *rowsDecoded = dstInfo.height();
298 return result;
299 default:
300 // Continue trying to find a valid embedded codec on a failed decode.
301 break;
302 }
303
304 index++;
305 }
306
307 SkCodecPrintf("Error: No matching candidate image in ico.\n");
308 return result;
309}
const SkImageInfo & dstInfo() const
Definition: SkCodec.h:878
Result getPixels(const SkImageInfo &info, void *pixels, size_t rowBytes, const Options *)
Definition: SkCodec.cpp:467
@ kInvalidScale
Definition: SkCodec.h:100
@ kUnimplemented
Definition: SkCodec.h:123
dst
Definition: cp.py:12
SkISize dimensions() const
Definition: SkImageInfo.h:421
int height() const
Definition: SkImageInfo.h:371

◆ onGetScaledDimensions()

SkISize SkIcoCodec::onGetScaledDimensions ( float  desiredScale) const
overrideprotectedvirtual

Reimplemented from SkCodec.

Definition at line 228 of file SkIcoCodec.cpp.

228 {
229 // We set the dimensions to the largest candidate image by default.
230 // Regardless of the scale request, this is the largest image that we
231 // will decode.
232 int origWidth = this->dimensions().width();
233 int origHeight = this->dimensions().height();
234 float desiredSize = desiredScale * origWidth * origHeight;
235 // At least one image will have smaller error than this initial value
236 float minError = ((float) (origWidth * origHeight)) - desiredSize + 1.0f;
237 int32_t minIndex = -1;
238 for (int32_t i = 0; i < fEmbeddedCodecs->size(); i++) {
239 auto dimensions = fEmbeddedCodecs->at(i)->dimensions();
240 int width = dimensions.width();
241 int height = dimensions.height();
242 float error = SkTAbs(((float) (width * height)) - desiredSize);
243 if (error < minError) {
244 minError = error;
245 minIndex = i;
246 }
247 }
248 SkASSERT(minIndex >= 0);
249
250 return fEmbeddedCodecs->at(minIndex)->dimensions();
251}
static T SkTAbs(T value)
Definition: SkTemplates.h:43
SkISize dimensions() const
Definition: SkCodec.h:230
const uint8_t uint32_t uint32_t GError ** error
int32_t height
int32_t width
constexpr int32_t width() const
Definition: SkSize.h:36
constexpr int32_t height() const
Definition: SkSize.h:37

◆ onGetScanlineOrder()

SkCodec::SkScanlineOrder SkIcoCodec::onGetScanlineOrder ( ) const
overrideprotectedvirtual

The remaining functions revolve around decoding scanlines. Most images types will be kTopDown and will not need to override this function.

Reimplemented from SkCodec.

Definition at line 394 of file SkIcoCodec.cpp.

394 {
395 // FIXME: This function will possibly return the wrong value if it is called
396 // before startScanlineDecode()/startIncrementalDecode().
397 if (fCurrCodec) {
398 return fCurrCodec->getScanlineOrder();
399 }
400
402}
virtual SkScanlineOrder onGetScanlineOrder() const
Definition: SkCodec.h:876
SkScanlineOrder getScanlineOrder() const
Definition: SkCodec.h:613

◆ usesColorXform()

bool SkIcoCodec::usesColorXform ( ) const
inlineoverrideprotectedvirtual

Reimplemented from SkCodec.

Definition at line 65 of file SkIcoCodec.h.

65{ return false; }

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