3 * Copyright 2012 Google Inc.
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
10 #include "SkErrorInternals.h"
11 #include "SkReadBuffer.h"
13 #include "SkTypeface.h"
15 static uint32_t default_flags() {
17 flags |= SkReadBuffer::kScalarIsFloat_Flag;
18 if (8 == sizeof(void*)) {
19 flags |= SkReadBuffer::kPtrIs64Bit_Flag;
24 SkReadBuffer::SkReadBuffer() {
25 fFlags = default_flags();
29 fBitmapStorage = NULL;
33 fFactoryTDArray = NULL;
36 fBitmapDecoder = NULL;
37 #ifdef DEBUG_NON_DETERMINISTIC_ASSERT
38 fDecodedBitmapIndex = -1;
39 #endif // DEBUG_NON_DETERMINISTIC_ASSERT
42 SkReadBuffer::SkReadBuffer(const void* data, size_t size) {
43 fFlags = default_flags();
45 fReader.setMemory(data, size);
48 fBitmapStorage = NULL;
52 fFactoryTDArray = NULL;
55 fBitmapDecoder = NULL;
56 #ifdef DEBUG_NON_DETERMINISTIC_ASSERT
57 fDecodedBitmapIndex = -1;
58 #endif // DEBUG_NON_DETERMINISTIC_ASSERT
61 SkReadBuffer::SkReadBuffer(SkStream* stream) {
62 fFlags = default_flags();
64 const size_t length = stream->getLength();
65 fMemoryPtr = sk_malloc_throw(length);
66 stream->read(fMemoryPtr, length);
67 fReader.setMemory(fMemoryPtr, length);
69 fBitmapStorage = NULL;
73 fFactoryTDArray = NULL;
76 fBitmapDecoder = NULL;
77 #ifdef DEBUG_NON_DETERMINISTIC_ASSERT
78 fDecodedBitmapIndex = -1;
79 #endif // DEBUG_NON_DETERMINISTIC_ASSERT
82 SkReadBuffer::~SkReadBuffer() {
84 SkSafeUnref(fBitmapStorage);
87 bool SkReadBuffer::readBool() {
88 return fReader.readBool();
91 SkColor SkReadBuffer::readColor() {
92 return fReader.readInt();
95 SkFixed SkReadBuffer::readFixed() {
96 return fReader.readS32();
99 int32_t SkReadBuffer::readInt() {
100 return fReader.readInt();
103 SkScalar SkReadBuffer::readScalar() {
104 return fReader.readScalar();
107 uint32_t SkReadBuffer::readUInt() {
108 return fReader.readU32();
111 int32_t SkReadBuffer::read32() {
112 return fReader.readInt();
115 void SkReadBuffer::readString(SkString* string) {
117 const char* strContents = fReader.readString(&len);
118 string->set(strContents, len);
121 void* 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);
130 void SkReadBuffer::readPoint(SkPoint* point) {
131 point->fX = fReader.readScalar();
132 point->fY = fReader.readScalar();
135 void SkReadBuffer::readMatrix(SkMatrix* matrix) {
136 fReader.readMatrix(matrix);
139 void SkReadBuffer::readIRect(SkIRect* rect) {
140 memcpy(rect, fReader.skip(sizeof(SkIRect)), sizeof(SkIRect));
143 void SkReadBuffer::readRect(SkRect* rect) {
144 memcpy(rect, fReader.skip(sizeof(SkRect)), sizeof(SkRect));
147 void SkReadBuffer::readRegion(SkRegion* region) {
148 fReader.readRegion(region);
151 void SkReadBuffer::readPath(SkPath* path) {
152 fReader.readPath(path);
155 bool SkReadBuffer::readArray(void* value, size_t size, size_t elementSize) {
156 const size_t count = this->getArrayCount();
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);
164 fReader.skip(fReader.available());
168 bool SkReadBuffer::readByteArray(void* value, size_t size) {
169 return readArray(static_cast<unsigned char*>(value), size, sizeof(unsigned char));
172 bool SkReadBuffer::readColorArray(SkColor* colors, size_t size) {
173 return readArray(colors, size, sizeof(SkColor));
176 bool SkReadBuffer::readIntArray(int32_t* values, size_t size) {
177 return readArray(values, size, sizeof(int32_t));
180 bool SkReadBuffer::readPointArray(SkPoint* points, size_t size) {
181 return readArray(points, size, sizeof(SkPoint));
184 bool SkReadBuffer::readScalarArray(SkScalar* values, size_t size) {
185 return readArray(values, size, sizeof(SkScalar));
188 uint32_t SkReadBuffer::getArrayCount() {
189 return *(uint32_t*)fReader.peek();
192 bool 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
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);
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.");
215 // The writer stored false, meaning the SkBitmap was not stored in an SkBitmapHeap.
216 const size_t length = this->readUInt();
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
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,
237 #endif // DEBUG_NON_DETERMINISTIC_ASSERT
238 // If the width and height match, there should be no offset.
239 SkASSERT(0 == xOffset && 0 == yOffset);
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
250 //SkASSERT(width <= bitmap->width() && height <= bitmap->height());
253 SkIRect subset = SkIRect::MakeXYWH(xOffset, yOffset, width, height);
254 if (bitmap->extractSubset(&subsetBm, subset)) {
255 bitmap->swap(subsetBm);
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.");
264 // A size of zero means the SkBitmap was simply flattened.
265 if (this->isVersionLT(kNoMoreBitmapFlatten_Version)) {
267 tmp.legacyUnflatten(*this);
268 // just throw this guy away
270 if (SkBitmap::ReadRawPixels(this, bitmap)) {
276 // Could not read the SkBitmap. Use a placeholder bitmap.
277 bitmap->setInfo(SkImageInfo::MakeUnknown(width, height));
281 SkTypeface* SkReadBuffer::readTypeface() {
283 uint32_t index = fReader.readU32();
284 if (0 == index || index > (unsigned)fTFCount) {
286 SkDebugf("====== typeface index %d\n", index);
291 return fTFArray[index - 1];
295 SkFlattenable* SkReadBuffer::readFlattenable(SkFlattenable::Type ft) {
297 // TODO: confirm that ft matches the factory we decide to use
300 SkFlattenable::Factory factory = NULL;
302 if (fFactoryCount > 0) {
303 int32_t index = fReader.readU32();
305 return NULL; // writer failed to give us the flattenable
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();
313 return NULL; // writer failed to give us the flattenable
315 index -= 1; // we stored the index-base-1
316 factory = (*fFactoryTDArray)[index];
318 factory = (SkFlattenable::Factory)readFunctionPtr();
319 if (NULL == factory) {
320 return NULL; // writer failed to give us the flattenable
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();
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...
338 // we must skip the remaining data
339 fReader.skip(sizeRecorded);
345 * Needs to follow the same pattern as readFlattenable(), but explicitly skip whatever data
348 void SkReadBuffer::skipFlattenable() {
349 if (fFactoryCount > 0) {
350 if (0 == fReader.readU32()) {
353 } else if (fFactoryTDArray) {
354 if (0 == fReader.readU32()) {
358 if (NULL == this->readFunctionPtr()) {
362 uint32_t sizeRecorded = fReader.readU32();
363 fReader.skip(sizeRecorded);