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