• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "include/core/SkColor.h"
12 #include "include/core/SkColorFilter.h"
13 #include "include/core/SkFlattenable.h"
14 #include "include/core/SkImageFilter.h"
15 #include "include/core/SkPaint.h"
16 #include "include/core/SkPathEffect.h"
17 #include "include/core/SkPoint.h"
18 #include "include/core/SkRect.h"
19 #include "include/core/SkRefCnt.h"
20 #include "include/core/SkSamplingOptions.h"
21 #include "include/core/SkScalar.h"
22 #include "include/core/SkSerialProcs.h"
23 #include "include/core/SkShader.h"
24 #include "include/private/base/SkAlign.h"
25 #include "include/private/base/SkAssert.h"
26 #include "src/core/SkBlenderBase.h"
27 #include "src/core/SkColorFilterBase.h"
28 #include "src/core/SkImageFilter_Base.h"
29 #include "src/core/SkMaskFilterBase.h"
30 #include "src/core/SkPaintPriv.h"
31 #include "src/core/SkPicturePriv.h"
32 #include "src/core/SkSamplingPriv.h"
33 #include "src/core/SkTHash.h"
34 #include "src/shaders/SkShaderBase.h"
35 
36 #include <cstddef>
37 #include <cstdint>
38 
39 class SkBlender;
40 class SkData;
41 class SkImage;
42 class SkM44;
43 class SkMaskFilter;
44 class SkMatrix;
45 class SkPath;
46 class SkRRect;
47 class SkRegion;
48 class SkString;
49 class SkTypeface;
50 struct SkPoint3;
51 
52 #ifdef SK_SUPPORT_LEGACY_DRAWLOOPER
53 #include "include/core/SkDrawLooper.h"
54 #endif
55 
56 class SkReadBuffer {
57 public:
58     SkReadBuffer() = default;
SkReadBuffer(const void * data,size_t size)59     SkReadBuffer(const void* data, size_t size) {
60         this->setMemory(data, size);
61     }
62 
63     void setMemory(const void*, size_t);
64 
65     /**
66      *  Returns true IFF the version is older than the specified version.
67      */
isVersionLT(SkPicturePriv::Version targetVersion)68     bool isVersionLT(SkPicturePriv::Version targetVersion) const {
69         SkASSERT(targetVersion > 0);
70         return fVersion > 0 && fVersion < targetVersion;
71     }
72 
getVersion()73     uint32_t getVersion() const { return fVersion; }
74 
75     /** This may be called at most once; most clients of SkReadBuffer should not mess with it. */
setVersion(int version)76     void setVersion(int version) {
77         SkASSERT(0 == fVersion || version == fVersion);
78         fVersion = version;
79     }
80 
size()81     size_t size() const { return fStop - fBase; }
offset()82     size_t offset() const { return fCurr - fBase; }
eof()83     bool eof() { return fCurr >= fStop; }
84     const void* skip(size_t size);
85     const void* skip(size_t count, size_t size);    // does safe multiply
available()86     size_t available() const { return fStop - fCurr; }
87 
skipT()88     template <typename T> const T* skipT() {
89         return static_cast<const T*>(this->skip(sizeof(T)));
90     }
skipT(size_t count)91     template <typename T> const T* skipT(size_t count) {
92         return static_cast<const T*>(this->skip(count, sizeof(T)));
93     }
94 
95     // primitives
96     bool readBool();
97     SkColor readColor();
98     int32_t readInt();
99     SkScalar readScalar();
100     uint32_t readUInt();
101     int32_t read32();
102 
read32LE(T max)103     template <typename T> T read32LE(T max) {
104         uint32_t value = this->readUInt();
105         if (!this->validate(value <= static_cast<uint32_t>(max))) {
106             value = 0;
107         }
108         return static_cast<T>(value);
109     }
110 
111     // peek
112     uint8_t peekByte();
113 
114     void readString(SkString* string);
115 
116     // common data structures
117     void readColor4f(SkColor4f* color);
118     void readPoint(SkPoint* point);
readPoint()119     SkPoint readPoint() { SkPoint p; this->readPoint(&p); return p; }
120     void readPoint3(SkPoint3* point);
121     void read(SkM44*);
122     void readMatrix(SkMatrix* matrix);
123     void readIRect(SkIRect* rect);
124     void readRect(SkRect* rect);
125     SkRect readRect();
126     void readRRect(SkRRect* rrect);
127     void readRegion(SkRegion* region);
128 
129     void readPath(SkPath* path);
130 
readPaint()131     SkPaint readPaint() {
132         return SkPaintPriv::Unflatten(*this);
133     }
134 
135     SkFlattenable* readRawFlattenable();
136     SkFlattenable* readFlattenable(SkFlattenable::Type);
readFlattenable()137     template <typename T> sk_sp<T> readFlattenable() {
138         return sk_sp<T>((T*)this->readFlattenable(T::GetFlattenableType()));
139     }
readColorFilter()140     sk_sp<SkColorFilter> readColorFilter() { return this->readFlattenable<SkColorFilterBase>(); }
141 #ifdef SK_SUPPORT_LEGACY_DRAWLOOPER
readDrawLooper()142     sk_sp<SkDrawLooper> readDrawLooper() { return this->readFlattenable<SkDrawLooper>(); }
143 #endif
readImageFilter()144     sk_sp<SkImageFilter> readImageFilter() { return this->readFlattenable<SkImageFilter_Base>(); }
readBlender()145     sk_sp<SkBlender> readBlender() { return this->readFlattenable<SkBlenderBase>(); }
readMaskFilter()146     sk_sp<SkMaskFilter> readMaskFilter() { return this->readFlattenable<SkMaskFilterBase>(); }
readPathEffect()147     sk_sp<SkPathEffect> readPathEffect() { return this->readFlattenable<SkPathEffect>(); }
readShader()148     sk_sp<SkShader> readShader() { return this->readFlattenable<SkShaderBase>(); }
149 
150     // Reads SkAlign4(bytes), but will only copy bytes into the buffer.
151     bool readPad32(void* buffer, size_t bytes);
152 
153     // binary data and arrays
154     bool readByteArray(void* value, size_t size);
155     bool readColorArray(SkColor* colors, size_t size);
156     bool readColor4fArray(SkColor4f* colors, size_t size);
157     bool readIntArray(int32_t* values, size_t size);
158     bool readPointArray(SkPoint* points, size_t size);
159     bool readScalarArray(SkScalar* values, size_t size);
160 
161     const void* skipByteArray(size_t* size);
162 
163     sk_sp<SkData> readByteArrayAsData();
164 
165     // helpers to get info about arrays and binary data
166     uint32_t getArrayCount();
167 
168     // If there is a real error (e.g. data is corrupted) this returns null. If the image cannot
169     // be created (e.g. it was not originally encoded) then this returns an image that doesn't
170     // draw.
171     sk_sp<SkImage> readImage();
172     sk_sp<SkTypeface> readTypeface();
173 
setTypefaceArray(sk_sp<SkTypeface> array[],int count)174     void setTypefaceArray(sk_sp<SkTypeface> array[], int count) {
175         fTFArray = array;
176         fTFCount = count;
177     }
178 
179     /**
180      *  Call this with a pre-loaded array of Factories, in the same order as
181      *  were created/written by the writer. SkPicture uses this.
182      */
setFactoryPlayback(SkFlattenable::Factory array[],int count)183     void setFactoryPlayback(SkFlattenable::Factory array[], int count) {
184         fFactoryArray = array;
185         fFactoryCount = count;
186     }
187 
188     void setDeserialProcs(const SkDeserialProcs& procs);
getDeserialProcs()189     const SkDeserialProcs& getDeserialProcs() const { return fProcs; }
190 
191     /**
192      *  If isValid is false, sets the buffer to be "invalid". Returns true if the buffer
193      *  is still valid.
194      */
validate(bool isValid)195     bool validate(bool isValid) {
196         if (!isValid) {
197             this->setInvalid();
198         }
199         return !fError;
200     }
201 
202     /**
203      * Helper function to do a preflight check before a large allocation or read.
204      * Returns true if there is enough bytes in the buffer to read n elements of T.
205      * If not, the buffer will be "invalid" and false will be returned.
206      */
207     template <typename T>
validateCanReadN(size_t n)208     bool validateCanReadN(size_t n) {
209         return this->validate(n <= (this->available() / sizeof(T)));
210     }
211 
isValid()212     bool isValid() const { return !fError; }
validateIndex(int index,int count)213     bool validateIndex(int index, int count) {
214         return this->validate(index >= 0 && index < count);
215     }
216 
217     // Utilities that mark the buffer invalid if the requested value is out-of-range
218 
219     // If the read value is outside of the range, validate(false) is called, and min
220     // is returned, else the value is returned.
221     int32_t checkInt(int min, int max);
222 
checkRange(T min,T max)223     template <typename T> T checkRange(T min, T max) {
224         return static_cast<T>(this->checkInt(static_cast<int32_t>(min),
225                                              static_cast<int32_t>(max)));
226     }
227 
228     SkLegacyFQ checkFilterQuality();
229 
230     SkSamplingOptions readSampling();
231 
232 private:
233     const char* readString(size_t* length);
234 
235     void setInvalid();
236     bool readArray(void* value, size_t size, size_t elementSize);
isAvailable(size_t size)237     bool isAvailable(size_t size) const { return size <= this->available(); }
238 
239     // These are always 4-byte aligned
240     const char* fCurr = nullptr;  // current position within buffer
241     const char* fStop = nullptr;  // end of buffer
242     const char* fBase = nullptr;  // beginning of buffer
243 
244     // Only used if we do not have an fFactoryArray.
245     SkTHashMap<uint32_t, SkFlattenable::Factory> fFlattenableDict;
246 
247     int fVersion = 0;
248 
249     sk_sp<SkTypeface>* fTFArray = nullptr;
250     int                fTFCount = 0;
251 
252     SkFlattenable::Factory* fFactoryArray = nullptr;
253     int                     fFactoryCount = 0;
254 
255     SkDeserialProcs fProcs;
256 
IsPtrAlign4(const void * ptr)257     static bool IsPtrAlign4(const void* ptr) {
258         return SkIsAlign4((uintptr_t)ptr);
259     }
260 
261     bool fError = false;
262 };
263 
264 #endif // SkReadBuffer_DEFINED
265