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 "SkOrderedReadBuffer.h"
13 #include "SkTypeface.h"
15 SkOrderedReadBuffer::SkOrderedReadBuffer() : INHERITED() {
18 fBitmapStorage = NULL;
22 fFactoryTDArray = NULL;
25 fBitmapDecoder = NULL;
26 #ifdef DEBUG_NON_DETERMINISTIC_ASSERT
27 fDecodedBitmapIndex = -1;
28 #endif // DEBUG_NON_DETERMINISTIC_ASSERT
31 SkOrderedReadBuffer::SkOrderedReadBuffer(const void* data, size_t size) : INHERITED() {
32 fReader.setMemory(data, size);
35 fBitmapStorage = NULL;
39 fFactoryTDArray = NULL;
42 fBitmapDecoder = NULL;
43 #ifdef DEBUG_NON_DETERMINISTIC_ASSERT
44 fDecodedBitmapIndex = -1;
45 #endif // DEBUG_NON_DETERMINISTIC_ASSERT
48 SkOrderedReadBuffer::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);
54 fBitmapStorage = NULL;
58 fFactoryTDArray = NULL;
61 fBitmapDecoder = NULL;
62 #ifdef DEBUG_NON_DETERMINISTIC_ASSERT
63 fDecodedBitmapIndex = -1;
64 #endif // DEBUG_NON_DETERMINISTIC_ASSERT
67 SkOrderedReadBuffer::~SkOrderedReadBuffer() {
69 SkSafeUnref(fBitmapStorage);
72 bool SkOrderedReadBuffer::readBool() {
73 return fReader.readBool();
76 SkColor SkOrderedReadBuffer::readColor() {
77 return fReader.readInt();
80 SkFixed SkOrderedReadBuffer::readFixed() {
81 return fReader.readS32();
84 int32_t SkOrderedReadBuffer::readInt() {
85 return fReader.readInt();
88 SkScalar SkOrderedReadBuffer::readScalar() {
89 return fReader.readScalar();
92 uint32_t SkOrderedReadBuffer::readUInt() {
93 return fReader.readU32();
96 int32_t SkOrderedReadBuffer::read32() {
97 return fReader.readInt();
100 void SkOrderedReadBuffer::readString(SkString* string) {
102 const char* strContents = fReader.readString(&len);
103 string->set(strContents, len);
106 void* 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);
115 void SkOrderedReadBuffer::readPoint(SkPoint* point) {
116 point->fX = fReader.readScalar();
117 point->fY = fReader.readScalar();
120 void SkOrderedReadBuffer::readMatrix(SkMatrix* matrix) {
121 fReader.readMatrix(matrix);
124 void SkOrderedReadBuffer::readIRect(SkIRect* rect) {
125 memcpy(rect, fReader.skip(sizeof(SkIRect)), sizeof(SkIRect));
128 void SkOrderedReadBuffer::readRect(SkRect* rect) {
129 memcpy(rect, fReader.skip(sizeof(SkRect)), sizeof(SkRect));
132 void SkOrderedReadBuffer::readRegion(SkRegion* region) {
133 fReader.readRegion(region);
136 void SkOrderedReadBuffer::readPath(SkPath* path) {
137 fReader.readPath(path);
140 bool SkOrderedReadBuffer::readArray(void* value, size_t size, size_t elementSize) {
141 const size_t count = this->getArrayCount();
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);
149 fReader.skip(fReader.available());
153 bool SkOrderedReadBuffer::readByteArray(void* value, size_t size) {
154 return readArray(static_cast<unsigned char*>(value), size, sizeof(unsigned char));
157 bool SkOrderedReadBuffer::readColorArray(SkColor* colors, size_t size) {
158 return readArray(colors, size, sizeof(SkColor));
161 bool SkOrderedReadBuffer::readIntArray(int32_t* values, size_t size) {
162 return readArray(values, size, sizeof(int32_t));
165 bool SkOrderedReadBuffer::readPointArray(SkPoint* points, size_t size) {
166 return readArray(points, size, sizeof(SkPoint));
169 bool SkOrderedReadBuffer::readScalarArray(SkScalar* values, size_t size) {
170 return readArray(values, size, sizeof(SkScalar));
173 uint32_t SkOrderedReadBuffer::getArrayCount() {
174 return *(uint32_t*)fReader.peek();
177 void 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
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);
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.");
200 // The writer stored false, meaning the SkBitmap was not stored in an SkBitmapHeap.
201 const size_t length = this->readUInt();
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
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,
222 #endif // DEBUG_NON_DETERMINISTIC_ASSERT
223 // If the width and height match, there should be no offset.
224 SkASSERT(0 == xOffset && 0 == yOffset);
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 // FIXME (scroggo): This assert assumes that our decoder and the
232 // sources encoder agree on the width and height which may not
233 // always be the case. Removing until it can be investigated
235 //SkASSERT(width <= bitmap->width() && height <= bitmap->height());
238 SkIRect subset = SkIRect::MakeXYWH(xOffset, yOffset, width, height);
239 if (bitmap->extractSubset(&subsetBm, subset)) {
240 bitmap->swap(subsetBm);
244 // This bitmap was encoded when written, but we are unable to decode, possibly due to
245 // not having a decoder.
246 SkErrorInternals::SetError(kParseError_SkError,
247 "Could not decode bitmap. Resulting bitmap will be red.");
249 // A size of zero means the SkBitmap was simply flattened.
250 bitmap->unflatten(*this);
254 // Could not read the SkBitmap. Use a placeholder bitmap.
255 bitmap->allocPixels(SkImageInfo::MakeN32Premul(width, height));
256 bitmap->eraseColor(SK_ColorRED);
259 SkTypeface* SkOrderedReadBuffer::readTypeface() {
261 uint32_t index = fReader.readU32();
262 if (0 == index || index > (unsigned)fTFCount) {
264 SkDebugf("====== typeface index %d\n", index);
269 return fTFArray[index - 1];
273 SkFlattenable* SkOrderedReadBuffer::readFlattenable(SkFlattenable::Type ft) {
275 // TODO: confirm that ft matches the factory we decide to use
278 SkFlattenable::Factory factory = NULL;
280 if (fFactoryCount > 0) {
281 int32_t index = fReader.readU32();
283 return NULL; // writer failed to give us the flattenable
285 index -= 1; // we stored the index-base-1
286 SkASSERT(index < fFactoryCount);
287 factory = fFactoryArray[index];
288 } else if (fFactoryTDArray) {
289 int32_t index = fReader.readU32();
291 return NULL; // writer failed to give us the flattenable
293 index -= 1; // we stored the index-base-1
294 factory = (*fFactoryTDArray)[index];
296 factory = (SkFlattenable::Factory)readFunctionPtr();
297 if (NULL == factory) {
298 return NULL; // writer failed to give us the flattenable
302 // if we get here, factory may still be null, but if that is the case, the
303 // failure was ours, not the writer.
304 SkFlattenable* obj = NULL;
305 uint32_t sizeRecorded = fReader.readU32();
307 uint32_t offset = fReader.offset();
308 obj = (*factory)(*this);
309 // check that we read the amount we expected
310 uint32_t sizeRead = fReader.offset() - offset;
311 if (sizeRecorded != sizeRead) {
312 // we could try to fix up the offset...
316 // we must skip the remaining data
317 fReader.skip(sizeRecorded);