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 "SkReadBuffer.h" 12#include "SkStream.h" 13#include "SkTypeface.h" 14 15static uint32_t default_flags() { 16 uint32_t flags = 0; 17 flags |= SkReadBuffer::kScalarIsFloat_Flag; 18 if (8 == sizeof(void*)) { 19 flags |= SkReadBuffer::kPtrIs64Bit_Flag; 20 } 21 return flags; 22} 23 24SkReadBuffer::SkReadBuffer() { 25 fFlags = default_flags(); 26 fVersion = 0; 27 fMemoryPtr = NULL; 28 29 fBitmapStorage = NULL; 30 fTFArray = NULL; 31 fTFCount = 0; 32 33 fFactoryTDArray = NULL; 34 fFactoryArray = NULL; 35 fFactoryCount = 0; 36 fBitmapDecoder = NULL; 37#ifdef DEBUG_NON_DETERMINISTIC_ASSERT 38 fDecodedBitmapIndex = -1; 39#endif // DEBUG_NON_DETERMINISTIC_ASSERT 40} 41 42SkReadBuffer::SkReadBuffer(const void* data, size_t size) { 43 fFlags = default_flags(); 44 fVersion = 0; 45 fReader.setMemory(data, size); 46 fMemoryPtr = NULL; 47 48 fBitmapStorage = NULL; 49 fTFArray = NULL; 50 fTFCount = 0; 51 52 fFactoryTDArray = NULL; 53 fFactoryArray = NULL; 54 fFactoryCount = 0; 55 fBitmapDecoder = NULL; 56#ifdef DEBUG_NON_DETERMINISTIC_ASSERT 57 fDecodedBitmapIndex = -1; 58#endif // DEBUG_NON_DETERMINISTIC_ASSERT 59} 60 61SkReadBuffer::SkReadBuffer(SkStream* stream) { 62 fFlags = default_flags(); 63 fVersion = 0; 64 const size_t length = stream->getLength(); 65 fMemoryPtr = sk_malloc_throw(length); 66 stream->read(fMemoryPtr, length); 67 fReader.setMemory(fMemoryPtr, length); 68 69 fBitmapStorage = NULL; 70 fTFArray = NULL; 71 fTFCount = 0; 72 73 fFactoryTDArray = NULL; 74 fFactoryArray = NULL; 75 fFactoryCount = 0; 76 fBitmapDecoder = NULL; 77#ifdef DEBUG_NON_DETERMINISTIC_ASSERT 78 fDecodedBitmapIndex = -1; 79#endif // DEBUG_NON_DETERMINISTIC_ASSERT 80} 81 82SkReadBuffer::~SkReadBuffer() { 83 sk_free(fMemoryPtr); 84 SkSafeUnref(fBitmapStorage); 85} 86 87bool SkReadBuffer::readBool() { 88 return fReader.readBool(); 89} 90 91SkColor SkReadBuffer::readColor() { 92 return fReader.readInt(); 93} 94 95SkFixed SkReadBuffer::readFixed() { 96 return fReader.readS32(); 97} 98 99int32_t SkReadBuffer::readInt() { 100 return fReader.readInt(); 101} 102 103SkScalar SkReadBuffer::readScalar() { 104 return fReader.readScalar(); 105} 106 107uint32_t SkReadBuffer::readUInt() { 108 return fReader.readU32(); 109} 110 111int32_t SkReadBuffer::read32() { 112 return fReader.readInt(); 113} 114 115void SkReadBuffer::readString(SkString* string) { 116 size_t len; 117 const char* strContents = fReader.readString(&len); 118 string->set(strContents, len); 119} 120 121void* 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); 127 return data; 128} 129 130void SkReadBuffer::readPoint(SkPoint* point) { 131 point->fX = fReader.readScalar(); 132 point->fY = fReader.readScalar(); 133} 134 135void SkReadBuffer::readMatrix(SkMatrix* matrix) { 136 fReader.readMatrix(matrix); 137} 138 139void SkReadBuffer::readIRect(SkIRect* rect) { 140 memcpy(rect, fReader.skip(sizeof(SkIRect)), sizeof(SkIRect)); 141} 142 143void SkReadBuffer::readRect(SkRect* rect) { 144 memcpy(rect, fReader.skip(sizeof(SkRect)), sizeof(SkRect)); 145} 146 147void SkReadBuffer::readRegion(SkRegion* region) { 148 fReader.readRegion(region); 149} 150 151void SkReadBuffer::readPath(SkPath* path) { 152 fReader.readPath(path); 153} 154 155bool SkReadBuffer::readArray(void* value, size_t size, size_t elementSize) { 156 const size_t count = this->getArrayCount(); 157 if (count == size) { 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); 161 return true; 162 } 163 SkASSERT(false); 164 fReader.skip(fReader.available()); 165 return false; 166} 167 168bool SkReadBuffer::readByteArray(void* value, size_t size) { 169 return readArray(static_cast<unsigned char*>(value), size, sizeof(unsigned char)); 170} 171 172bool SkReadBuffer::readColorArray(SkColor* colors, size_t size) { 173 return readArray(colors, size, sizeof(SkColor)); 174} 175 176bool SkReadBuffer::readIntArray(int32_t* values, size_t size) { 177 return readArray(values, size, sizeof(int32_t)); 178} 179 180bool SkReadBuffer::readPointArray(SkPoint* points, size_t size) { 181 return readArray(points, size, sizeof(SkPoint)); 182} 183 184bool SkReadBuffer::readScalarArray(SkScalar* values, size_t size) { 185 return readArray(values, size, sizeof(SkScalar)); 186} 187 188uint32_t SkReadBuffer::getArrayCount() { 189 return *(uint32_t*)fReader.peek(); 190} 191 192bool 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 196 // writing. 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); 205 return true; 206 } else { 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."); 213 } 214 } else { 215 // The writer stored false, meaning the SkBitmap was not stored in an SkBitmapHeap. 216 const size_t length = this->readUInt(); 217 if (length > 0) { 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 222 // offset. 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, 235 yOffset); 236 } 237#endif // DEBUG_NON_DETERMINISTIC_ASSERT 238 // If the width and height match, there should be no offset. 239 SkASSERT(0 == xOffset && 0 == yOffset); 240 return true; 241 } 242 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 249 // further. 250 //SkASSERT(width <= bitmap->width() && height <= bitmap->height()); 251 252 SkBitmap subsetBm; 253 SkIRect subset = SkIRect::MakeXYWH(xOffset, yOffset, width, height); 254 if (bitmap->extractSubset(&subsetBm, subset)) { 255 bitmap->swap(subsetBm); 256 return true; 257 } 258 } 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 empty."); 263 // Even though we weren't able to decode the pixels, the readbuffer should still be 264 // intact, so we return true with an empty bitmap, so we don't force an abort of the 265 // larger deserialize. 266 bitmap->setInfo(SkImageInfo::MakeUnknown(width, height)); 267 return true; 268 } else if (SkBitmap::ReadRawPixels(this, bitmap)) { 269 return true; 270 } 271 } 272 // Could not read the SkBitmap. Use a placeholder bitmap. 273 bitmap->setInfo(SkImageInfo::MakeUnknown(width, height)); 274 return false; 275} 276 277SkTypeface* SkReadBuffer::readTypeface() { 278 279 uint32_t index = fReader.readU32(); 280 if (0 == index || index > (unsigned)fTFCount) { 281 if (index) { 282 SkDebugf("====== typeface index %d\n", index); 283 } 284 return NULL; 285 } else { 286 SkASSERT(fTFArray); 287 return fTFArray[index - 1]; 288 } 289} 290 291SkFlattenable* SkReadBuffer::readFlattenable(SkFlattenable::Type ft) { 292 // 293 // TODO: confirm that ft matches the factory we decide to use 294 // 295 296 SkFlattenable::Factory factory = NULL; 297 298 if (fFactoryCount > 0) { 299 int32_t index = fReader.readU32(); 300 if (0 == index) { 301 return NULL; // writer failed to give us the flattenable 302 } 303 index -= 1; // we stored the index-base-1 304 SkASSERT(index < fFactoryCount); 305 factory = fFactoryArray[index]; 306 } else if (fFactoryTDArray) { 307 int32_t index = fReader.readU32(); 308 if (0 == index) { 309 return NULL; // writer failed to give us the flattenable 310 } 311 index -= 1; // we stored the index-base-1 312 factory = (*fFactoryTDArray)[index]; 313 } else { 314 factory = (SkFlattenable::Factory)readFunctionPtr(); 315 if (NULL == factory) { 316 return NULL; // writer failed to give us the flattenable 317 } 318 } 319 320 // if we get here, factory may still be null, but if that is the case, the 321 // failure was ours, not the writer. 322 SkFlattenable* obj = NULL; 323 uint32_t sizeRecorded = fReader.readU32(); 324 if (factory) { 325 size_t offset = fReader.offset(); 326 obj = (*factory)(*this); 327 // check that we read the amount we expected 328 size_t sizeRead = fReader.offset() - offset; 329 if (sizeRecorded != sizeRead) { 330 // we could try to fix up the offset... 331 sk_throw(); 332 } 333 } else { 334 // we must skip the remaining data 335 fReader.skip(sizeRecorded); 336 } 337 return obj; 338} 339 340/** 341 * Needs to follow the same pattern as readFlattenable(), but explicitly skip whatever data 342 * has been written. 343 */ 344void SkReadBuffer::skipFlattenable() { 345 if (fFactoryCount > 0) { 346 if (0 == fReader.readU32()) { 347 return; 348 } 349 } else if (fFactoryTDArray) { 350 if (0 == fReader.readU32()) { 351 return; 352 } 353 } else { 354 if (NULL == this->readFunctionPtr()) { 355 return; 356 } 357 } 358 uint32_t sizeRecorded = fReader.readU32(); 359 fReader.skip(sizeRecorded); 360} 361