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
140bool SkOrderedReadBuffer::readArray(void* value, size_t size, size_t elementSize) {
141    const size_t count = this->getArrayCount();
142    if (count == size) {
143        (void)fReader.skip(sizeof(uint32_t)); // Skip array count
144        const size_t byteLength = count * elementSize;
145        memcpy(value, fReader.skip(SkAlign4(byteLength)), byteLength);
146        return true;
147    }
148    SkASSERT(false);
149    fReader.skip(fReader.available());
150    return false;
151}
152
153bool SkOrderedReadBuffer::readByteArray(void* value, size_t size) {
154    return readArray(static_cast<unsigned char*>(value), size, sizeof(unsigned char));
155}
156
157bool SkOrderedReadBuffer::readColorArray(SkColor* colors, size_t size) {
158    return readArray(colors, size, sizeof(SkColor));
159}
160
161bool SkOrderedReadBuffer::readIntArray(int32_t* values, size_t size) {
162    return readArray(values, size, sizeof(int32_t));
163}
164
165bool SkOrderedReadBuffer::readPointArray(SkPoint* points, size_t size) {
166    return readArray(points, size, sizeof(SkPoint));
167}
168
169bool SkOrderedReadBuffer::readScalarArray(SkScalar* values, size_t size) {
170    return readArray(values, size, sizeof(SkScalar));
171}
172
173uint32_t SkOrderedReadBuffer::getArrayCount() {
174    return *(uint32_t*)fReader.peek();
175}
176
177void SkOrderedReadBuffer::readBitmap(SkBitmap* bitmap) {
178    const int width = this->readInt();
179    const int height = this->readInt();
180    // The writer stored a boolean value to determine whether an SkBitmapHeap was used during
181    // writing.
182    if (this->readBool()) {
183        // An SkBitmapHeap was used for writing. Read the index from the stream and find the
184        // corresponding SkBitmap in fBitmapStorage.
185        const uint32_t index = fReader.readU32();
186        fReader.readU32(); // bitmap generation ID (see SkOrderedWriteBuffer::writeBitmap)
187        if (fBitmapStorage) {
188            *bitmap = *fBitmapStorage->getBitmap(index);
189            fBitmapStorage->releaseRef(index);
190            return;
191        } else {
192            // The bitmap was stored in a heap, but there is no way to access it. Set an error and
193            // fall through to use a place holder bitmap.
194            SkErrorInternals::SetError(kParseError_SkError, "SkOrderedWriteBuffer::writeBitmap "
195                                       "stored the SkBitmap in an SkBitmapHeap, but "
196                                       "SkOrderedReadBuffer has no SkBitmapHeapReader to "
197                                       "retrieve the SkBitmap.");
198        }
199    } else {
200        // The writer stored false, meaning the SkBitmap was not stored in an SkBitmapHeap.
201        const size_t length = this->readUInt();
202        if (length > 0) {
203#ifdef DEBUG_NON_DETERMINISTIC_ASSERT
204            fDecodedBitmapIndex++;
205#endif // DEBUG_NON_DETERMINISTIC_ASSERT
206            // A non-zero size means the SkBitmap was encoded. Read the data and pixel
207            // offset.
208            const void* data = this->skip(length);
209            const int32_t xOffset = fReader.readS32();
210            const int32_t yOffset = fReader.readS32();
211            if (fBitmapDecoder != NULL && fBitmapDecoder(data, length, bitmap)) {
212                if (bitmap->width() == width && bitmap->height() == height) {
213#ifdef DEBUG_NON_DETERMINISTIC_ASSERT
214                    if (0 != xOffset || 0 != yOffset) {
215                        SkDebugf("SkOrderedReadBuffer::readBitmap: heights match,"
216                                 " but offset is not zero. \nInfo about the bitmap:"
217                                 "\n\tIndex: %d\n\tDimensions: [%d %d]\n\tEncoded"
218                                 " data size: %d\n\tOffset: (%d, %d)\n",
219                                 fDecodedBitmapIndex, width, height, length, xOffset,
220                                 yOffset);
221                    }
222#endif // DEBUG_NON_DETERMINISTIC_ASSERT
223                    // If the width and height match, there should be no offset.
224                    SkASSERT(0 == xOffset && 0 == yOffset);
225                    return;
226                }
227
228                // This case can only be reached if extractSubset was called, so
229                // the recorded width and height must be smaller than (or equal to
230                // the encoded width and height.
231                SkASSERT(width <= bitmap->width() && height <= bitmap->height());
232
233                SkBitmap subsetBm;
234                SkIRect subset = SkIRect::MakeXYWH(xOffset, yOffset, width, height);
235                if (bitmap->extractSubset(&subsetBm, subset)) {
236                    bitmap->swap(subsetBm);
237                    return;
238                }
239            }
240            // This bitmap was encoded when written, but we are unable to decode, possibly due to
241            // not having a decoder.
242            SkErrorInternals::SetError(kParseError_SkError,
243                                       "Could not decode bitmap. Resulting bitmap will be red.");
244        } else {
245            // A size of zero means the SkBitmap was simply flattened.
246            bitmap->unflatten(*this);
247            return;
248        }
249    }
250    // Could not read the SkBitmap. Use a placeholder bitmap.
251    bitmap->setConfig(SkBitmap::kARGB_8888_Config, width, height);
252    bitmap->allocPixels();
253    bitmap->eraseColor(SK_ColorRED);
254}
255
256SkTypeface* SkOrderedReadBuffer::readTypeface() {
257
258    uint32_t index = fReader.readU32();
259    if (0 == index || index > (unsigned)fTFCount) {
260        if (index) {
261            SkDebugf("====== typeface index %d\n", index);
262        }
263        return NULL;
264    } else {
265        SkASSERT(fTFArray);
266        return fTFArray[index - 1];
267    }
268}
269
270SkFlattenable* SkOrderedReadBuffer::readFlattenable(SkFlattenable::Type ft) {
271    //
272    // TODO: confirm that ft matches the factory we decide to use
273    //
274
275    SkFlattenable::Factory factory = NULL;
276
277    if (fFactoryCount > 0) {
278        int32_t index = fReader.readU32();
279        if (0 == index) {
280            return NULL; // writer failed to give us the flattenable
281        }
282        index -= 1;     // we stored the index-base-1
283        SkASSERT(index < fFactoryCount);
284        factory = fFactoryArray[index];
285    } else if (fFactoryTDArray) {
286        int32_t index = fReader.readU32();
287        if (0 == index) {
288            return NULL; // writer failed to give us the flattenable
289        }
290        index -= 1;     // we stored the index-base-1
291        factory = (*fFactoryTDArray)[index];
292    } else {
293        factory = (SkFlattenable::Factory)readFunctionPtr();
294        if (NULL == factory) {
295            return NULL; // writer failed to give us the flattenable
296        }
297    }
298
299    // if we get here, factory may still be null, but if that is the case, the
300    // failure was ours, not the writer.
301    SkFlattenable* obj = NULL;
302    uint32_t sizeRecorded = fReader.readU32();
303    if (factory) {
304        uint32_t offset = fReader.offset();
305        obj = (*factory)(*this);
306        // check that we read the amount we expected
307        uint32_t sizeRead = fReader.offset() - offset;
308        if (sizeRecorded != sizeRead) {
309            // we could try to fix up the offset...
310            sk_throw();
311        }
312    } else {
313        // we must skip the remaining data
314        fReader.skip(sizeRecorded);
315    }
316    return obj;
317}
318