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 "SkImage.h"
     12 #include "SkImageGenerator.h"
     13 #include "SkReadBuffer.h"
     14 #include "SkStream.h"
     15 #include "SkTypeface.h"
     16 
     17 static uint32_t default_flags() {
     18     uint32_t flags = 0;
     19     flags |= SkReadBuffer::kScalarIsFloat_Flag;
     20     if (8 == sizeof(void*)) {
     21         flags |= SkReadBuffer::kPtrIs64Bit_Flag;
     22     }
     23     return flags;
     24 }
     25 
     26 SkReadBuffer::SkReadBuffer() {
     27     fFlags = default_flags();
     28     fVersion = 0;
     29     fMemoryPtr = nullptr;
     30 
     31     fBitmapStorage = nullptr;
     32     fTFArray = nullptr;
     33     fTFCount = 0;
     34 
     35     fFactoryTDArray = nullptr;
     36     fFactoryArray = nullptr;
     37     fFactoryCount = 0;
     38     fBitmapDecoder = nullptr;
     39 #ifdef DEBUG_NON_DETERMINISTIC_ASSERT
     40     fDecodedBitmapIndex = -1;
     41 #endif // DEBUG_NON_DETERMINISTIC_ASSERT
     42 }
     43 
     44 SkReadBuffer::SkReadBuffer(const void* data, size_t size) {
     45     fFlags = default_flags();
     46     fVersion = 0;
     47     fReader.setMemory(data, size);
     48     fMemoryPtr = nullptr;
     49 
     50     fBitmapStorage = nullptr;
     51     fTFArray = nullptr;
     52     fTFCount = 0;
     53 
     54     fFactoryTDArray = nullptr;
     55     fFactoryArray = nullptr;
     56     fFactoryCount = 0;
     57     fBitmapDecoder = nullptr;
     58 #ifdef DEBUG_NON_DETERMINISTIC_ASSERT
     59     fDecodedBitmapIndex = -1;
     60 #endif // DEBUG_NON_DETERMINISTIC_ASSERT
     61 }
     62 
     63 SkReadBuffer::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 = nullptr;
     72     fTFArray = nullptr;
     73     fTFCount = 0;
     74 
     75     fFactoryTDArray = nullptr;
     76     fFactoryArray = nullptr;
     77     fFactoryCount = 0;
     78     fBitmapDecoder = nullptr;
     79 #ifdef DEBUG_NON_DETERMINISTIC_ASSERT
     80     fDecodedBitmapIndex = -1;
     81 #endif // DEBUG_NON_DETERMINISTIC_ASSERT
     82 }
     83 
     84 SkReadBuffer::~SkReadBuffer() {
     85     sk_free(fMemoryPtr);
     86     SkSafeUnref(fBitmapStorage);
     87 }
     88 
     89 bool SkReadBuffer::readBool() {
     90     return fReader.readBool();
     91 }
     92 
     93 SkColor SkReadBuffer::readColor() {
     94     return fReader.readInt();
     95 }
     96 
     97 SkFixed SkReadBuffer::readFixed() {
     98     return fReader.readS32();
     99 }
    100 
    101 int32_t SkReadBuffer::readInt() {
    102     return fReader.readInt();
    103 }
    104 
    105 SkScalar SkReadBuffer::readScalar() {
    106     return fReader.readScalar();
    107 }
    108 
    109 uint32_t SkReadBuffer::readUInt() {
    110     return fReader.readU32();
    111 }
    112 
    113 int32_t SkReadBuffer::read32() {
    114     return fReader.readInt();
    115 }
    116 
    117 void SkReadBuffer::readString(SkString* string) {
    118     size_t len;
    119     const char* strContents = fReader.readString(&len);
    120     string->set(strContents, len);
    121 }
    122 
    123 void* 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 
    132 void SkReadBuffer::readPoint(SkPoint* point) {
    133     point->fX = fReader.readScalar();
    134     point->fY = fReader.readScalar();
    135 }
    136 
    137 void SkReadBuffer::readMatrix(SkMatrix* matrix) {
    138     fReader.readMatrix(matrix);
    139 }
    140 
    141 void SkReadBuffer::readIRect(SkIRect* rect) {
    142     memcpy(rect, fReader.skip(sizeof(SkIRect)), sizeof(SkIRect));
    143 }
    144 
    145 void SkReadBuffer::readRect(SkRect* rect) {
    146     memcpy(rect, fReader.skip(sizeof(SkRect)), sizeof(SkRect));
    147 }
    148 
    149 void SkReadBuffer::readRegion(SkRegion* region) {
    150     fReader.readRegion(region);
    151 }
    152 
    153 void SkReadBuffer::readPath(SkPath* path) {
    154     fReader.readPath(path);
    155 }
    156 
    157 bool 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 
    170 bool SkReadBuffer::readByteArray(void* value, size_t size) {
    171     return readArray(static_cast<unsigned char*>(value), size, sizeof(unsigned char));
    172 }
    173 
    174 bool SkReadBuffer::readColorArray(SkColor* colors, size_t size) {
    175     return readArray(colors, size, sizeof(SkColor));
    176 }
    177 
    178 bool SkReadBuffer::readIntArray(int32_t* values, size_t size) {
    179     return readArray(values, size, sizeof(int32_t));
    180 }
    181 
    182 bool SkReadBuffer::readPointArray(SkPoint* points, size_t size) {
    183     return readArray(points, size, sizeof(SkPoint));
    184 }
    185 
    186 bool SkReadBuffer::readScalarArray(SkScalar* values, size_t size) {
    187     return readArray(values, size, sizeof(SkScalar));
    188 }
    189 
    190 uint32_t SkReadBuffer::getArrayCount() {
    191     return *(uint32_t*)fReader.peek();
    192 }
    193 
    194 bool 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 != nullptr && 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 empty.");
    265             // Even though we weren't able to decode the pixels, the readbuffer should still be
    266             // intact, so we return true with an empty bitmap, so we don't force an abort of the
    267             // larger deserialize.
    268             bitmap->setInfo(SkImageInfo::MakeUnknown(width, height));
    269             return true;
    270         } else if (SkBitmap::ReadRawPixels(this, bitmap)) {
    271             return true;
    272         }
    273     }
    274     // Could not read the SkBitmap. Use a placeholder bitmap.
    275     bitmap->setInfo(SkImageInfo::MakeUnknown(width, height));
    276     return false;
    277 }
    278 
    279 namespace {
    280 
    281 // This generator intentionally should always fail on all attempts to get its pixels,
    282 // simulating a bad or empty codec stream.
    283 class EmptyImageGenerator final : public SkImageGenerator {
    284 public:
    285     EmptyImageGenerator(const SkImageInfo& info) : INHERITED(info) { }
    286 
    287 private:
    288     typedef SkImageGenerator INHERITED;
    289 };
    290 
    291 } // anonymous namespace
    292 
    293 SkImage* SkReadBuffer::readImage() {
    294     int width = this->read32();
    295     int height = this->read32();
    296     if (width <= 0 || height <= 0) {    // SkImage never has a zero dimension
    297         this->validate(false);
    298         return nullptr;
    299     }
    300 
    301     SkAutoTUnref<SkData> encoded(this->readByteArrayAsData());
    302     if (encoded->size() == 0) {
    303         // The image could not be encoded at serialization time - return an empty placeholder.
    304         return SkImage::NewFromGenerator(
    305             new EmptyImageGenerator(SkImageInfo::MakeN32Premul(width, height)));
    306     }
    307 
    308     int originX = this->read32();
    309     int originY = this->read32();
    310     if (originX < 0 || originY < 0) {
    311         this->validate(false);
    312         return nullptr;
    313     }
    314 
    315     const SkIRect subset = SkIRect::MakeXYWH(originX, originY, width, height);
    316     SkImage* image = SkImage::NewFromEncoded(encoded, &subset);
    317     if (image) {
    318         return image;
    319     }
    320 
    321     return SkImage::NewFromGenerator(
    322             new EmptyImageGenerator(SkImageInfo::MakeN32Premul(width, height)));
    323 }
    324 
    325 SkTypeface* SkReadBuffer::readTypeface() {
    326 
    327     uint32_t index = fReader.readU32();
    328     if (0 == index || index > (unsigned)fTFCount) {
    329         return nullptr;
    330     } else {
    331         SkASSERT(fTFArray);
    332         return fTFArray[index - 1];
    333     }
    334 }
    335 
    336 SkFlattenable* SkReadBuffer::readFlattenable(SkFlattenable::Type ft) {
    337     //
    338     // TODO: confirm that ft matches the factory we decide to use
    339     //
    340 
    341     SkFlattenable::Factory factory = nullptr;
    342 
    343     if (fFactoryCount > 0) {
    344         int32_t index = fReader.readU32();
    345         if (0 == index) {
    346             return nullptr; // writer failed to give us the flattenable
    347         }
    348         index -= 1;     // we stored the index-base-1
    349         if ((unsigned)index >= (unsigned)fFactoryCount) {
    350             this->validate(false);
    351             return nullptr;
    352         }
    353         factory = fFactoryArray[index];
    354     } else if (fFactoryTDArray) {
    355         int32_t index = fReader.readU32();
    356         if (0 == index) {
    357             return nullptr; // writer failed to give us the flattenable
    358         }
    359         index -= 1;     // we stored the index-base-1
    360         if ((unsigned)index >= (unsigned)fFactoryCount) {
    361             this->validate(false);
    362             return nullptr;
    363         }
    364         factory = (*fFactoryTDArray)[index];
    365     } else {
    366         factory = (SkFlattenable::Factory)readFunctionPtr();
    367         if (nullptr == factory) {
    368             return nullptr; // writer failed to give us the flattenable
    369         }
    370     }
    371 
    372     // if we get here, factory may still be null, but if that is the case, the
    373     // failure was ours, not the writer.
    374     SkFlattenable* obj = nullptr;
    375     uint32_t sizeRecorded = fReader.readU32();
    376     if (factory) {
    377         size_t offset = fReader.offset();
    378         obj = (*factory)(*this);
    379         // check that we read the amount we expected
    380         size_t sizeRead = fReader.offset() - offset;
    381         if (sizeRecorded != sizeRead) {
    382             this->validate(false);
    383             return nullptr;
    384         }
    385     } else {
    386         // we must skip the remaining data
    387         fReader.skip(sizeRecorded);
    388     }
    389     return obj;
    390 }
    391 
    392 /**
    393  *  Needs to follow the same pattern as readFlattenable(), but explicitly skip whatever data
    394  *  has been written.
    395  */
    396 void SkReadBuffer::skipFlattenable() {
    397     if (fFactoryCount > 0) {
    398         if (0 == fReader.readU32()) {
    399             return;
    400         }
    401     } else if (fFactoryTDArray) {
    402         if (0 == fReader.readU32()) {
    403             return;
    404         }
    405     } else {
    406         if (nullptr == this->readFunctionPtr()) {
    407             return;
    408         }
    409     }
    410     uint32_t sizeRecorded = fReader.readU32();
    411     fReader.skip(sizeRecorded);
    412 }
    413