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();
30 fBitmapStorage = NULL;
34 fFactoryTDArray = NULL;
37 fBitmapDecoder = NULL;
38 #ifdef DEBUG_NON_DETERMINISTIC_ASSERT
39 fDecodedBitmapIndex = -1;
40 #endif // DEBUG_NON_DETERMINISTIC_ASSERT
43 SkReadBuffer::SkReadBuffer(const void* data, size_t size) {
44 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();
63 const size_t length = stream->getLength();
64 fMemoryPtr = sk_malloc_throw(length);
65 stream->read(fMemoryPtr, length);
66 fReader.setMemory(fMemoryPtr, length);
68 fBitmapStorage = NULL;
72 fFactoryTDArray = NULL;
75 fBitmapDecoder = NULL;
76 #ifdef DEBUG_NON_DETERMINISTIC_ASSERT
77 fDecodedBitmapIndex = -1;
78 #endif // DEBUG_NON_DETERMINISTIC_ASSERT
81 SkReadBuffer::~SkReadBuffer() {
83 SkSafeUnref(fBitmapStorage);
86 bool SkReadBuffer::readBool() {
87 return fReader.readBool();
90 SkColor SkReadBuffer::readColor() {
91 return fReader.readInt();
94 SkFixed SkReadBuffer::readFixed() {
95 return fReader.readS32();
98 int32_t SkReadBuffer::readInt() {
99 return fReader.readInt();
102 SkScalar SkReadBuffer::readScalar() {
103 return fReader.readScalar();
106 uint32_t SkReadBuffer::readUInt() {
107 return fReader.readU32();
110 int32_t SkReadBuffer::read32() {
111 return fReader.readInt();
114 void SkReadBuffer::readString(SkString* string) {
116 const char* strContents = fReader.readString(&len);
117 string->set(strContents, len);
120 void* SkReadBuffer::readEncodedString(size_t* length, SkPaint::TextEncoding encoding) {
121 SkDEBUGCODE(int32_t encodingType = ) fReader.readInt();
122 SkASSERT(encodingType == encoding);
123 *length = fReader.readInt();
124 void* data = sk_malloc_throw(*length);
125 memcpy(data, fReader.skip(SkAlign4(*length)), *length);
129 void SkReadBuffer::readPoint(SkPoint* point) {
130 point->fX = fReader.readScalar();
131 point->fY = fReader.readScalar();
134 void SkReadBuffer::readMatrix(SkMatrix* matrix) {
135 fReader.readMatrix(matrix);
138 void SkReadBuffer::readIRect(SkIRect* rect) {
139 memcpy(rect, fReader.skip(sizeof(SkIRect)), sizeof(SkIRect));
142 void SkReadBuffer::readRect(SkRect* rect) {
143 memcpy(rect, fReader.skip(sizeof(SkRect)), sizeof(SkRect));
146 void SkReadBuffer::readRegion(SkRegion* region) {
147 fReader.readRegion(region);
150 void SkReadBuffer::readPath(SkPath* path) {
151 fReader.readPath(path);
154 bool SkReadBuffer::readArray(void* value, size_t size, size_t elementSize) {
155 const size_t count = this->getArrayCount();
157 (void)fReader.skip(sizeof(uint32_t)); // Skip array count
158 const size_t byteLength = count * elementSize;
159 memcpy(value, fReader.skip(SkAlign4(byteLength)), byteLength);
163 fReader.skip(fReader.available());
167 bool SkReadBuffer::readByteArray(void* value, size_t size) {
168 return readArray(static_cast<unsigned char*>(value), size, sizeof(unsigned char));
171 bool SkReadBuffer::readColorArray(SkColor* colors, size_t size) {
172 return readArray(colors, size, sizeof(SkColor));
175 bool SkReadBuffer::readIntArray(int32_t* values, size_t size) {
176 return readArray(values, size, sizeof(int32_t));
179 bool SkReadBuffer::readPointArray(SkPoint* points, size_t size) {
180 return readArray(points, size, sizeof(SkPoint));
183 bool SkReadBuffer::readScalarArray(SkScalar* values, size_t size) {
184 return readArray(values, size, sizeof(SkScalar));
187 uint32_t SkReadBuffer::getArrayCount() {
188 return *(uint32_t*)fReader.peek();
191 void SkReadBuffer::readBitmap(SkBitmap* bitmap) {
192 const int width = this->readInt();
193 const int height = this->readInt();
194 // The writer stored a boolean value to determine whether an SkBitmapHeap was used during
196 if (this->readBool()) {
197 // An SkBitmapHeap was used for writing. Read the index from the stream and find the
198 // corresponding SkBitmap in fBitmapStorage.
199 const uint32_t index = fReader.readU32();
200 fReader.readU32(); // bitmap generation ID (see SkWriteBuffer::writeBitmap)
201 if (fBitmapStorage) {
202 *bitmap = *fBitmapStorage->getBitmap(index);
203 fBitmapStorage->releaseRef(index);
206 // The bitmap was stored in a heap, but there is no way to access it. Set an error and
207 // fall through to use a place holder bitmap.
208 SkErrorInternals::SetError(kParseError_SkError, "SkWriteBuffer::writeBitmap "
209 "stored the SkBitmap in an SkBitmapHeap, but "
210 "SkReadBuffer has no SkBitmapHeapReader to "
211 "retrieve the SkBitmap.");
214 // The writer stored false, meaning the SkBitmap was not stored in an SkBitmapHeap.
215 const size_t length = this->readUInt();
217 #ifdef DEBUG_NON_DETERMINISTIC_ASSERT
218 fDecodedBitmapIndex++;
219 #endif // DEBUG_NON_DETERMINISTIC_ASSERT
220 // A non-zero size means the SkBitmap was encoded. Read the data and pixel
222 const void* data = this->skip(length);
223 const int32_t xOffset = fReader.readS32();
224 const int32_t yOffset = fReader.readS32();
225 if (fBitmapDecoder != NULL && fBitmapDecoder(data, length, bitmap)) {
226 if (bitmap->width() == width && bitmap->height() == height) {
227 #ifdef DEBUG_NON_DETERMINISTIC_ASSERT
228 if (0 != xOffset || 0 != yOffset) {
229 SkDebugf("SkReadBuffer::readBitmap: heights match,"
230 " but offset is not zero. \nInfo about the bitmap:"
231 "\n\tIndex: %d\n\tDimensions: [%d %d]\n\tEncoded"
232 " data size: %d\n\tOffset: (%d, %d)\n",
233 fDecodedBitmapIndex, width, height, length, xOffset,
236 #endif // DEBUG_NON_DETERMINISTIC_ASSERT
237 // If the width and height match, there should be no offset.
238 SkASSERT(0 == xOffset && 0 == yOffset);
242 // This case can only be reached if extractSubset was called, so
243 // the recorded width and height must be smaller than or equal to
244 // the encoded width and height.
245 // FIXME (scroggo): This assert assumes that our decoder and the
246 // sources encoder agree on the width and height which may not
247 // always be the case. Removing until it can be investigated
249 //SkASSERT(width <= bitmap->width() && height <= bitmap->height());
252 SkIRect subset = SkIRect::MakeXYWH(xOffset, yOffset, width, height);
253 if (bitmap->extractSubset(&subsetBm, subset)) {
254 bitmap->swap(subsetBm);
258 // This bitmap was encoded when written, but we are unable to decode, possibly due to
259 // not having a decoder.
260 SkErrorInternals::SetError(kParseError_SkError,
261 "Could not decode bitmap. Resulting bitmap will be red.");
263 // A size of zero means the SkBitmap was simply flattened.
264 bitmap->unflatten(*this);
268 // Could not read the SkBitmap. Use a placeholder bitmap.
269 bitmap->allocPixels(SkImageInfo::MakeN32Premul(width, height));
270 bitmap->eraseColor(SK_ColorRED);
273 SkTypeface* SkReadBuffer::readTypeface() {
275 uint32_t index = fReader.readU32();
276 if (0 == index || index > (unsigned)fTFCount) {
278 SkDebugf("====== typeface index %d\n", index);
283 return fTFArray[index - 1];
287 SkFlattenable* SkReadBuffer::readFlattenable(SkFlattenable::Type ft) {
289 // TODO: confirm that ft matches the factory we decide to use
292 SkFlattenable::Factory factory = NULL;
294 if (fFactoryCount > 0) {
295 int32_t index = fReader.readU32();
297 return NULL; // writer failed to give us the flattenable
299 index -= 1; // we stored the index-base-1
300 SkASSERT(index < fFactoryCount);
301 factory = fFactoryArray[index];
302 } else if (fFactoryTDArray) {
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 factory = (*fFactoryTDArray)[index];
310 factory = (SkFlattenable::Factory)readFunctionPtr();
311 if (NULL == factory) {
312 return NULL; // writer failed to give us the flattenable
316 // if we get here, factory may still be null, but if that is the case, the
317 // failure was ours, not the writer.
318 SkFlattenable* obj = NULL;
319 uint32_t sizeRecorded = fReader.readU32();
321 uint32_t offset = fReader.offset();
322 obj = (*factory)(*this);
323 // check that we read the amount we expected
324 uint32_t sizeRead = fReader.offset() - offset;
325 if (sizeRecorded != sizeRead) {
326 // we could try to fix up the offset...
330 // we must skip the remaining data
331 fReader.skip(sizeRecorded);