/* * Copyright 2011 Google Inc. * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef SkReadBuffer_DEFINED #define SkReadBuffer_DEFINED #include "SkColorFilter.h" #include "SkSerialProcs.h" #include "SkDrawLooper.h" #include "SkFont.h" #include "SkImageFilter.h" #include "SkMaskFilterBase.h" #include "SkPaintPriv.h" #include "SkPath.h" #include "SkPathEffect.h" #include "SkPicture.h" #include "SkReader32.h" #include "SkRefCnt.h" #include "SkShaderBase.h" #include "SkWriteBuffer.h" class SkData; class SkImage; #ifndef SK_DISABLE_READBUFFER class SkReadBuffer { public: SkReadBuffer(); SkReadBuffer(const void* data, size_t size); enum Version { kTileModeInBlurImageFilter_Version = 56, kTileInfoInSweepGradient_Version = 57, k2PtConicalNoFlip_Version = 58, kRemovePictureImageFilterLocalSpace = 59, kRemoveHeaderFlags_Version = 60, kTwoColorDrawShadow_Version = 61, kDontNegateImageSize_Version = 62, kStoreImageBounds_Version = 63, kRemoveOccluderFromBlurMaskFilter = 64, kFloat4PaintColor_Version = 65, kSaveBehind_Version = 66, kSerializeFonts_Version = 67, kPaintDoesntSerializeFonts_Version = 68, }; /** * Returns true IFF the version is older than the specified version. */ bool isVersionLT(Version targetVersion) const { SkASSERT(targetVersion > 0); return fVersion > 0 && fVersion < targetVersion; } uint32_t getVersion() const { return fVersion; } /** This may be called at most once; most clients of SkReadBuffer should not mess with it. */ void setVersion(int version) { SkASSERT(0 == fVersion || version == fVersion); fVersion = version; } size_t size() const { return fReader.size(); } size_t offset() const { return fReader.offset(); } bool eof() { return fReader.eof(); } const void* skip(size_t size); const void* skip(size_t count, size_t size); // does safe multiply size_t available() const { return fReader.available(); } template <typename T> const T* skipT() { return static_cast<const T*>(this->skip(sizeof(T))); } template <typename T> const T* skipT(size_t count) { return static_cast<const T*>(this->skip(count, sizeof(T))); } // primitives bool readBool(); SkColor readColor(); int32_t readInt(); SkScalar readScalar(); uint32_t readUInt(); int32_t read32(); template <typename T> T read32LE(T max) { uint32_t value = this->readUInt(); if (!this->validate(value <= static_cast<uint32_t>(max))) { value = 0; } return static_cast<T>(value); } // peek uint8_t peekByte(); // strings -- the caller is responsible for freeing the string contents void readString(SkString* string); // common data structures void readColor4f(SkColor4f* color); void readPoint(SkPoint* point); SkPoint readPoint() { SkPoint p; this->readPoint(&p); return p; } void readPoint3(SkPoint3* point); void readMatrix(SkMatrix* matrix); void readIRect(SkIRect* rect); void readRect(SkRect* rect); void readRRect(SkRRect* rrect); void readRegion(SkRegion* region); void readPath(SkPath* path); SkReadPaintResult readPaint(SkPaint* paint, SkFont* font) { return SkPaintPriv::Unflatten(paint, *this, font); } SkFlattenable* readFlattenable(SkFlattenable::Type); template <typename T> sk_sp<T> readFlattenable() { return sk_sp<T>((T*)this->readFlattenable(T::GetFlattenableType())); } sk_sp<SkColorFilter> readColorFilter() { return this->readFlattenable<SkColorFilter>(); } sk_sp<SkDrawLooper> readDrawLooper() { return this->readFlattenable<SkDrawLooper>(); } sk_sp<SkImageFilter> readImageFilter() { return this->readFlattenable<SkImageFilter>(); } sk_sp<SkMaskFilter> readMaskFilter() { return this->readFlattenable<SkMaskFilterBase>(); } sk_sp<SkPathEffect> readPathEffect() { return this->readFlattenable<SkPathEffect>(); } sk_sp<SkShader> readShader() { return this->readFlattenable<SkShaderBase>(); } // Reads SkAlign4(bytes), but will only copy bytes into the buffer. bool readPad32(void* buffer, size_t bytes); // binary data and arrays bool readByteArray(void* value, size_t size); bool readColorArray(SkColor* colors, size_t size); bool readColor4fArray(SkColor4f* colors, size_t size); bool readIntArray(int32_t* values, size_t size); bool readPointArray(SkPoint* points, size_t size); bool readScalarArray(SkScalar* values, size_t size); sk_sp<SkData> readByteArrayAsData(); // helpers to get info about arrays and binary data uint32_t getArrayCount(); // If there is a real error (e.g. data is corrupted) this returns null. If the image cannot // be created (e.g. it was not originally encoded) then this returns an image that doesn't // draw. sk_sp<SkImage> readImage(); sk_sp<SkTypeface> readTypeface(); void setTypefaceArray(sk_sp<SkTypeface> array[], int count) { fTFArray = array; fTFCount = count; } /** * Call this with a pre-loaded array of Factories, in the same order as * were created/written by the writer. SkPicture uses this. */ void setFactoryPlayback(SkFlattenable::Factory array[], int count) { fFactoryArray = array; fFactoryCount = count; } void setDeserialProcs(const SkDeserialProcs& procs); const SkDeserialProcs& getDeserialProcs() const { return fProcs; } /** * If isValid is false, sets the buffer to be "invalid". Returns true if the buffer * is still valid. */ bool validate(bool isValid) { if (!isValid) { this->setInvalid(); } return !fError; } /** * Helper function to do a preflight check before a large allocation or read. * Returns true if there is enough bytes in the buffer to read n elements of T. * If not, the buffer will be "invalid" and false will be returned. */ template <typename T> bool validateCanReadN(size_t n) { return this->validate(n <= (fReader.available() / sizeof(T))); } bool isValid() const { return !fError; } bool validateIndex(int index, int count) { return this->validate(index >= 0 && index < count); } // Utilities that mark the buffer invalid if the requested value is out-of-range // If the read value is outside of the range, validate(false) is called, and min // is returned, else the value is returned. int32_t checkInt(int min, int max); template <typename T> T checkRange(T min, T max) { return static_cast<T>(this->checkInt(static_cast<int32_t>(min), static_cast<int32_t>(max))); } SkFilterQuality checkFilterQuality(); private: void setInvalid(); bool readArray(void* value, size_t size, size_t elementSize); void setMemory(const void*, size_t); SkReader32 fReader; // Only used if we do not have an fFactoryArray. SkTHashMap<uint32_t, SkFlattenable::Factory> fFlattenableDict; int fVersion; sk_sp<SkTypeface>* fTFArray; int fTFCount; SkFlattenable::Factory* fFactoryArray; int fFactoryCount; SkDeserialProcs fProcs; static bool IsPtrAlign4(const void* ptr) { return SkIsAlign4((uintptr_t)ptr); } bool fError = false; }; #else // #ifndef SK_DISABLE_READBUFFER class SkReadBuffer { public: SkReadBuffer() {} SkReadBuffer(const void*, size_t) {} enum Version { kTileModeInBlurImageFilter_Version = 56, kTileInfoInSweepGradient_Version = 57, k2PtConicalNoFlip_Version = 58, kRemovePictureImageFilterLocalSpace = 59, kRemoveHeaderFlags_Version = 60, kTwoColorDrawShadow_Version = 61, kDontNegateImageSize_Version = 62, kStoreImageBounds_Version = 63, kRemoveOccluderFromBlurMaskFilter = 64, kFloat4PaintColor_Version = 65, kSaveBehind_Version = 66, kSerializeFonts_Version = 67, kPaintDoesntSerializeFonts_Version = 68, }; bool isVersionLT(Version) const { return false; } uint32_t getVersion() const { return 0xffffffff; } void setVersion(int) {} size_t size() const { return 0; } size_t offset() const { return 0; } bool eof() { return true; } size_t available() const { return 0; } const void* skip(size_t) { return nullptr; } const void* skip(size_t, size_t) { return nullptr; } template <typename T> const T* skipT() { return nullptr; } template <typename T> const T* skipT(size_t) { return nullptr; } bool readBool() { return 0; } SkColor readColor() { return 0; } int32_t readInt() { return 0; } SkScalar readScalar() { return 0; } uint32_t readUInt() { return 0; } int32_t read32() { return 0; } template <typename T> T read32LE(T max) { return max; } uint8_t peekByte() { return 0; } void readColor4f(SkColor4f* out) { *out = SkColor4f{0,0,0,0}; } void readPoint (SkPoint* out) { *out = SkPoint{0,0}; } void readPoint3 (SkPoint3* out) { *out = SkPoint3{0,0,0}; } void readMatrix (SkMatrix* out) { *out = SkMatrix::I(); } void readIRect (SkIRect* out) { *out = SkIRect{0,0,0,0}; } void readRect (SkRect* out) { *out = SkRect{0,0,0,0}; } void readRRect (SkRRect* out) { *out = SkRRect(); } void readRegion (SkRegion* out) { *out = SkRegion(); } void readString (SkString* out) { *out = SkString(); } void readPath (SkPath* out) { *out = SkPath(); } SkReadPaintResult readPaint (SkPaint* out, SkFont* font) { *out = SkPaint(); if (font) { *font = SkFont(); } return kFailed_ReadPaint; } SkPoint readPoint() { return {0,0}; } SkFlattenable* readFlattenable(SkFlattenable::Type) { return nullptr; } template <typename T> sk_sp<T> readFlattenable() { return nullptr; } sk_sp<SkColorFilter> readColorFilter() { return nullptr; } sk_sp<SkDrawLooper> readDrawLooper() { return nullptr; } sk_sp<SkImageFilter> readImageFilter() { return nullptr; } sk_sp<SkMaskFilter> readMaskFilter() { return nullptr; } sk_sp<SkPathEffect> readPathEffect() { return nullptr; } sk_sp<SkShader> readShader() { return nullptr; } bool readPad32 (void*, size_t) { return false; } bool readByteArray (void*, size_t) { return false; } bool readColorArray (SkColor*, size_t) { return false; } bool readColor4fArray(SkColor4f*, size_t) { return false; } bool readIntArray (int32_t*, size_t) { return false; } bool readPointArray (SkPoint*, size_t) { return false; } bool readScalarArray (SkScalar*, size_t) { return false; } sk_sp<SkData> readByteArrayAsData() { return nullptr; } uint32_t getArrayCount() { return 0; } sk_sp<SkImage> readImage() { return nullptr; } sk_sp<SkTypeface> readTypeface() { return nullptr; } bool validate(bool) { return false; } template <typename T> bool validateCanReadN(size_t) { return false; } bool isValid() const { return false; } bool validateIndex(int, int) { return false; } int32_t checkInt(int min, int) { return min; } template <typename T> T checkRange(T min, T) { return min; } SkFilterQuality checkFilterQuality() { return SkFilterQuality::kNone_SkFilterQuality; } void setTypefaceArray(sk_sp<SkTypeface>[], int) {} void setFactoryPlayback(SkFlattenable::Factory[], int) {} void setDeserialProcs(const SkDeserialProcs&) {} const SkDeserialProcs& getDeserialProcs() const { static const SkDeserialProcs procs; return procs; } }; #endif // #ifndef SK_DISABLE_READBUFFER #endif // SkReadBuffer_DEFINED