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 #ifdef SK_SCALAR_IS_FLOAT
18 flags |= SkReadBuffer::kScalarIsFloat_Flag;
20 if (8 == sizeof(void*)) {
21 flags |= SkReadBuffer::kPtrIs64Bit_Flag;
26 SkReadBuffer::SkReadBuffer() {
27 fFlags = default_flags();
31 fBitmapStorage = NULL;
35 fFactoryTDArray = NULL;
38 fBitmapDecoder = NULL;
39 #ifdef DEBUG_NON_DETERMINISTIC_ASSERT
40 fDecodedBitmapIndex = -1;
41 #endif // DEBUG_NON_DETERMINISTIC_ASSERT
44 SkReadBuffer::SkReadBuffer(const void* data, size_t size) {
45 fFlags = default_flags();
47 fReader.setMemory(data, size);
50 fBitmapStorage = NULL;
54 fFactoryTDArray = NULL;
57 fBitmapDecoder = NULL;
58 #ifdef DEBUG_NON_DETERMINISTIC_ASSERT
59 fDecodedBitmapIndex = -1;
60 #endif // DEBUG_NON_DETERMINISTIC_ASSERT
63 SkReadBuffer::SkReadBuffer(SkStream* stream) {
64 fFlags = default_flags();
66 const size_t length = stream->getLength();
67 fMemoryPtr = sk_malloc_throw(length);
68 stream->read(fMemoryPtr, length);
69 fReader.setMemory(fMemoryPtr, length);
71 fBitmapStorage = NULL;
75 fFactoryTDArray = NULL;
78 fBitmapDecoder = NULL;
79 #ifdef DEBUG_NON_DETERMINISTIC_ASSERT
80 fDecodedBitmapIndex = -1;
81 #endif // DEBUG_NON_DETERMINISTIC_ASSERT
84 SkReadBuffer::~SkReadBuffer() {
86 SkSafeUnref(fBitmapStorage);
89 bool SkReadBuffer::readBool() {
90 return fReader.readBool();
93 SkColor SkReadBuffer::readColor() {
94 return fReader.readInt();
97 SkFixed SkReadBuffer::readFixed() {
98 return fReader.readS32();
101 int32_t SkReadBuffer::readInt() {
102 return fReader.readInt();
105 SkScalar SkReadBuffer::readScalar() {
106 return fReader.readScalar();
109 uint32_t SkReadBuffer::readUInt() {
110 return fReader.readU32();
113 int32_t SkReadBuffer::read32() {
114 return fReader.readInt();
117 void SkReadBuffer::readString(SkString* string) {
119 const char* strContents = fReader.readString(&len);
120 string->set(strContents, len);
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);
132 void SkReadBuffer::readPoint(SkPoint* point) {
133 point->fX = fReader.readScalar();
134 point->fY = fReader.readScalar();
137 void SkReadBuffer::readMatrix(SkMatrix* matrix) {
138 fReader.readMatrix(matrix);
141 void SkReadBuffer::readIRect(SkIRect* rect) {
142 memcpy(rect, fReader.skip(sizeof(SkIRect)), sizeof(SkIRect));
145 void SkReadBuffer::readRect(SkRect* rect) {
146 memcpy(rect, fReader.skip(sizeof(SkRect)), sizeof(SkRect));
149 void SkReadBuffer::readRegion(SkRegion* region) {
150 fReader.readRegion(region);
153 void SkReadBuffer::readPath(SkPath* path) {
154 fReader.readPath(path);
157 bool SkReadBuffer::readArray(void* value, size_t size, size_t elementSize) {
158 const size_t count = this->getArrayCount();
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);
166 fReader.skip(fReader.available());
170 bool SkReadBuffer::readByteArray(void* value, size_t size) {
171 return readArray(static_cast<unsigned char*>(value), size, sizeof(unsigned char));
174 bool SkReadBuffer::readColorArray(SkColor* colors, size_t size) {
175 return readArray(colors, size, sizeof(SkColor));
178 bool SkReadBuffer::readIntArray(int32_t* values, size_t size) {
179 return readArray(values, size, sizeof(int32_t));
182 bool SkReadBuffer::readPointArray(SkPoint* points, size_t size) {
183 return readArray(points, size, sizeof(SkPoint));
186 bool SkReadBuffer::readScalarArray(SkScalar* values, size_t size) {
187 return readArray(values, size, sizeof(SkScalar));
190 uint32_t SkReadBuffer::getArrayCount() {
191 return *(uint32_t*)fReader.peek();
194 void 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
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 = fReader.readU32();
203 fReader.readU32(); // bitmap generation ID (see SkWriteBuffer::writeBitmap)
204 if (fBitmapStorage) {
205 *bitmap = *fBitmapStorage->getBitmap(index);
206 fBitmapStorage->releaseRef(index);
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.");
217 // The writer stored false, meaning the SkBitmap was not stored in an SkBitmapHeap.
218 const size_t length = this->readUInt();
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
225 const void* data = this->skip(length);
226 const int32_t xOffset = fReader.readS32();
227 const int32_t yOffset = fReader.readS32();
228 if (fBitmapDecoder != NULL && 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,
239 #endif // DEBUG_NON_DETERMINISTIC_ASSERT
240 // If the width and height match, there should be no offset.
241 SkASSERT(0 == xOffset && 0 == yOffset);
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
252 //SkASSERT(width <= bitmap->width() && height <= bitmap->height());
255 SkIRect subset = SkIRect::MakeXYWH(xOffset, yOffset, width, height);
256 if (bitmap->extractSubset(&subsetBm, subset)) {
257 bitmap->swap(subsetBm);
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 red.");
266 // A size of zero means the SkBitmap was simply flattened.
267 bitmap->unflatten(*this);
271 // Could not read the SkBitmap. Use a placeholder bitmap.
272 bitmap->allocPixels(SkImageInfo::MakeN32Premul(width, height));
273 bitmap->eraseColor(SK_ColorRED);
276 SkTypeface* SkReadBuffer::readTypeface() {
278 uint32_t index = fReader.readU32();
279 if (0 == index || index > (unsigned)fTFCount) {
281 SkDebugf("====== typeface index %d\n", index);
286 return fTFArray[index - 1];
290 SkFlattenable* SkReadBuffer::readFlattenable(SkFlattenable::Type ft) {
292 // TODO: confirm that ft matches the factory we decide to use
295 SkFlattenable::Factory factory = NULL;
297 if (fFactoryCount > 0) {
298 int32_t index = fReader.readU32();
300 return NULL; // writer failed to give us the flattenable
302 index -= 1; // we stored the index-base-1
303 SkASSERT(index < fFactoryCount);
304 factory = fFactoryArray[index];
305 } else if (fFactoryTDArray) {
306 int32_t index = fReader.readU32();
308 return NULL; // writer failed to give us the flattenable
310 index -= 1; // we stored the index-base-1
311 factory = (*fFactoryTDArray)[index];
313 factory = (SkFlattenable::Factory)readFunctionPtr();
314 if (NULL == factory) {
315 return NULL; // writer failed to give us the flattenable
319 // if we get here, factory may still be null, but if that is the case, the
320 // failure was ours, not the writer.
321 SkFlattenable* obj = NULL;
322 uint32_t sizeRecorded = fReader.readU32();
324 size_t offset = fReader.offset();
325 obj = (*factory)(*this);
326 // check that we read the amount we expected
327 size_t sizeRead = fReader.offset() - offset;
328 if (sizeRecorded != sizeRead) {
329 // we could try to fix up the offset...
333 // we must skip the remaining data
334 fReader.skip(sizeRecorded);