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