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