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 red."); 263 } else { 264 // A size of zero means the SkBitmap was simply flattened. 265 if (this->isVersionLT(kNoMoreBitmapFlatten_Version)) { 266 SkBitmap tmp; 267 tmp.legacyUnflatten(*this); 268 // just throw this guy away 269 } else { 270 if (SkBitmap::ReadRawPixels(this, bitmap)) { 271 return true; 272 } 273 } 274 } 275 } 276 // Could not read the SkBitmap. Use a placeholder bitmap. 277 bitmap->setInfo(SkImageInfo::MakeUnknown(width, height)); 278 return false; 279} 280 281SkTypeface* SkReadBuffer::readTypeface() { 282 283 uint32_t index = fReader.readU32(); 284 if (0 == index || index > (unsigned)fTFCount) { 285 if (index) { 286 SkDebugf("====== typeface index %d\n", index); 287 } 288 return NULL; 289 } else { 290 SkASSERT(fTFArray); 291 return fTFArray[index - 1]; 292 } 293} 294 295SkFlattenable* SkReadBuffer::readFlattenable(SkFlattenable::Type ft) { 296 // 297 // TODO: confirm that ft matches the factory we decide to use 298 // 299 300 SkFlattenable::Factory factory = NULL; 301 302 if (fFactoryCount > 0) { 303 int32_t index = fReader.readU32(); 304 if (0 == index) { 305 return NULL; // writer failed to give us the flattenable 306 } 307 index -= 1; // we stored the index-base-1 308 SkASSERT(index < fFactoryCount); 309 factory = fFactoryArray[index]; 310 } else if (fFactoryTDArray) { 311 int32_t index = fReader.readU32(); 312 if (0 == index) { 313 return NULL; // writer failed to give us the flattenable 314 } 315 index -= 1; // we stored the index-base-1 316 factory = (*fFactoryTDArray)[index]; 317 } else { 318 factory = (SkFlattenable::Factory)readFunctionPtr(); 319 if (NULL == factory) { 320 return NULL; // writer failed to give us the flattenable 321 } 322 } 323 324 // if we get here, factory may still be null, but if that is the case, the 325 // failure was ours, not the writer. 326 SkFlattenable* obj = NULL; 327 uint32_t sizeRecorded = fReader.readU32(); 328 if (factory) { 329 size_t offset = fReader.offset(); 330 obj = (*factory)(*this); 331 // check that we read the amount we expected 332 size_t sizeRead = fReader.offset() - offset; 333 if (sizeRecorded != sizeRead) { 334 // we could try to fix up the offset... 335 sk_throw(); 336 } 337 } else { 338 // we must skip the remaining data 339 fReader.skip(sizeRecorded); 340 } 341 return obj; 342} 343 344/** 345 * Needs to follow the same pattern as readFlattenable(), but explicitly skip whatever data 346 * has been written. 347 */ 348void SkReadBuffer::skipFlattenable() { 349 if (fFactoryCount > 0) { 350 if (0 == fReader.readU32()) { 351 return; 352 } 353 } else if (fFactoryTDArray) { 354 if (0 == fReader.readU32()) { 355 return; 356 } 357 } else { 358 if (NULL == this->readFunctionPtr()) { 359 return; 360 } 361 } 362 uint32_t sizeRecorded = fReader.readU32(); 363 fReader.skip(sizeRecorded); 364} 365