Line data Source code
1 : /*
2 : * Copyright 2012 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 :
8 : #include "SkBitmap.h"
9 : #include "SkDeduper.h"
10 : #include "SkImage.h"
11 : #include "SkImageDeserializer.h"
12 : #include "SkImageGenerator.h"
13 : #include "SkMakeUnique.h"
14 : #include "SkReadBuffer.h"
15 : #include "SkStream.h"
16 : #include "SkTypeface.h"
17 :
18 : namespace {
19 :
20 : // This generator intentionally should always fail on all attempts to get its pixels,
21 : // simulating a bad or empty codec stream.
22 0 : class EmptyImageGenerator final : public SkImageGenerator {
23 : public:
24 0 : EmptyImageGenerator(const SkImageInfo& info) : INHERITED(info) { }
25 :
26 : private:
27 : typedef SkImageGenerator INHERITED;
28 : };
29 :
30 0 : static sk_sp<SkImage> MakeEmptyImage(int width, int height) {
31 : return SkImage::MakeFromGenerator(
32 0 : skstd::make_unique<EmptyImageGenerator>(SkImageInfo::MakeN32Premul(width, height)));
33 : }
34 :
35 : } // anonymous namespace
36 :
37 :
38 0 : static uint32_t default_flags() {
39 0 : uint32_t flags = 0;
40 0 : flags |= SkReadBuffer::kScalarIsFloat_Flag;
41 : if (8 == sizeof(void*)) {
42 0 : flags |= SkReadBuffer::kPtrIs64Bit_Flag;
43 : }
44 0 : return flags;
45 : }
46 :
47 : // This has an empty constructor and destructor, and is thread-safe, so we can use a singleton.
48 3 : static SkImageDeserializer gDefaultImageDeserializer;
49 :
50 0 : SkReadBuffer::SkReadBuffer() {
51 0 : fFlags = default_flags();
52 0 : fVersion = 0;
53 0 : fMemoryPtr = nullptr;
54 :
55 0 : fTFArray = nullptr;
56 0 : fTFCount = 0;
57 :
58 0 : fFactoryArray = nullptr;
59 0 : fFactoryCount = 0;
60 0 : fImageDeserializer = &gDefaultImageDeserializer;
61 : #ifdef DEBUG_NON_DETERMINISTIC_ASSERT
62 : fDecodedBitmapIndex = -1;
63 : #endif // DEBUG_NON_DETERMINISTIC_ASSERT
64 0 : }
65 :
66 0 : SkReadBuffer::SkReadBuffer(const void* data, size_t size) {
67 0 : fFlags = default_flags();
68 0 : fVersion = 0;
69 0 : fReader.setMemory(data, size);
70 0 : fMemoryPtr = nullptr;
71 :
72 0 : fTFArray = nullptr;
73 0 : fTFCount = 0;
74 :
75 0 : fFactoryArray = nullptr;
76 0 : fFactoryCount = 0;
77 0 : fImageDeserializer = &gDefaultImageDeserializer;
78 : #ifdef DEBUG_NON_DETERMINISTIC_ASSERT
79 : fDecodedBitmapIndex = -1;
80 : #endif // DEBUG_NON_DETERMINISTIC_ASSERT
81 0 : }
82 :
83 0 : SkReadBuffer::SkReadBuffer(SkStream* stream) {
84 0 : fFlags = default_flags();
85 0 : fVersion = 0;
86 0 : const size_t length = stream->getLength();
87 0 : fMemoryPtr = sk_malloc_throw(length);
88 0 : stream->read(fMemoryPtr, length);
89 0 : fReader.setMemory(fMemoryPtr, length);
90 :
91 0 : fTFArray = nullptr;
92 0 : fTFCount = 0;
93 :
94 0 : fFactoryArray = nullptr;
95 0 : fFactoryCount = 0;
96 0 : fImageDeserializer = &gDefaultImageDeserializer;
97 : #ifdef DEBUG_NON_DETERMINISTIC_ASSERT
98 : fDecodedBitmapIndex = -1;
99 : #endif // DEBUG_NON_DETERMINISTIC_ASSERT
100 0 : }
101 :
102 0 : SkReadBuffer::~SkReadBuffer() {
103 0 : sk_free(fMemoryPtr);
104 0 : }
105 :
106 0 : void SkReadBuffer::setImageDeserializer(SkImageDeserializer* deserializer) {
107 0 : fImageDeserializer = deserializer ? deserializer : &gDefaultImageDeserializer;
108 0 : }
109 :
110 0 : bool SkReadBuffer::readBool() {
111 0 : return fReader.readBool();
112 : }
113 :
114 0 : SkColor SkReadBuffer::readColor() {
115 0 : return fReader.readInt();
116 : }
117 :
118 0 : int32_t SkReadBuffer::readInt() {
119 0 : return fReader.readInt();
120 : }
121 :
122 0 : SkScalar SkReadBuffer::readScalar() {
123 0 : return fReader.readScalar();
124 : }
125 :
126 0 : uint32_t SkReadBuffer::readUInt() {
127 0 : return fReader.readU32();
128 : }
129 :
130 0 : int32_t SkReadBuffer::read32() {
131 0 : return fReader.readInt();
132 : }
133 :
134 0 : uint8_t SkReadBuffer::peekByte() {
135 0 : SkASSERT(fReader.available() > 0);
136 0 : return *((uint8_t*) fReader.peek());
137 : }
138 :
139 0 : void SkReadBuffer::readString(SkString* string) {
140 : size_t len;
141 0 : const char* strContents = fReader.readString(&len);
142 0 : string->set(strContents, len);
143 0 : }
144 :
145 0 : void SkReadBuffer::readColor4f(SkColor4f* color) {
146 0 : memcpy(color, fReader.skip(sizeof(SkColor4f)), sizeof(SkColor4f));
147 0 : }
148 :
149 0 : void SkReadBuffer::readPoint(SkPoint* point) {
150 0 : point->fX = fReader.readScalar();
151 0 : point->fY = fReader.readScalar();
152 0 : }
153 :
154 0 : void SkReadBuffer::readMatrix(SkMatrix* matrix) {
155 0 : fReader.readMatrix(matrix);
156 0 : }
157 :
158 0 : void SkReadBuffer::readIRect(SkIRect* rect) {
159 0 : memcpy(rect, fReader.skip(sizeof(SkIRect)), sizeof(SkIRect));
160 0 : }
161 :
162 0 : void SkReadBuffer::readRect(SkRect* rect) {
163 0 : memcpy(rect, fReader.skip(sizeof(SkRect)), sizeof(SkRect));
164 0 : }
165 :
166 0 : void SkReadBuffer::readRRect(SkRRect* rrect) {
167 0 : fReader.readRRect(rrect);
168 0 : }
169 :
170 0 : void SkReadBuffer::readRegion(SkRegion* region) {
171 0 : fReader.readRegion(region);
172 0 : }
173 :
174 0 : void SkReadBuffer::readPath(SkPath* path) {
175 0 : fReader.readPath(path);
176 0 : }
177 :
178 0 : bool SkReadBuffer::readArray(void* value, size_t size, size_t elementSize) {
179 0 : const size_t count = this->getArrayCount();
180 0 : if (count == size) {
181 0 : (void)fReader.skip(sizeof(uint32_t)); // Skip array count
182 0 : const size_t byteLength = count * elementSize;
183 0 : memcpy(value, fReader.skip(SkAlign4(byteLength)), byteLength);
184 0 : return true;
185 : }
186 0 : SkASSERT(false);
187 0 : fReader.skip(fReader.available());
188 0 : return false;
189 : }
190 :
191 0 : bool SkReadBuffer::readByteArray(void* value, size_t size) {
192 0 : return readArray(static_cast<unsigned char*>(value), size, sizeof(unsigned char));
193 : }
194 :
195 0 : bool SkReadBuffer::readColorArray(SkColor* colors, size_t size) {
196 0 : return readArray(colors, size, sizeof(SkColor));
197 : }
198 :
199 0 : bool SkReadBuffer::readColor4fArray(SkColor4f* colors, size_t size) {
200 0 : return readArray(colors, size, sizeof(SkColor4f));
201 : }
202 :
203 0 : bool SkReadBuffer::readIntArray(int32_t* values, size_t size) {
204 0 : return readArray(values, size, sizeof(int32_t));
205 : }
206 :
207 0 : bool SkReadBuffer::readPointArray(SkPoint* points, size_t size) {
208 0 : return readArray(points, size, sizeof(SkPoint));
209 : }
210 :
211 0 : bool SkReadBuffer::readScalarArray(SkScalar* values, size_t size) {
212 0 : return readArray(values, size, sizeof(SkScalar));
213 : }
214 :
215 0 : uint32_t SkReadBuffer::getArrayCount() {
216 0 : return *(uint32_t*)fReader.peek();
217 : }
218 :
219 0 : sk_sp<SkImage> SkReadBuffer::readBitmapAsImage() {
220 0 : const int width = this->readInt();
221 0 : const int height = this->readInt();
222 :
223 : // The writer stored a boolean value to determine whether an SkBitmapHeap was used during
224 : // writing. That feature is deprecated.
225 0 : if (this->readBool()) {
226 0 : this->readUInt(); // Bitmap index
227 0 : this->readUInt(); // Bitmap generation ID
228 : // Old unsupported SkBitmapHeap format. No longer supported.
229 : } else {
230 : // The writer stored false, meaning the SkBitmap was not stored in an SkBitmapHeap.
231 0 : const size_t length = this->readUInt();
232 0 : if (length > 0) {
233 : #ifdef DEBUG_NON_DETERMINISTIC_ASSERT
234 : fDecodedBitmapIndex++;
235 : #endif // DEBUG_NON_DETERMINISTIC_ASSERT
236 : // A non-zero size means the SkBitmap was encoded. Read the data and pixel
237 : // offset.
238 0 : const void* data = this->skip(length);
239 0 : const int32_t xOffset = this->readInt();
240 0 : const int32_t yOffset = this->readInt();
241 0 : SkIRect subset = SkIRect::MakeXYWH(xOffset, yOffset, width, height);
242 0 : sk_sp<SkImage> image = fImageDeserializer->makeFromMemory(data, length, &subset);
243 0 : if (image) {
244 0 : return image;
245 : }
246 :
247 : // This bitmap was encoded when written, but we are unable to
248 : // decode, possibly due to not having a decoder. Even though we
249 : // weren't able to decode the pixels, the readbuffer should still
250 : // be intact, so we return true with an empty bitmap, so we don't
251 : // force an abort of the larger deserialize.
252 0 : return MakeEmptyImage(width, height);
253 : } else {
254 0 : SkBitmap bitmap;
255 0 : if (SkBitmap::ReadRawPixels(this, &bitmap)) {
256 0 : bitmap.setImmutable();
257 0 : return SkImage::MakeFromBitmap(bitmap);
258 : }
259 : }
260 : }
261 : // Could not read the SkBitmap. Use a placeholder bitmap.
262 0 : return nullptr;
263 : }
264 :
265 0 : sk_sp<SkImage> SkReadBuffer::readImage() {
266 0 : if (fInflator) {
267 0 : SkImage* img = fInflator->getImage(this->read32());
268 0 : return img ? sk_ref_sp(img) : nullptr;
269 : }
270 :
271 0 : int width = this->read32();
272 0 : int height = this->read32();
273 0 : if (width <= 0 || height <= 0) { // SkImage never has a zero dimension
274 0 : this->validate(false);
275 0 : return nullptr;
276 : }
277 :
278 0 : uint32_t encoded_size = this->getArrayCount();
279 0 : if (encoded_size == 0) {
280 : // The image could not be encoded at serialization time - return an empty placeholder.
281 0 : (void)this->readUInt(); // Swallow that encoded_size == 0 sentinel.
282 0 : return MakeEmptyImage(width, height);
283 : }
284 0 : if (encoded_size == 1) {
285 : // We had to encode the image as raw pixels via SkBitmap.
286 0 : (void)this->readUInt(); // Swallow that encoded_size == 1 sentinel.
287 0 : SkBitmap bm;
288 0 : if (SkBitmap::ReadRawPixels(this, &bm)) {
289 0 : return SkImage::MakeFromBitmap(bm);
290 : }
291 0 : return MakeEmptyImage(width, height);
292 : }
293 :
294 : // The SkImage encoded itself.
295 0 : sk_sp<SkData> encoded(this->readByteArrayAsData());
296 :
297 0 : int originX = this->read32();
298 0 : int originY = this->read32();
299 0 : if (originX < 0 || originY < 0) {
300 0 : this->validate(false);
301 0 : return nullptr;
302 : }
303 :
304 0 : const SkIRect subset = SkIRect::MakeXYWH(originX, originY, width, height);
305 :
306 0 : sk_sp<SkImage> image = fImageDeserializer->makeFromData(encoded.get(), &subset);
307 0 : return image ? image : MakeEmptyImage(width, height);
308 : }
309 :
310 0 : sk_sp<SkTypeface> SkReadBuffer::readTypeface() {
311 0 : if (fInflator) {
312 0 : return sk_ref_sp(fInflator->getTypeface(this->read32()));
313 : }
314 :
315 0 : uint32_t index = this->readUInt();
316 0 : if (0 == index || index > (unsigned)fTFCount) {
317 0 : return nullptr;
318 : } else {
319 0 : SkASSERT(fTFArray);
320 0 : return sk_ref_sp(fTFArray[index - 1]);
321 : }
322 : }
323 :
324 0 : SkFlattenable* SkReadBuffer::readFlattenable(SkFlattenable::Type ft) {
325 : //
326 : // TODO: confirm that ft matches the factory we decide to use
327 : //
328 :
329 0 : SkFlattenable::Factory factory = nullptr;
330 :
331 0 : if (fInflator) {
332 0 : factory = fInflator->getFactory(this->read32());
333 0 : if (!factory) {
334 0 : return nullptr;
335 : }
336 0 : } else if (fFactoryCount > 0) {
337 0 : int32_t index = fReader.readU32();
338 0 : if (0 == index) {
339 0 : return nullptr; // writer failed to give us the flattenable
340 : }
341 0 : index -= 1; // we stored the index-base-1
342 0 : if ((unsigned)index >= (unsigned)fFactoryCount) {
343 0 : this->validate(false);
344 0 : return nullptr;
345 : }
346 0 : factory = fFactoryArray[index];
347 : } else {
348 0 : SkString name;
349 0 : if (this->peekByte()) {
350 : // If the first byte is non-zero, the flattenable is specified by a string.
351 0 : this->readString(&name);
352 :
353 : // Add the string to the dictionary.
354 0 : fFlattenableDict.set(fFlattenableDict.count() + 1, name);
355 : } else {
356 : // Read the index. We are guaranteed that the first byte
357 : // is zeroed, so we must shift down a byte.
358 0 : uint32_t index = fReader.readU32() >> 8;
359 0 : if (0 == index) {
360 0 : return nullptr; // writer failed to give us the flattenable
361 : }
362 :
363 0 : SkString* namePtr = fFlattenableDict.find(index);
364 0 : SkASSERT(namePtr);
365 0 : name = *namePtr;
366 : }
367 :
368 : // Check if a custom Factory has been specified for this flattenable.
369 0 : if (!(factory = this->getCustomFactory(name))) {
370 : // If there is no custom Factory, check for a default.
371 0 : if (!(factory = SkFlattenable::NameToFactory(name.c_str()))) {
372 0 : return nullptr; // writer failed to give us the flattenable
373 : }
374 : }
375 : }
376 :
377 : // if we get here, factory may still be null, but if that is the case, the
378 : // failure was ours, not the writer.
379 0 : sk_sp<SkFlattenable> obj;
380 0 : uint32_t sizeRecorded = fReader.readU32();
381 0 : if (factory) {
382 0 : size_t offset = fReader.offset();
383 0 : obj = (*factory)(*this);
384 : // check that we read the amount we expected
385 0 : size_t sizeRead = fReader.offset() - offset;
386 0 : if (sizeRecorded != sizeRead) {
387 0 : this->validate(false);
388 0 : return nullptr;
389 : }
390 : } else {
391 : // we must skip the remaining data
392 0 : fReader.skip(sizeRecorded);
393 : }
394 0 : return obj.release();
395 : }
|