Home | History | Annotate | Download | only in core
      1 /*
      2  * Copyright 2011 Google Inc.
      3  *
      4  * Use of this source code is governed by a BSD-style license that can be
      5  * found in the LICENSE file.
      6  */
      7 
      8 #ifndef SkReadBuffer_DEFINED
      9 #define SkReadBuffer_DEFINED
     10 
     11 #include "SkColorFilter.h"
     12 #include "SkData.h"
     13 #include "SkSerialProcs.h"
     14 #include "SkDrawLooper.h"
     15 #include "SkImageFilter.h"
     16 #include "SkMaskFilterBase.h"
     17 #include "SkPath.h"
     18 #include "SkPathEffect.h"
     19 #include "SkPicture.h"
     20 #include "SkReadBuffer.h"
     21 #include "SkReader32.h"
     22 #include "SkRefCnt.h"
     23 #include "SkShaderBase.h"
     24 #include "SkTHash.h"
     25 #include "SkWriteBuffer.h"
     26 
     27 class SkImage;
     28 class SkInflator;
     29 
     30 #if defined(SK_DEBUG) && defined(SK_BUILD_FOR_MAC)
     31     #define DEBUG_NON_DETERMINISTIC_ASSERT
     32 #endif
     33 
     34 class SkReadBuffer {
     35 public:
     36     SkReadBuffer();
     37     SkReadBuffer(const void* data, size_t size);
     38     virtual ~SkReadBuffer();
     39 
     40     virtual SkReadBuffer* clone(const void* data, size_t size) const {
     41         return new SkReadBuffer(data, size);
     42     }
     43 
     44     enum Version {
     45         /*
     46         kFilterLevelIsEnum_Version         = 23,
     47         kGradientFlippedFlag_Version       = 24,
     48         kDashWritesPhaseIntervals_Version  = 25,
     49         kColorShaderNoBool_Version         = 26,
     50         kNoUnitMappers_Version             = 27,
     51         kNoMoreBitmapFlatten_Version       = 28,
     52         kSimplifyLocalMatrix_Version       = 30,
     53         kImageFilterUniqueID_Version       = 31,
     54         kRemoveAndroidPaintOpts_Version    = 32,
     55         kFlattenCreateProc_Version         = 33,
     56         kRemoveColorTableAlpha_Version     = 36,
     57         kDropShadowMode_Version            = 37,
     58         kPictureImageFilterResolution_Version = 38,
     59         kPictureImageFilterLevel_Version   = 39,
     60         kImageFilterNoUniqueID_Version     = 40,
     61         kBitmapSourceFilterQuality_Version = 41,
     62         kPictureShaderHasPictureBool_Version = 42,
     63         kHasDrawImageOpCodes_Version       = 43,
     64         kAnnotationsMovedToCanvas_Version  = 44,
     65         kLightingShaderWritesInvNormRotation = 45,
     66         kBlurMaskFilterWritesOccluder      = 47,
     67         kGradientShaderFloatColor_Version  = 49,
     68         kXfermodeToBlendMode_Version       = 50,
     69         kXfermodeToBlendMode2_Version      = 51,
     70         kTextBlobImplicitRunCount_Version  = 52,
     71         kComposeShaderCanLerp_Version      = 54,
     72         kNoModesInMergeImageFilter_Verison = 55,
     73          */
     74         kTileModeInBlurImageFilter_Version = 56,
     75         kTileInfoInSweepGradient_Version   = 57,
     76         k2PtConicalNoFlip_Version          = 58,
     77         kRemovePictureImageFilterLocalSpace = 59,
     78         kRemoveHeaderFlags_Version         = 60,
     79         kTwoColorDrawShadow_Version        = 61,
     80     };
     81 
     82     /**
     83      *  Returns true IFF the version is older than the specified version.
     84      */
     85     bool isVersionLT(Version targetVersion) const {
     86         SkASSERT(targetVersion > 0);
     87         return fVersion > 0 && fVersion < targetVersion;
     88     }
     89 
     90     uint32_t getVersion() const { return fVersion; }
     91 
     92     /** This may be called at most once; most clients of SkReadBuffer should not mess with it. */
     93     void setVersion(int version) {
     94         SkASSERT(0 == fVersion || version == fVersion);
     95         fVersion = version;
     96     }
     97 
     98     size_t size() { return fReader.size(); }
     99     size_t offset() { return fReader.offset(); }
    100     bool eof() { return fReader.eof(); }
    101     const void* skip(size_t size);
    102     const void* skip(size_t count, size_t size);    // does safe multiply
    103 
    104     template <typename T> const T* skipT() {
    105         return static_cast<const T*>(this->skip(sizeof(T)));
    106     }
    107     template <typename T> const T* skipT(size_t count) {
    108         return static_cast<const T*>(this->skip(count, sizeof(T)));
    109     }
    110 
    111     // primitives
    112     bool readBool();
    113     SkColor readColor();
    114     int32_t readInt();
    115     SkScalar readScalar();
    116     uint32_t readUInt();
    117     int32_t read32();
    118 
    119     template <typename T> T read32LE(T max) {
    120         uint32_t value = this->readUInt();
    121         if (!this->validate(value <= static_cast<uint32_t>(max))) {
    122             value = 0;
    123         }
    124         return static_cast<T>(value);
    125     }
    126 
    127     // peek
    128     uint8_t peekByte();
    129 
    130     // strings -- the caller is responsible for freeing the string contents
    131     void readString(SkString* string);
    132 
    133     // common data structures
    134     void readColor4f(SkColor4f* color);
    135     void readPoint(SkPoint* point);
    136     SkPoint readPoint() { SkPoint p; this->readPoint(&p); return p; }
    137     void readPoint3(SkPoint3* point);
    138     void readMatrix(SkMatrix* matrix);
    139     void readIRect(SkIRect* rect);
    140     void readRect(SkRect* rect);
    141     void readRRect(SkRRect* rrect);
    142     void readRegion(SkRegion* region);
    143 
    144     void readPath(SkPath* path);
    145     virtual bool readPaint(SkPaint* paint) { return paint->unflatten(*this); }
    146 
    147     SkFlattenable* readFlattenable(SkFlattenable::Type);
    148     template <typename T> sk_sp<T> readFlattenable() {
    149         return sk_sp<T>((T*)this->readFlattenable(T::GetFlattenableType()));
    150     }
    151     sk_sp<SkColorFilter> readColorFilter() { return this->readFlattenable<SkColorFilter>(); }
    152     sk_sp<SkDrawLooper> readDrawLooper() { return this->readFlattenable<SkDrawLooper>(); }
    153     sk_sp<SkImageFilter> readImageFilter() { return this->readFlattenable<SkImageFilter>(); }
    154     sk_sp<SkMaskFilter> readMaskFilter() { return this->readFlattenable<SkMaskFilterBase>(); }
    155     sk_sp<SkPathEffect> readPathEffect() { return this->readFlattenable<SkPathEffect>(); }
    156     sk_sp<SkShader> readShader() { return this->readFlattenable<SkShaderBase>(); }
    157 
    158     // Reads SkAlign4(bytes), but will only copy bytes into the buffer.
    159     bool readPad32(void* buffer, size_t bytes);
    160 
    161     // binary data and arrays
    162     bool readByteArray(void* value, size_t size);
    163     bool readColorArray(SkColor* colors, size_t size);
    164     bool readColor4fArray(SkColor4f* colors, size_t size);
    165     bool readIntArray(int32_t* values, size_t size);
    166     bool readPointArray(SkPoint* points, size_t size);
    167     bool readScalarArray(SkScalar* values, size_t size);
    168 
    169     sk_sp<SkData> readByteArrayAsData() {
    170         size_t len = this->getArrayCount();
    171         void* buffer = sk_malloc_throw(len);
    172         if (!this->readByteArray(buffer, len)) {
    173             sk_free(buffer);
    174             return SkData::MakeEmpty();
    175         }
    176         return SkData::MakeFromMalloc(buffer, len);
    177     }
    178 
    179     // helpers to get info about arrays and binary data
    180     uint32_t getArrayCount();
    181 
    182     // If there is a real error (e.g. data is corrupted) this returns null. If the image cannot
    183     // be created (e.g. it was not originally encoded) then this returns an image that doesn't
    184     // draw.
    185     sk_sp<SkImage> readImage();
    186     sk_sp<SkTypeface> readTypeface();
    187 
    188     void setTypefaceArray(SkTypeface* array[], int count) {
    189         fTFArray = array;
    190         fTFCount = count;
    191     }
    192 
    193     /**
    194      *  Call this with a pre-loaded array of Factories, in the same order as
    195      *  were created/written by the writer. SkPicture uses this.
    196      */
    197     void setFactoryPlayback(SkFlattenable::Factory array[], int count) {
    198         fFactoryArray = array;
    199         fFactoryCount = count;
    200     }
    201 
    202     /**
    203      *  For an input flattenable (specified by name), set a custom factory proc
    204      *  to use when unflattening.  Will make a copy of |name|.
    205      *
    206      *  If the global registry already has a default factory for the flattenable,
    207      *  this will override that factory.  If a custom factory has already been
    208      *  set for the flattenable, this will override that factory.
    209      *
    210      *  Custom factories can be removed by calling setCustomFactory("...", nullptr).
    211      */
    212     void setCustomFactory(const SkString& name, SkFlattenable::Factory factory) {
    213         fCustomFactory.set(name, factory);
    214     }
    215 
    216     void setDeserialProcs(const SkDeserialProcs& procs);
    217 
    218     /**
    219      *  If isValid is false, sets the buffer to be "invalid". Returns true if the buffer
    220      *  is still valid.
    221      */
    222     bool validate(bool isValid) {
    223         if (!isValid) {
    224             this->setInvalid();
    225         }
    226         return !fError;
    227     }
    228     bool isValid() const { return !fError; }
    229     bool validateIndex(int index, int count) {
    230         return this->validate(index >= 0 && index < count);
    231     }
    232 
    233     SkInflator* getInflator() const { return fInflator; }
    234     void setInflator(SkInflator* inf) { fInflator = inf; }
    235 
    236     // Utilities that mark the buffer invalid if the requested value is out-of-range
    237 
    238     // If the read value is outside of the range, validate(false) is called, and min
    239     // is returned, else the value is returned.
    240     int32_t checkInt(int min, int max);
    241 
    242     template <typename T> T checkRange(T min, T max) {
    243         return static_cast<T>(this->checkInt(static_cast<int32_t>(min),
    244                                              static_cast<int32_t>(max)));
    245     }
    246 
    247     SkFilterQuality checkFilterQuality();
    248 
    249 protected:
    250     /**
    251      *  Allows subclass to check if we are using factories for expansion
    252      *  of flattenables.
    253      */
    254     int factoryCount() { return fFactoryCount; }
    255 
    256     /**
    257      *  Checks if a custom factory has been set for a given flattenable.
    258      *  Returns the custom factory if it exists, or nullptr otherwise.
    259      */
    260     SkFlattenable::Factory getCustomFactory(const SkString& name) {
    261         SkFlattenable::Factory* factoryPtr = fCustomFactory.find(name);
    262         return factoryPtr ? *factoryPtr : nullptr;
    263     }
    264 
    265     SkReader32 fReader;
    266 
    267     // Only used if we do not have an fFactoryArray.
    268     SkTHashMap<uint32_t, SkString> fFlattenableDict;
    269 
    270 private:
    271     void setInvalid();
    272     bool readArray(void* value, size_t size, size_t elementSize);
    273     void setMemory(const void*, size_t);
    274 
    275     int fVersion;
    276 
    277     void* fMemoryPtr;
    278 
    279     SkTypeface** fTFArray;
    280     int        fTFCount;
    281 
    282     SkFlattenable::Factory* fFactoryArray;
    283     int                     fFactoryCount;
    284 
    285     // Only used if we do not have an fFactoryArray.
    286     SkTHashMap<SkString, SkFlattenable::Factory> fCustomFactory;
    287 
    288     SkDeserialProcs fProcs;
    289     friend class SkPicture;
    290 
    291 #ifdef DEBUG_NON_DETERMINISTIC_ASSERT
    292     // Debugging counter to keep track of how many bitmaps we
    293     // have decoded.
    294     int fDecodedBitmapIndex;
    295 #endif // DEBUG_NON_DETERMINISTIC_ASSERT
    296 
    297     SkInflator* fInflator = nullptr;
    298 
    299     static bool IsPtrAlign4(const void* ptr) {
    300         return SkIsAlign4((uintptr_t)ptr);
    301     }
    302 
    303     bool fError = false;
    304 };
    305 
    306 #endif // SkReadBuffer_DEFINED
    307