Flutter Engine
The Flutter Engine
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
SkWbmpCodec.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2015 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
9
14#include "include/core/SkData.h"
17#include "include/core/SkSize.h"
22#include "modules/skcms/skcms.h"
24
25#include <utility>
26
27using namespace skia_private;
28
29// Each bit represents a pixel, so width is actually a number of bits.
30// A row will always be stored in bytes, so we round width up to the
31// nearest multiple of 8 to get the number of bits actually in the row.
32// We then divide by 8 to convert to bytes.
33static inline size_t get_src_row_bytes(int width) {
34 return SkAlign8(width) >> 3;
35}
36
37static inline bool valid_color_type(const SkImageInfo& dstInfo) {
38 switch (dstInfo.colorType()) {
43 return true;
45 return dstInfo.colorSpace();
46 default:
47 return false;
48 }
49}
50
51static bool read_byte(SkStream* stream, uint8_t* data)
52{
53 return stream->read(data, 1) == 1;
54}
55
56// http://en.wikipedia.org/wiki/Variable-length_quantity
57static bool read_mbf(SkStream* stream, uint64_t* value) {
58 uint64_t n = 0;
59 uint8_t data;
60 const uint64_t kLimit = 0xFE00000000000000;
61 SkASSERT(kLimit == ~((~static_cast<uint64_t>(0)) >> 7));
62 do {
63 if (n & kLimit) { // Will overflow on shift by 7.
64 return false;
65 }
66 if (stream->read(&data, 1) != 1) {
67 return false;
68 }
69 n = (n << 7) | (data & 0x7F);
70 } while (data & 0x80);
71 *value = n;
72 return true;
73}
74
76 {
77 uint8_t data;
78 if (!read_byte(stream, &data) || data != 0) { // unknown type
79 return false;
80 }
81 if (!read_byte(stream, &data) || (data & 0x9F)) { // skip fixed header
82 return false;
83 }
84 }
85
86 uint64_t width, height;
87 if (!read_mbf(stream, &width) || width > 0xFFFF || !width) {
88 return false;
89 }
90 if (!read_mbf(stream, &height) || height > 0xFFFF || !height) {
91 return false;
92 }
93 if (size) {
95 }
96 return true;
97}
98
100 return read_header(this->stream(), nullptr);
101}
102
103bool SkWbmpCodec::readRow(uint8_t* row) {
104 return this->stream()->read(row, fSrcRowBytes) == fSrcRowBytes;
105}
106
107SkWbmpCodec::SkWbmpCodec(SkEncodedInfo&& info, std::unique_ptr<SkStream> stream)
108 // Wbmp does not need a colorXform, so choose an arbitrary srcFormat.
110 std::move(stream))
111 , fSrcRowBytes(get_src_row_bytes(this->dimensions().width()))
112 , fSwizzler(nullptr)
113{}
114
117}
118
120 bool /*needsColorXform*/) {
121 return valid_color_type(dst) && valid_alpha(dst.alphaType(), srcIsOpaque);
122}
123
125 void* dst,
126 size_t rowBytes,
127 const Options& options,
128 int* rowsDecoded) {
129 if (options.fSubset) {
130 // Subsets are not supported.
131 return kUnimplemented;
132 }
133
134 // Initialize the swizzler
135 std::unique_ptr<SkSwizzler> swizzler = SkSwizzler::Make(this->getEncodedInfo(), nullptr, info,
136 options);
137 SkASSERT(swizzler);
138
139 // Perform the decode
140 SkISize size = info.dimensions();
141 AutoTMalloc<uint8_t> src(fSrcRowBytes);
142 void* dstRow = dst;
143 for (int y = 0; y < size.height(); ++y) {
144 if (!this->readRow(src.get())) {
145 *rowsDecoded = y;
146 return kIncompleteInput;
147 }
148 swizzler->swizzle(dstRow, src.get());
149 dstRow = SkTAddOffset<void>(dstRow, rowBytes);
150 }
151 return kSuccess;
152}
153
154bool SkWbmpCodec::IsWbmp(const void* buffer, size_t bytesRead) {
155 SkMemoryStream stream(buffer, bytesRead, false);
156 return read_header(&stream, nullptr);
157}
158
159std::unique_ptr<SkCodec> SkWbmpCodec::MakeFromStream(std::unique_ptr<SkStream> stream,
160 Result* result) {
162 if (!stream) {
164 return nullptr;
165 }
167 if (!read_header(stream.get(), &size)) {
168 // This already succeeded in IsWbmp, so this stream was corrupted in/
169 // after rewind.
171 return nullptr;
172 }
173 *result = kSuccess;
176 return std::unique_ptr<SkCodec>(new SkWbmpCodec(std::move(info), std::move(stream)));
177}
178
179int SkWbmpCodec::onGetScanlines(void* dst, int count, size_t dstRowBytes) {
180 void* dstRow = dst;
181 for (int y = 0; y < count; ++y) {
182 if (!this->readRow(fSrcBuffer.get())) {
183 return y;
184 }
185 fSwizzler->swizzle(dstRow, fSrcBuffer.get());
186 dstRow = SkTAddOffset<void>(dstRow, dstRowBytes);
187 }
188 return count;
189}
190
191bool SkWbmpCodec::onSkipScanlines(int count) {
192 const size_t bytesToSkip = count * fSrcRowBytes;
193 return this->stream()->skip(bytesToSkip) == bytesToSkip;
194}
195
196SkCodec::Result SkWbmpCodec::onStartScanlineDecode(const SkImageInfo& dstInfo,
197 const Options& options) {
198 if (options.fSubset) {
199 // Subsets are not supported.
200 return kUnimplemented;
201 }
202
203 fSwizzler = SkSwizzler::Make(this->getEncodedInfo(), nullptr, dstInfo, options);
204 SkASSERT(fSwizzler);
205
206 fSrcBuffer.reset(fSrcRowBytes);
207
208 return kSuccess;
209}
210
211namespace SkWbmpDecoder {
212bool IsWbmp(const void* data, size_t len) {
214}
215
216std::unique_ptr<SkCodec> Decode(std::unique_ptr<SkStream> stream,
217 SkCodec::Result* outResult,
219 SkCodec::Result resultStorage;
220 if (!outResult) {
221 outResult = &resultStorage;
222 }
223 return SkWbmpCodec::MakeFromStream(std::move(stream), outResult);
224}
225
226std::unique_ptr<SkCodec> Decode(sk_sp<SkData> data,
227 SkCodec::Result* outResult,
229 if (!data) {
230 if (outResult) {
231 *outResult = SkCodec::kInvalidInput;
232 }
233 return nullptr;
234 }
235 return Decode(SkMemoryStream::Make(std::move(data)), outResult, nullptr);
236}
237} // namespace SkWbmpDecoder
const char * options
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
Definition: DM.cpp:213
int count
Definition: FontMgrTest.cpp:50
static constexpr T SkAlign8(T x)
Definition: SkAlign.h:17
#define SkASSERT(cond)
Definition: SkAssert.h:116
static bool valid_alpha(SkAlphaType dstAlpha, bool srcIsOpaque)
Definition: SkCodecPriv.h:90
@ 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
@ kGray_8_SkColorType
pixel with grayscale level in 8-bit byte
Definition: SkColorType.h:35
@ 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
SkEncodedImageFormat
#define INHERITED(method,...)
Definition: SkRecorder.cpp:128
constexpr int32_t SkToS32(S x)
Definition: SkTo.h:25
static bool read_mbf(SkStream *stream, uint64_t *value)
Definition: SkWbmpCodec.cpp:57
static bool read_byte(SkStream *stream, uint8_t *data)
Definition: SkWbmpCodec.cpp:51
static size_t get_src_row_bytes(int width)
Definition: SkWbmpCodec.cpp:33
static bool valid_color_type(const SkImageInfo &dstInfo)
Definition: SkWbmpCodec.cpp:37
static bool read_header(SkStream *stream, SkISize *size)
Definition: SkWbmpCodec.cpp:75
SkStream * stream()
Definition: SkCodec.h:865
const SkEncodedInfo & getEncodedInfo() const
Definition: SkCodec.h:788
Result
Definition: SkCodec.h:76
@ kIncompleteInput
Definition: SkCodec.h:84
@ kInvalidInput
Definition: SkCodec.h:109
@ kCouldNotRewind
Definition: SkCodec.h:114
@ kUnimplemented
Definition: SkCodec.h:123
@ kSuccess
Definition: SkCodec.h:80
const Options & options() const
Definition: SkCodec.h:880
static std::unique_ptr< SkMemoryStream > Make(sk_sp< SkData > data)
Definition: SkStream.cpp:314
size_t skip(size_t size)
Definition: SkStream.h:51
virtual size_t read(void *buffer, size_t size)=0
static std::unique_ptr< SkSwizzler > Make(const SkEncodedInfo &encodedInfo, const SkPMColor *ctable, const SkImageInfo &dstInfo, const SkCodec::Options &, const SkIRect *frame=nullptr)
Definition: SkSwizzler.cpp:821
SkEncodedImageFormat onGetEncodedFormat() const override
static bool IsWbmp(const void *, size_t)
bool conversionSupported(const SkImageInfo &dst, bool srcIsOpaque, bool needsXform) override
bool onRewind() override
Definition: SkWbmpCodec.cpp:99
Result onGetPixels(const SkImageInfo &, void *, size_t, const Options &, int *) override
static std::unique_ptr< SkCodec > MakeFromStream(std::unique_ptr< SkStream >, Result *)
T * reset(size_t count=0)
Definition: SkTemplates.h:296
uint8_t value
GAsyncResult * result
double y
void * DecodeContext
Definition: SkCodec.h:1047
SK_API bool IsWbmp(const void *, size_t)
SK_API std::unique_ptr< SkCodec > Decode(std::unique_ptr< SkStream >, SkCodec::Result *, SkCodecs::DecodeContext=nullptr)
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
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
dst
Definition: cp.py:12
Definition: ref_ptr.h:256
int32_t height
int32_t width
skcms_PixelFormat
Definition: skcms_public.h:273
const SkIRect * fSubset
Definition: SkCodec.h:347
static SkEncodedInfo Make(int width, int height, Color color, Alpha alpha, int bitsPerComponent)
Definition: SkSize.h:16
static constexpr SkISize Make(int32_t w, int32_t h)
Definition: SkSize.h:20
SkColorSpace * colorSpace() const
SkColorType colorType() const
Definition: SkImageInfo.h:373
std::shared_ptr< const fml::Mapping > data
Definition: texture_gles.cc:63