1
2 /*
3 * Copyright 2012 Google Inc.
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
8
9 #include "SkBitmap.h"
10 #include "SkErrorInternals.h"
11 #include "SkImage.h"
12 #include "SkImageGenerator.h"
13 #include "SkReadBuffer.h"
14 #include "SkStream.h"
15 #include "SkTypeface.h"
16
default_flags()17 static uint32_t default_flags() {
18 uint32_t flags = 0;
19 flags |= SkReadBuffer::kScalarIsFloat_Flag;
20 if (8 == sizeof(void*)) {
21 flags |= SkReadBuffer::kPtrIs64Bit_Flag;
22 }
23 return flags;
24 }
25
SkReadBuffer()26 SkReadBuffer::SkReadBuffer() {
27 fFlags = default_flags();
28 fVersion = 0;
29 fMemoryPtr = nullptr;
30
31 fBitmapStorage = nullptr;
32 fTFArray = nullptr;
33 fTFCount = 0;
34
35 fFactoryTDArray = nullptr;
36 fFactoryArray = nullptr;
37 fFactoryCount = 0;
38 fBitmapDecoder = nullptr;
39 #ifdef DEBUG_NON_DETERMINISTIC_ASSERT
40 fDecodedBitmapIndex = -1;
41 #endif // DEBUG_NON_DETERMINISTIC_ASSERT
42 }
43
SkReadBuffer(const void * data,size_t size)44 SkReadBuffer::SkReadBuffer(const void* data, size_t size) {
45 fFlags = default_flags();
46 fVersion = 0;
47 fReader.setMemory(data, size);
48 fMemoryPtr = nullptr;
49
50 fBitmapStorage = nullptr;
51 fTFArray = nullptr;
52 fTFCount = 0;
53
54 fFactoryTDArray = nullptr;
55 fFactoryArray = nullptr;
56 fFactoryCount = 0;
57 fBitmapDecoder = nullptr;
58 #ifdef DEBUG_NON_DETERMINISTIC_ASSERT
59 fDecodedBitmapIndex = -1;
60 #endif // DEBUG_NON_DETERMINISTIC_ASSERT
61 }
62
SkReadBuffer(SkStream * stream)63 SkReadBuffer::SkReadBuffer(SkStream* stream) {
64 fFlags = default_flags();
65 fVersion = 0;
66 const size_t length = stream->getLength();
67 fMemoryPtr = sk_malloc_throw(length);
68 stream->read(fMemoryPtr, length);
69 fReader.setMemory(fMemoryPtr, length);
70
71 fBitmapStorage = nullptr;
72 fTFArray = nullptr;
73 fTFCount = 0;
74
75 fFactoryTDArray = nullptr;
76 fFactoryArray = nullptr;
77 fFactoryCount = 0;
78 fBitmapDecoder = nullptr;
79 #ifdef DEBUG_NON_DETERMINISTIC_ASSERT
80 fDecodedBitmapIndex = -1;
81 #endif // DEBUG_NON_DETERMINISTIC_ASSERT
82 }
83
~SkReadBuffer()84 SkReadBuffer::~SkReadBuffer() {
85 sk_free(fMemoryPtr);
86 SkSafeUnref(fBitmapStorage);
87 }
88
readBool()89 bool SkReadBuffer::readBool() {
90 return fReader.readBool();
91 }
92
readColor()93 SkColor SkReadBuffer::readColor() {
94 return fReader.readInt();
95 }
96
readFixed()97 SkFixed SkReadBuffer::readFixed() {
98 return fReader.readS32();
99 }
100
readInt()101 int32_t SkReadBuffer::readInt() {
102 return fReader.readInt();
103 }
104
readScalar()105 SkScalar SkReadBuffer::readScalar() {
106 return fReader.readScalar();
107 }
108
readUInt()109 uint32_t SkReadBuffer::readUInt() {
110 return fReader.readU32();
111 }
112
read32()113 int32_t SkReadBuffer::read32() {
114 return fReader.readInt();
115 }
116
readString(SkString * string)117 void SkReadBuffer::readString(SkString* string) {
118 size_t len;
119 const char* strContents = fReader.readString(&len);
120 string->set(strContents, len);
121 }
122
readEncodedString(size_t * length,SkPaint::TextEncoding encoding)123 void* SkReadBuffer::readEncodedString(size_t* length, SkPaint::TextEncoding encoding) {
124 SkDEBUGCODE(int32_t encodingType = ) fReader.readInt();
125 SkASSERT(encodingType == encoding);
126 *length = fReader.readInt();
127 void* data = sk_malloc_throw(*length);
128 memcpy(data, fReader.skip(SkAlign4(*length)), *length);
129 return data;
130 }
131
readPoint(SkPoint * point)132 void SkReadBuffer::readPoint(SkPoint* point) {
133 point->fX = fReader.readScalar();
134 point->fY = fReader.readScalar();
135 }
136
readMatrix(SkMatrix * matrix)137 void SkReadBuffer::readMatrix(SkMatrix* matrix) {
138 fReader.readMatrix(matrix);
139 }
140
readIRect(SkIRect * rect)141 void SkReadBuffer::readIRect(SkIRect* rect) {
142 memcpy(rect, fReader.skip(sizeof(SkIRect)), sizeof(SkIRect));
143 }
144
readRect(SkRect * rect)145 void SkReadBuffer::readRect(SkRect* rect) {
146 memcpy(rect, fReader.skip(sizeof(SkRect)), sizeof(SkRect));
147 }
148
readRegion(SkRegion * region)149 void SkReadBuffer::readRegion(SkRegion* region) {
150 fReader.readRegion(region);
151 }
152
readPath(SkPath * path)153 void SkReadBuffer::readPath(SkPath* path) {
154 fReader.readPath(path);
155 }
156
readArray(void * value,size_t size,size_t elementSize)157 bool SkReadBuffer::readArray(void* value, size_t size, size_t elementSize) {
158 const size_t count = this->getArrayCount();
159 if (count == size) {
160 (void)fReader.skip(sizeof(uint32_t)); // Skip array count
161 const size_t byteLength = count * elementSize;
162 memcpy(value, fReader.skip(SkAlign4(byteLength)), byteLength);
163 return true;
164 }
165 SkASSERT(false);
166 fReader.skip(fReader.available());
167 return false;
168 }
169
readByteArray(void * value,size_t size)170 bool SkReadBuffer::readByteArray(void* value, size_t size) {
171 return readArray(static_cast<unsigned char*>(value), size, sizeof(unsigned char));
172 }
173
readColorArray(SkColor * colors,size_t size)174 bool SkReadBuffer::readColorArray(SkColor* colors, size_t size) {
175 return readArray(colors, size, sizeof(SkColor));
176 }
177
readIntArray(int32_t * values,size_t size)178 bool SkReadBuffer::readIntArray(int32_t* values, size_t size) {
179 return readArray(values, size, sizeof(int32_t));
180 }
181
readPointArray(SkPoint * points,size_t size)182 bool SkReadBuffer::readPointArray(SkPoint* points, size_t size) {
183 return readArray(points, size, sizeof(SkPoint));
184 }
185
readScalarArray(SkScalar * values,size_t size)186 bool SkReadBuffer::readScalarArray(SkScalar* values, size_t size) {
187 return readArray(values, size, sizeof(SkScalar));
188 }
189
getArrayCount()190 uint32_t SkReadBuffer::getArrayCount() {
191 return *(uint32_t*)fReader.peek();
192 }
193
readBitmap(SkBitmap * bitmap)194 bool SkReadBuffer::readBitmap(SkBitmap* bitmap) {
195 const int width = this->readInt();
196 const int height = this->readInt();
197 // The writer stored a boolean value to determine whether an SkBitmapHeap was used during
198 // writing.
199 if (this->readBool()) {
200 // An SkBitmapHeap was used for writing. Read the index from the stream and find the
201 // corresponding SkBitmap in fBitmapStorage.
202 const uint32_t index = this->readUInt();
203 this->readUInt(); // bitmap generation ID (see SkWriteBuffer::writeBitmap)
204 if (fBitmapStorage) {
205 *bitmap = *fBitmapStorage->getBitmap(index);
206 fBitmapStorage->releaseRef(index);
207 return true;
208 } else {
209 // The bitmap was stored in a heap, but there is no way to access it. Set an error and
210 // fall through to use a place holder bitmap.
211 SkErrorInternals::SetError(kParseError_SkError, "SkWriteBuffer::writeBitmap "
212 "stored the SkBitmap in an SkBitmapHeap, but "
213 "SkReadBuffer has no SkBitmapHeapReader to "
214 "retrieve the SkBitmap.");
215 }
216 } else {
217 // The writer stored false, meaning the SkBitmap was not stored in an SkBitmapHeap.
218 const size_t length = this->readUInt();
219 if (length > 0) {
220 #ifdef DEBUG_NON_DETERMINISTIC_ASSERT
221 fDecodedBitmapIndex++;
222 #endif // DEBUG_NON_DETERMINISTIC_ASSERT
223 // A non-zero size means the SkBitmap was encoded. Read the data and pixel
224 // offset.
225 const void* data = this->skip(length);
226 const int32_t xOffset = this->readInt();
227 const int32_t yOffset = this->readInt();
228 if (fBitmapDecoder != nullptr && fBitmapDecoder(data, length, bitmap)) {
229 if (bitmap->width() == width && bitmap->height() == height) {
230 #ifdef DEBUG_NON_DETERMINISTIC_ASSERT
231 if (0 != xOffset || 0 != yOffset) {
232 SkDebugf("SkReadBuffer::readBitmap: heights match,"
233 " but offset is not zero. \nInfo about the bitmap:"
234 "\n\tIndex: %d\n\tDimensions: [%d %d]\n\tEncoded"
235 " data size: %d\n\tOffset: (%d, %d)\n",
236 fDecodedBitmapIndex, width, height, length, xOffset,
237 yOffset);
238 }
239 #endif // DEBUG_NON_DETERMINISTIC_ASSERT
240 // If the width and height match, there should be no offset.
241 SkASSERT(0 == xOffset && 0 == yOffset);
242 return true;
243 }
244
245 // This case can only be reached if extractSubset was called, so
246 // the recorded width and height must be smaller than or equal to
247 // the encoded width and height.
248 // FIXME (scroggo): This assert assumes that our decoder and the
249 // sources encoder agree on the width and height which may not
250 // always be the case. Removing until it can be investigated
251 // further.
252 //SkASSERT(width <= bitmap->width() && height <= bitmap->height());
253
254 SkBitmap subsetBm;
255 SkIRect subset = SkIRect::MakeXYWH(xOffset, yOffset, width, height);
256 if (bitmap->extractSubset(&subsetBm, subset)) {
257 bitmap->swap(subsetBm);
258 return true;
259 }
260 }
261 // This bitmap was encoded when written, but we are unable to decode, possibly due to
262 // not having a decoder.
263 SkErrorInternals::SetError(kParseError_SkError,
264 "Could not decode bitmap. Resulting bitmap will be empty.");
265 // Even though we weren't able to decode the pixels, the readbuffer should still be
266 // intact, so we return true with an empty bitmap, so we don't force an abort of the
267 // larger deserialize.
268 bitmap->setInfo(SkImageInfo::MakeUnknown(width, height));
269 return true;
270 } else if (SkBitmap::ReadRawPixels(this, bitmap)) {
271 return true;
272 }
273 }
274 // Could not read the SkBitmap. Use a placeholder bitmap.
275 bitmap->setInfo(SkImageInfo::MakeUnknown(width, height));
276 return false;
277 }
278
279 namespace {
280
281 // This generator intentionally should always fail on all attempts to get its pixels,
282 // simulating a bad or empty codec stream.
283 class EmptyImageGenerator final : public SkImageGenerator {
284 public:
EmptyImageGenerator(const SkImageInfo & info)285 EmptyImageGenerator(const SkImageInfo& info) : INHERITED(info) { }
286
287 private:
288 typedef SkImageGenerator INHERITED;
289 };
290
291 } // anonymous namespace
292
readImage()293 SkImage* SkReadBuffer::readImage() {
294 int width = this->read32();
295 int height = this->read32();
296 if (width <= 0 || height <= 0) { // SkImage never has a zero dimension
297 this->validate(false);
298 return nullptr;
299 }
300
301 SkAutoTUnref<SkData> encoded(this->readByteArrayAsData());
302 if (encoded->size() == 0) {
303 // The image could not be encoded at serialization time - return an empty placeholder.
304 return SkImage::NewFromGenerator(
305 new EmptyImageGenerator(SkImageInfo::MakeN32Premul(width, height)));
306 }
307
308 int originX = this->read32();
309 int originY = this->read32();
310 if (originX < 0 || originY < 0) {
311 this->validate(false);
312 return nullptr;
313 }
314
315 const SkIRect subset = SkIRect::MakeXYWH(originX, originY, width, height);
316 SkImage* image = SkImage::NewFromEncoded(encoded, &subset);
317 if (image) {
318 return image;
319 }
320
321 return SkImage::NewFromGenerator(
322 new EmptyImageGenerator(SkImageInfo::MakeN32Premul(width, height)));
323 }
324
readTypeface()325 SkTypeface* SkReadBuffer::readTypeface() {
326
327 uint32_t index = fReader.readU32();
328 if (0 == index || index > (unsigned)fTFCount) {
329 return nullptr;
330 } else {
331 SkASSERT(fTFArray);
332 return fTFArray[index - 1];
333 }
334 }
335
readFlattenable(SkFlattenable::Type ft)336 SkFlattenable* SkReadBuffer::readFlattenable(SkFlattenable::Type ft) {
337 //
338 // TODO: confirm that ft matches the factory we decide to use
339 //
340
341 SkFlattenable::Factory factory = nullptr;
342
343 if (fFactoryCount > 0) {
344 int32_t index = fReader.readU32();
345 if (0 == index) {
346 return nullptr; // writer failed to give us the flattenable
347 }
348 index -= 1; // we stored the index-base-1
349 if ((unsigned)index >= (unsigned)fFactoryCount) {
350 this->validate(false);
351 return nullptr;
352 }
353 factory = fFactoryArray[index];
354 } else if (fFactoryTDArray) {
355 int32_t index = fReader.readU32();
356 if (0 == index) {
357 return nullptr; // writer failed to give us the flattenable
358 }
359 index -= 1; // we stored the index-base-1
360 if ((unsigned)index >= (unsigned)fFactoryCount) {
361 this->validate(false);
362 return nullptr;
363 }
364 factory = (*fFactoryTDArray)[index];
365 } else {
366 factory = (SkFlattenable::Factory)readFunctionPtr();
367 if (nullptr == factory) {
368 return nullptr; // writer failed to give us the flattenable
369 }
370 }
371
372 // if we get here, factory may still be null, but if that is the case, the
373 // failure was ours, not the writer.
374 SkFlattenable* obj = nullptr;
375 uint32_t sizeRecorded = fReader.readU32();
376 if (factory) {
377 size_t offset = fReader.offset();
378 obj = (*factory)(*this);
379 // check that we read the amount we expected
380 size_t sizeRead = fReader.offset() - offset;
381 if (sizeRecorded != sizeRead) {
382 this->validate(false);
383 return nullptr;
384 }
385 } else {
386 // we must skip the remaining data
387 fReader.skip(sizeRecorded);
388 }
389 return obj;
390 }
391
392 /**
393 * Needs to follow the same pattern as readFlattenable(), but explicitly skip whatever data
394 * has been written.
395 */
skipFlattenable()396 void SkReadBuffer::skipFlattenable() {
397 if (fFactoryCount > 0) {
398 if (0 == fReader.readU32()) {
399 return;
400 }
401 } else if (fFactoryTDArray) {
402 if (0 == fReader.readU32()) {
403 return;
404 }
405 } else {
406 if (nullptr == this->readFunctionPtr()) {
407 return;
408 }
409 }
410 uint32_t sizeRecorded = fReader.readU32();
411 fReader.skip(sizeRecorded);
412 }
413