Home | History | Annotate | Download | only in core
      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 
     15 static 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 
     24 SkReadBuffer::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 
     42 SkReadBuffer::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 
     61 SkReadBuffer::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 
     82 SkReadBuffer::~SkReadBuffer() {
     83     sk_free(fMemoryPtr);
     84     SkSafeUnref(fBitmapStorage);
     85 }
     86 
     87 bool SkReadBuffer::readBool() {
     88     return fReader.readBool();
     89 }
     90 
     91 SkColor SkReadBuffer::readColor() {
     92     return fReader.readInt();
     93 }
     94 
     95 SkFixed SkReadBuffer::readFixed() {
     96     return fReader.readS32();
     97 }
     98 
     99 int32_t SkReadBuffer::readInt() {
    100     return fReader.readInt();
    101 }
    102 
    103 SkScalar SkReadBuffer::readScalar() {
    104     return fReader.readScalar();
    105 }
    106 
    107 uint32_t SkReadBuffer::readUInt() {
    108     return fReader.readU32();
    109 }
    110 
    111 int32_t SkReadBuffer::read32() {
    112     return fReader.readInt();
    113 }
    114 
    115 void SkReadBuffer::readString(SkString* string) {
    116     size_t len;
    117     const char* strContents = fReader.readString(&len);
    118     string->set(strContents, len);
    119 }
    120 
    121 void* 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 
    130 void SkReadBuffer::readPoint(SkPoint* point) {
    131     point->fX = fReader.readScalar();
    132     point->fY = fReader.readScalar();
    133 }
    134 
    135 void SkReadBuffer::readMatrix(SkMatrix* matrix) {
    136     fReader.readMatrix(matrix);
    137 }
    138 
    139 void SkReadBuffer::readIRect(SkIRect* rect) {
    140     memcpy(rect, fReader.skip(sizeof(SkIRect)), sizeof(SkIRect));
    141 }
    142 
    143 void SkReadBuffer::readRect(SkRect* rect) {
    144     memcpy(rect, fReader.skip(sizeof(SkRect)), sizeof(SkRect));
    145 }
    146 
    147 void SkReadBuffer::readRegion(SkRegion* region) {
    148     fReader.readRegion(region);
    149 }
    150 
    151 void SkReadBuffer::readPath(SkPath* path) {
    152     fReader.readPath(path);
    153 }
    154 
    155 bool 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 
    168 bool SkReadBuffer::readByteArray(void* value, size_t size) {
    169     return readArray(static_cast<unsigned char*>(value), size, sizeof(unsigned char));
    170 }
    171 
    172 bool SkReadBuffer::readColorArray(SkColor* colors, size_t size) {
    173     return readArray(colors, size, sizeof(SkColor));
    174 }
    175 
    176 bool SkReadBuffer::readIntArray(int32_t* values, size_t size) {
    177     return readArray(values, size, sizeof(int32_t));
    178 }
    179 
    180 bool SkReadBuffer::readPointArray(SkPoint* points, size_t size) {
    181     return readArray(points, size, sizeof(SkPoint));
    182 }
    183 
    184 bool SkReadBuffer::readScalarArray(SkScalar* values, size_t size) {
    185     return readArray(values, size, sizeof(SkScalar));
    186 }
    187 
    188 uint32_t SkReadBuffer::getArrayCount() {
    189     return *(uint32_t*)fReader.peek();
    190 }
    191 
    192 bool 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 
    277 SkTypeface* 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 
    291 SkFlattenable* 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  */
    344 void 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