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