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