1cb93a386Sopenharmony_ci/*
2cb93a386Sopenharmony_ci * Copyright 2012 Google Inc.
3cb93a386Sopenharmony_ci *
4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be
5cb93a386Sopenharmony_ci * found in the LICENSE file.
6cb93a386Sopenharmony_ci */
7cb93a386Sopenharmony_ci
8cb93a386Sopenharmony_ci#include "include/core/SkBitmap.h"
9cb93a386Sopenharmony_ci#include "include/core/SkData.h"
10cb93a386Sopenharmony_ci#include "include/core/SkImage.h"
11cb93a386Sopenharmony_ci#include "include/core/SkImageGenerator.h"
12cb93a386Sopenharmony_ci#include "include/core/SkStream.h"
13cb93a386Sopenharmony_ci#include "include/core/SkTypeface.h"
14cb93a386Sopenharmony_ci#include "src/core/SkAutoMalloc.h"
15cb93a386Sopenharmony_ci#include "src/core/SkMathPriv.h"
16cb93a386Sopenharmony_ci#include "src/core/SkMatrixPriv.h"
17cb93a386Sopenharmony_ci#include "src/core/SkMipmapBuilder.h"
18cb93a386Sopenharmony_ci#include "src/core/SkReadBuffer.h"
19cb93a386Sopenharmony_ci#include "src/core/SkSafeMath.h"
20cb93a386Sopenharmony_ci
21cb93a386Sopenharmony_cinamespace {
22cb93a386Sopenharmony_ci    // This generator intentionally should always fail on all attempts to get its pixels,
23cb93a386Sopenharmony_ci    // simulating a bad or empty codec stream.
24cb93a386Sopenharmony_ci    class EmptyImageGenerator final : public SkImageGenerator {
25cb93a386Sopenharmony_ci    public:
26cb93a386Sopenharmony_ci        EmptyImageGenerator(const SkImageInfo& info) : INHERITED(info) { }
27cb93a386Sopenharmony_ci
28cb93a386Sopenharmony_ci    private:
29cb93a386Sopenharmony_ci        using INHERITED = SkImageGenerator;
30cb93a386Sopenharmony_ci    };
31cb93a386Sopenharmony_ci
32cb93a386Sopenharmony_ci    static sk_sp<SkImage> MakeEmptyImage(int width, int height) {
33cb93a386Sopenharmony_ci        return SkImage::MakeFromGenerator(
34cb93a386Sopenharmony_ci              std::make_unique<EmptyImageGenerator>(SkImageInfo::MakeN32Premul(width, height)));
35cb93a386Sopenharmony_ci    }
36cb93a386Sopenharmony_ci
37cb93a386Sopenharmony_ci} // anonymous namespace
38cb93a386Sopenharmony_ci
39cb93a386Sopenharmony_civoid SkReadBuffer::setMemory(const void* data, size_t size) {
40cb93a386Sopenharmony_ci    this->validate(IsPtrAlign4(data) && (SkAlign4(size) == size));
41cb93a386Sopenharmony_ci    if (!fError) {
42cb93a386Sopenharmony_ci        fBase = fCurr = (const char*)data;
43cb93a386Sopenharmony_ci        fStop = fBase + size;
44cb93a386Sopenharmony_ci    }
45cb93a386Sopenharmony_ci}
46cb93a386Sopenharmony_ci
47cb93a386Sopenharmony_civoid SkReadBuffer::setInvalid() {
48cb93a386Sopenharmony_ci    if (!fError) {
49cb93a386Sopenharmony_ci        // When an error is found, send the read cursor to the end of the stream
50cb93a386Sopenharmony_ci        fCurr = fStop;
51cb93a386Sopenharmony_ci        fError = true;
52cb93a386Sopenharmony_ci    }
53cb93a386Sopenharmony_ci}
54cb93a386Sopenharmony_ci
55cb93a386Sopenharmony_ciconst void* SkReadBuffer::skip(size_t size) {
56cb93a386Sopenharmony_ci    size_t inc = SkAlign4(size);
57cb93a386Sopenharmony_ci    this->validate(inc >= size);
58cb93a386Sopenharmony_ci    const void* addr = fCurr;
59cb93a386Sopenharmony_ci    this->validate(IsPtrAlign4(addr) && this->isAvailable(inc));
60cb93a386Sopenharmony_ci    if (fError) {
61cb93a386Sopenharmony_ci        return nullptr;
62cb93a386Sopenharmony_ci    }
63cb93a386Sopenharmony_ci
64cb93a386Sopenharmony_ci    fCurr += inc;
65cb93a386Sopenharmony_ci    return addr;
66cb93a386Sopenharmony_ci}
67cb93a386Sopenharmony_ci
68cb93a386Sopenharmony_ciconst void* SkReadBuffer::skip(size_t count, size_t size) {
69cb93a386Sopenharmony_ci    return this->skip(SkSafeMath::Mul(count, size));
70cb93a386Sopenharmony_ci}
71cb93a386Sopenharmony_ci
72cb93a386Sopenharmony_civoid SkReadBuffer::setDeserialProcs(const SkDeserialProcs& procs) {
73cb93a386Sopenharmony_ci    fProcs = procs;
74cb93a386Sopenharmony_ci}
75cb93a386Sopenharmony_ci
76cb93a386Sopenharmony_cibool SkReadBuffer::readBool() {
77cb93a386Sopenharmony_ci    uint32_t value = this->readUInt();
78cb93a386Sopenharmony_ci    // Boolean value should be either 0 or 1
79cb93a386Sopenharmony_ci    this->validate(!(value & ~1));
80cb93a386Sopenharmony_ci    return value != 0;
81cb93a386Sopenharmony_ci}
82cb93a386Sopenharmony_ci
83cb93a386Sopenharmony_ciSkColor SkReadBuffer::readColor() {
84cb93a386Sopenharmony_ci    return this->readUInt();
85cb93a386Sopenharmony_ci}
86cb93a386Sopenharmony_ci
87cb93a386Sopenharmony_ciint32_t SkReadBuffer::readInt() {
88cb93a386Sopenharmony_ci    const size_t inc = sizeof(int32_t);
89cb93a386Sopenharmony_ci    if (!this->validate(IsPtrAlign4(fCurr) && this->isAvailable(inc))) {
90cb93a386Sopenharmony_ci        return 0;
91cb93a386Sopenharmony_ci    }
92cb93a386Sopenharmony_ci    int32_t value = *((const int32_t*)fCurr);
93cb93a386Sopenharmony_ci    fCurr += inc;
94cb93a386Sopenharmony_ci    return value;
95cb93a386Sopenharmony_ci}
96cb93a386Sopenharmony_ci
97cb93a386Sopenharmony_ciSkScalar SkReadBuffer::readScalar() {
98cb93a386Sopenharmony_ci    const size_t inc = sizeof(SkScalar);
99cb93a386Sopenharmony_ci    if (!this->validate(IsPtrAlign4(fCurr) && this->isAvailable(inc))) {
100cb93a386Sopenharmony_ci        return 0;
101cb93a386Sopenharmony_ci    }
102cb93a386Sopenharmony_ci    SkScalar value = *((const SkScalar*)fCurr);
103cb93a386Sopenharmony_ci    fCurr += inc;
104cb93a386Sopenharmony_ci    return value;
105cb93a386Sopenharmony_ci}
106cb93a386Sopenharmony_ci
107cb93a386Sopenharmony_ciuint32_t SkReadBuffer::readUInt() {
108cb93a386Sopenharmony_ci    return this->readInt();
109cb93a386Sopenharmony_ci}
110cb93a386Sopenharmony_ci
111cb93a386Sopenharmony_ciint32_t SkReadBuffer::read32() {
112cb93a386Sopenharmony_ci    return this->readInt();
113cb93a386Sopenharmony_ci}
114cb93a386Sopenharmony_ci
115cb93a386Sopenharmony_ciuint8_t SkReadBuffer::peekByte() {
116cb93a386Sopenharmony_ci    if (this->available() <= 0) {
117cb93a386Sopenharmony_ci        fError = true;
118cb93a386Sopenharmony_ci        return 0;
119cb93a386Sopenharmony_ci    }
120cb93a386Sopenharmony_ci    return *((uint8_t*)fCurr);
121cb93a386Sopenharmony_ci}
122cb93a386Sopenharmony_ci
123cb93a386Sopenharmony_cibool SkReadBuffer::readPad32(void* buffer, size_t bytes) {
124cb93a386Sopenharmony_ci    if (const void* src = this->skip(bytes)) {
125cb93a386Sopenharmony_ci        // buffer might be null if bytes is zero (see SkAutoMalloc), hence we call
126cb93a386Sopenharmony_ci        // the careful version of memcpy.
127cb93a386Sopenharmony_ci        sk_careful_memcpy(buffer, src, bytes);
128cb93a386Sopenharmony_ci        return true;
129cb93a386Sopenharmony_ci    }
130cb93a386Sopenharmony_ci    return false;
131cb93a386Sopenharmony_ci}
132cb93a386Sopenharmony_ci
133cb93a386Sopenharmony_ciconst char* SkReadBuffer::readString(size_t* len) {
134cb93a386Sopenharmony_ci    *len = this->readUInt();
135cb93a386Sopenharmony_ci
136cb93a386Sopenharmony_ci    // The string is len characters and a terminating \0.
137cb93a386Sopenharmony_ci    const char* c_str = this->skipT<char>(*len+1);
138cb93a386Sopenharmony_ci
139cb93a386Sopenharmony_ci    if (this->validate(c_str && c_str[*len] == '\0')) {
140cb93a386Sopenharmony_ci        return c_str;
141cb93a386Sopenharmony_ci    }
142cb93a386Sopenharmony_ci    return nullptr;
143cb93a386Sopenharmony_ci}
144cb93a386Sopenharmony_ci
145cb93a386Sopenharmony_civoid SkReadBuffer::readString(SkString* string) {
146cb93a386Sopenharmony_ci    size_t len;
147cb93a386Sopenharmony_ci    if (const char* c_str = this->readString(&len)) {
148cb93a386Sopenharmony_ci        string->set(c_str, len);
149cb93a386Sopenharmony_ci        return;
150cb93a386Sopenharmony_ci    }
151cb93a386Sopenharmony_ci    string->reset();
152cb93a386Sopenharmony_ci}
153cb93a386Sopenharmony_ci
154cb93a386Sopenharmony_civoid SkReadBuffer::readColor4f(SkColor4f* color) {
155cb93a386Sopenharmony_ci    if (!this->readPad32(color, sizeof(SkColor4f))) {
156cb93a386Sopenharmony_ci        *color = {0, 0, 0, 0};
157cb93a386Sopenharmony_ci    }
158cb93a386Sopenharmony_ci}
159cb93a386Sopenharmony_ci
160cb93a386Sopenharmony_civoid SkReadBuffer::readPoint(SkPoint* point) {
161cb93a386Sopenharmony_ci    point->fX = this->readScalar();
162cb93a386Sopenharmony_ci    point->fY = this->readScalar();
163cb93a386Sopenharmony_ci}
164cb93a386Sopenharmony_ci
165cb93a386Sopenharmony_civoid SkReadBuffer::readPoint3(SkPoint3* point) {
166cb93a386Sopenharmony_ci    this->readPad32(point, sizeof(SkPoint3));
167cb93a386Sopenharmony_ci}
168cb93a386Sopenharmony_ci
169cb93a386Sopenharmony_civoid SkReadBuffer::read(SkM44* matrix) {
170cb93a386Sopenharmony_ci    if (this->isValid()) {
171cb93a386Sopenharmony_ci        if (const float* m = (const float*)this->skip(sizeof(float) * 16)) {
172cb93a386Sopenharmony_ci            *matrix = SkM44::ColMajor(m);
173cb93a386Sopenharmony_ci        }
174cb93a386Sopenharmony_ci    }
175cb93a386Sopenharmony_ci    if (!this->isValid()) {
176cb93a386Sopenharmony_ci        *matrix = SkM44();
177cb93a386Sopenharmony_ci    }
178cb93a386Sopenharmony_ci}
179cb93a386Sopenharmony_ci
180cb93a386Sopenharmony_civoid SkReadBuffer::readMatrix(SkMatrix* matrix) {
181cb93a386Sopenharmony_ci    size_t size = 0;
182cb93a386Sopenharmony_ci    if (this->isValid()) {
183cb93a386Sopenharmony_ci        size = SkMatrixPriv::ReadFromMemory(matrix, fCurr, this->available());
184cb93a386Sopenharmony_ci        (void)this->validate((SkAlign4(size) == size) && (0 != size));
185cb93a386Sopenharmony_ci    }
186cb93a386Sopenharmony_ci    if (!this->isValid()) {
187cb93a386Sopenharmony_ci        matrix->reset();
188cb93a386Sopenharmony_ci    }
189cb93a386Sopenharmony_ci    (void)this->skip(size);
190cb93a386Sopenharmony_ci}
191cb93a386Sopenharmony_ci
192cb93a386Sopenharmony_civoid SkReadBuffer::readIRect(SkIRect* rect) {
193cb93a386Sopenharmony_ci    if (!this->readPad32(rect, sizeof(SkIRect))) {
194cb93a386Sopenharmony_ci        rect->setEmpty();
195cb93a386Sopenharmony_ci    }
196cb93a386Sopenharmony_ci}
197cb93a386Sopenharmony_ci
198cb93a386Sopenharmony_civoid SkReadBuffer::readRect(SkRect* rect) {
199cb93a386Sopenharmony_ci    if (!this->readPad32(rect, sizeof(SkRect))) {
200cb93a386Sopenharmony_ci        rect->setEmpty();
201cb93a386Sopenharmony_ci    }
202cb93a386Sopenharmony_ci}
203cb93a386Sopenharmony_ci
204cb93a386Sopenharmony_ciSkRect SkReadBuffer::readRect() {
205cb93a386Sopenharmony_ci    SkRect r;
206cb93a386Sopenharmony_ci    if (!this->readPad32(&r, sizeof(SkRect))) {
207cb93a386Sopenharmony_ci        r.setEmpty();
208cb93a386Sopenharmony_ci    }
209cb93a386Sopenharmony_ci    return r;
210cb93a386Sopenharmony_ci}
211cb93a386Sopenharmony_ci
212cb93a386Sopenharmony_ciSkSamplingOptions SkReadBuffer::readSampling() {
213cb93a386Sopenharmony_ci    if (this->readBool()) {
214cb93a386Sopenharmony_ci        float B = this->readScalar();
215cb93a386Sopenharmony_ci        float C = this->readScalar();
216cb93a386Sopenharmony_ci        return SkSamplingOptions({B, C});
217cb93a386Sopenharmony_ci    } else {
218cb93a386Sopenharmony_ci        SkFilterMode filter = this->read32LE(SkFilterMode::kLinear);
219cb93a386Sopenharmony_ci        SkMipmapMode mipmap = this->read32LE(SkMipmapMode::kLinear);
220cb93a386Sopenharmony_ci        return SkSamplingOptions(filter, mipmap);
221cb93a386Sopenharmony_ci    }
222cb93a386Sopenharmony_ci}
223cb93a386Sopenharmony_ci
224cb93a386Sopenharmony_civoid SkReadBuffer::readRRect(SkRRect* rrect) {
225cb93a386Sopenharmony_ci    size_t size = 0;
226cb93a386Sopenharmony_ci    if (!fError) {
227cb93a386Sopenharmony_ci        size = rrect->readFromMemory(fCurr, this->available());
228cb93a386Sopenharmony_ci        if (!this->validate((SkAlign4(size) == size) && (0 != size))) {
229cb93a386Sopenharmony_ci            rrect->setEmpty();
230cb93a386Sopenharmony_ci        }
231cb93a386Sopenharmony_ci    }
232cb93a386Sopenharmony_ci    (void)this->skip(size);
233cb93a386Sopenharmony_ci}
234cb93a386Sopenharmony_ci
235cb93a386Sopenharmony_civoid SkReadBuffer::readRegion(SkRegion* region) {
236cb93a386Sopenharmony_ci    size_t size = 0;
237cb93a386Sopenharmony_ci    if (!fError) {
238cb93a386Sopenharmony_ci        size = region->readFromMemory(fCurr, this->available());
239cb93a386Sopenharmony_ci        if (!this->validate((SkAlign4(size) == size) && (0 != size))) {
240cb93a386Sopenharmony_ci            region->setEmpty();
241cb93a386Sopenharmony_ci        }
242cb93a386Sopenharmony_ci    }
243cb93a386Sopenharmony_ci    (void)this->skip(size);
244cb93a386Sopenharmony_ci}
245cb93a386Sopenharmony_ci
246cb93a386Sopenharmony_civoid SkReadBuffer::readPath(SkPath* path) {
247cb93a386Sopenharmony_ci    size_t size = 0;
248cb93a386Sopenharmony_ci    if (!fError) {
249cb93a386Sopenharmony_ci        size = path->readFromMemory(fCurr, this->available());
250cb93a386Sopenharmony_ci        if (!this->validate((SkAlign4(size) == size) && (0 != size))) {
251cb93a386Sopenharmony_ci            path->reset();
252cb93a386Sopenharmony_ci        }
253cb93a386Sopenharmony_ci    }
254cb93a386Sopenharmony_ci    (void)this->skip(size);
255cb93a386Sopenharmony_ci}
256cb93a386Sopenharmony_ci
257cb93a386Sopenharmony_cibool SkReadBuffer::readArray(void* value, size_t size, size_t elementSize) {
258cb93a386Sopenharmony_ci    const uint32_t count = this->readUInt();
259cb93a386Sopenharmony_ci    return this->validate(size == count) &&
260cb93a386Sopenharmony_ci           this->readPad32(value, SkSafeMath::Mul(size, elementSize));
261cb93a386Sopenharmony_ci}
262cb93a386Sopenharmony_ci
263cb93a386Sopenharmony_cibool SkReadBuffer::readByteArray(void* value, size_t size) {
264cb93a386Sopenharmony_ci    return this->readArray(value, size, sizeof(uint8_t));
265cb93a386Sopenharmony_ci}
266cb93a386Sopenharmony_ci
267cb93a386Sopenharmony_cibool SkReadBuffer::readColorArray(SkColor* colors, size_t size) {
268cb93a386Sopenharmony_ci    return this->readArray(colors, size, sizeof(SkColor));
269cb93a386Sopenharmony_ci}
270cb93a386Sopenharmony_ci
271cb93a386Sopenharmony_cibool SkReadBuffer::readColor4fArray(SkColor4f* colors, size_t size) {
272cb93a386Sopenharmony_ci    return this->readArray(colors, size, sizeof(SkColor4f));
273cb93a386Sopenharmony_ci}
274cb93a386Sopenharmony_ci
275cb93a386Sopenharmony_cibool SkReadBuffer::readIntArray(int32_t* values, size_t size) {
276cb93a386Sopenharmony_ci    return this->readArray(values, size, sizeof(int32_t));
277cb93a386Sopenharmony_ci}
278cb93a386Sopenharmony_ci
279cb93a386Sopenharmony_cibool SkReadBuffer::readPointArray(SkPoint* points, size_t size) {
280cb93a386Sopenharmony_ci    return this->readArray(points, size, sizeof(SkPoint));
281cb93a386Sopenharmony_ci}
282cb93a386Sopenharmony_ci
283cb93a386Sopenharmony_cibool SkReadBuffer::readScalarArray(SkScalar* values, size_t size) {
284cb93a386Sopenharmony_ci    return this->readArray(values, size, sizeof(SkScalar));
285cb93a386Sopenharmony_ci}
286cb93a386Sopenharmony_ci
287cb93a386Sopenharmony_ciconst void* SkReadBuffer::skipByteArray(size_t* size) {
288cb93a386Sopenharmony_ci    const uint32_t count = this->readUInt();
289cb93a386Sopenharmony_ci    const void* buf = this->skip(count);
290cb93a386Sopenharmony_ci    if (size) {
291cb93a386Sopenharmony_ci        *size = this->isValid() ? count : 0;
292cb93a386Sopenharmony_ci    }
293cb93a386Sopenharmony_ci    return buf;
294cb93a386Sopenharmony_ci}
295cb93a386Sopenharmony_ci
296cb93a386Sopenharmony_cisk_sp<SkData> SkReadBuffer::readByteArrayAsData() {
297cb93a386Sopenharmony_ci    size_t numBytes = this->getArrayCount();
298cb93a386Sopenharmony_ci    if (!this->validate(this->isAvailable(numBytes))) {
299cb93a386Sopenharmony_ci        return nullptr;
300cb93a386Sopenharmony_ci    }
301cb93a386Sopenharmony_ci
302cb93a386Sopenharmony_ci    SkAutoMalloc buffer(numBytes);
303cb93a386Sopenharmony_ci    if (!this->readByteArray(buffer.get(), numBytes)) {
304cb93a386Sopenharmony_ci        return nullptr;
305cb93a386Sopenharmony_ci    }
306cb93a386Sopenharmony_ci    return SkData::MakeFromMalloc(buffer.release(), numBytes);
307cb93a386Sopenharmony_ci}
308cb93a386Sopenharmony_ci
309cb93a386Sopenharmony_ciuint32_t SkReadBuffer::getArrayCount() {
310cb93a386Sopenharmony_ci    const size_t inc = sizeof(uint32_t);
311cb93a386Sopenharmony_ci    if (!this->validate(IsPtrAlign4(fCurr) && this->isAvailable(inc))) {
312cb93a386Sopenharmony_ci        return 0;
313cb93a386Sopenharmony_ci    }
314cb93a386Sopenharmony_ci    return *((uint32_t*)fCurr);
315cb93a386Sopenharmony_ci}
316cb93a386Sopenharmony_ci
317cb93a386Sopenharmony_ci#include "src/core/SkMipmap.h"
318cb93a386Sopenharmony_ci
319cb93a386Sopenharmony_ci// If we see a corrupt stream, we return null (fail). If we just fail trying to decode
320cb93a386Sopenharmony_ci// the image, we don't fail, but return a 1x1 empty image.
321cb93a386Sopenharmony_cisk_sp<SkImage> SkReadBuffer::readImage() {
322cb93a386Sopenharmony_ci    uint32_t flags = this->read32();
323cb93a386Sopenharmony_ci
324cb93a386Sopenharmony_ci    sk_sp<SkImage> image;
325cb93a386Sopenharmony_ci    {
326cb93a386Sopenharmony_ci        sk_sp<SkData> data = this->readByteArrayAsData();
327cb93a386Sopenharmony_ci        if (!data) {
328cb93a386Sopenharmony_ci            this->validate(false);
329cb93a386Sopenharmony_ci            return nullptr;
330cb93a386Sopenharmony_ci        }
331cb93a386Sopenharmony_ci        if (fProcs.fImageProc) {
332cb93a386Sopenharmony_ci            image = fProcs.fImageProc(data->data(), data->size(), fProcs.fImageCtx);
333cb93a386Sopenharmony_ci        }
334cb93a386Sopenharmony_ci        if (!image) {
335cb93a386Sopenharmony_ci            image = SkImage::MakeFromEncoded(std::move(data));
336cb93a386Sopenharmony_ci        }
337cb93a386Sopenharmony_ci    }
338cb93a386Sopenharmony_ci
339cb93a386Sopenharmony_ci    if (flags & SkWriteBufferImageFlags::kHasSubsetRect) {
340cb93a386Sopenharmony_ci        SkIRect subset;
341cb93a386Sopenharmony_ci        this->readIRect(&subset);
342cb93a386Sopenharmony_ci        if (image) {
343cb93a386Sopenharmony_ci            image = image->makeSubset(subset);
344cb93a386Sopenharmony_ci        }
345cb93a386Sopenharmony_ci    }
346cb93a386Sopenharmony_ci
347cb93a386Sopenharmony_ci    if (flags & SkWriteBufferImageFlags::kHasMipmap) {
348cb93a386Sopenharmony_ci        sk_sp<SkData> data = this->readByteArrayAsData();
349cb93a386Sopenharmony_ci        if (!data) {
350cb93a386Sopenharmony_ci            this->validate(false);
351cb93a386Sopenharmony_ci            return nullptr;
352cb93a386Sopenharmony_ci        }
353cb93a386Sopenharmony_ci        if (image) {
354cb93a386Sopenharmony_ci            SkMipmapBuilder builder(image->imageInfo());
355cb93a386Sopenharmony_ci            if (SkMipmap::Deserialize(&builder, data->data(), data->size())) {
356cb93a386Sopenharmony_ci                // TODO: need to make lazy images support mips
357cb93a386Sopenharmony_ci                if (auto ri = image->makeRasterImage()) {
358cb93a386Sopenharmony_ci                    image = ri;
359cb93a386Sopenharmony_ci                }
360cb93a386Sopenharmony_ci                image = builder.attachTo(image);
361cb93a386Sopenharmony_ci                SkASSERT(image);    // withMipmaps should never return null
362cb93a386Sopenharmony_ci            }
363cb93a386Sopenharmony_ci        }
364cb93a386Sopenharmony_ci    }
365cb93a386Sopenharmony_ci    return image ? image : MakeEmptyImage(1, 1);
366cb93a386Sopenharmony_ci}
367cb93a386Sopenharmony_ci
368cb93a386Sopenharmony_cisk_sp<SkTypeface> SkReadBuffer::readTypeface() {
369cb93a386Sopenharmony_ci    // Read 32 bits (signed)
370cb93a386Sopenharmony_ci    //   0 -- return null (default font)
371cb93a386Sopenharmony_ci    //  >0 -- index
372cb93a386Sopenharmony_ci    //  <0 -- custom (serial procs) : negative size in bytes
373cb93a386Sopenharmony_ci
374cb93a386Sopenharmony_ci    int32_t index = this->read32();
375cb93a386Sopenharmony_ci    if (index == 0) {
376cb93a386Sopenharmony_ci        return nullptr;
377cb93a386Sopenharmony_ci    } else if (index > 0) {
378cb93a386Sopenharmony_ci        if (!this->validate(index <= fTFCount)) {
379cb93a386Sopenharmony_ci            return nullptr;
380cb93a386Sopenharmony_ci        }
381cb93a386Sopenharmony_ci        return fTFArray[index - 1];
382cb93a386Sopenharmony_ci    } else {    // custom
383cb93a386Sopenharmony_ci        size_t size = sk_negate_to_size_t(index);
384cb93a386Sopenharmony_ci        const void* data = this->skip(size);
385cb93a386Sopenharmony_ci        if (!this->validate(data != nullptr && fProcs.fTypefaceProc)) {
386cb93a386Sopenharmony_ci            return nullptr;
387cb93a386Sopenharmony_ci        }
388cb93a386Sopenharmony_ci        return fProcs.fTypefaceProc(data, size, fProcs.fTypefaceCtx);
389cb93a386Sopenharmony_ci    }
390cb93a386Sopenharmony_ci}
391cb93a386Sopenharmony_ci
392cb93a386Sopenharmony_ciSkFlattenable* SkReadBuffer::readFlattenable(SkFlattenable::Type ft) {
393cb93a386Sopenharmony_ci    SkFlattenable::Factory factory = nullptr;
394cb93a386Sopenharmony_ci
395cb93a386Sopenharmony_ci    if (fFactoryCount > 0) {
396cb93a386Sopenharmony_ci        int32_t index = this->read32();
397cb93a386Sopenharmony_ci        if (0 == index || !this->isValid()) {
398cb93a386Sopenharmony_ci            return nullptr; // writer failed to give us the flattenable
399cb93a386Sopenharmony_ci        }
400cb93a386Sopenharmony_ci        index -= 1;     // we stored the index-base-1
401cb93a386Sopenharmony_ci        if ((unsigned)index >= (unsigned)fFactoryCount) {
402cb93a386Sopenharmony_ci            this->validate(false);
403cb93a386Sopenharmony_ci            return nullptr;
404cb93a386Sopenharmony_ci        }
405cb93a386Sopenharmony_ci        factory = fFactoryArray[index];
406cb93a386Sopenharmony_ci    } else {
407cb93a386Sopenharmony_ci        if (this->peekByte() != 0) {
408cb93a386Sopenharmony_ci            // If the first byte is non-zero, the flattenable is specified by a string.
409cb93a386Sopenharmony_ci            size_t ignored_length;
410cb93a386Sopenharmony_ci            if (const char* name = this->readString(&ignored_length)) {
411cb93a386Sopenharmony_ci                factory = SkFlattenable::NameToFactory(name);
412cb93a386Sopenharmony_ci                fFlattenableDict.set(fFlattenableDict.count() + 1, factory);
413cb93a386Sopenharmony_ci            }
414cb93a386Sopenharmony_ci        } else {
415cb93a386Sopenharmony_ci            // Read the index.  We are guaranteed that the first byte
416cb93a386Sopenharmony_ci            // is zeroed, so we must shift down a byte.
417cb93a386Sopenharmony_ci            uint32_t index = this->readUInt() >> 8;
418cb93a386Sopenharmony_ci            if (index == 0) {
419cb93a386Sopenharmony_ci                return nullptr; // writer failed to give us the flattenable
420cb93a386Sopenharmony_ci            }
421cb93a386Sopenharmony_ci
422cb93a386Sopenharmony_ci            if (SkFlattenable::Factory* found = fFlattenableDict.find(index)) {
423cb93a386Sopenharmony_ci                factory = *found;
424cb93a386Sopenharmony_ci            }
425cb93a386Sopenharmony_ci        }
426cb93a386Sopenharmony_ci
427cb93a386Sopenharmony_ci        if (!this->validate(factory != nullptr)) {
428cb93a386Sopenharmony_ci            return nullptr;
429cb93a386Sopenharmony_ci        }
430cb93a386Sopenharmony_ci    }
431cb93a386Sopenharmony_ci
432cb93a386Sopenharmony_ci    // if we get here, factory may still be null, but if that is the case, the
433cb93a386Sopenharmony_ci    // failure was ours, not the writer.
434cb93a386Sopenharmony_ci    sk_sp<SkFlattenable> obj;
435cb93a386Sopenharmony_ci    uint32_t sizeRecorded = this->read32();
436cb93a386Sopenharmony_ci    if (factory) {
437cb93a386Sopenharmony_ci        size_t offset = this->offset();
438cb93a386Sopenharmony_ci        obj = (*factory)(*this);
439cb93a386Sopenharmony_ci        // check that we read the amount we expected
440cb93a386Sopenharmony_ci        size_t sizeRead = this->offset() - offset;
441cb93a386Sopenharmony_ci        if (sizeRecorded != sizeRead) {
442cb93a386Sopenharmony_ci            this->validate(false);
443cb93a386Sopenharmony_ci            return nullptr;
444cb93a386Sopenharmony_ci        }
445cb93a386Sopenharmony_ci        if (obj && obj->getFlattenableType() != ft) {
446cb93a386Sopenharmony_ci            this->validate(false);
447cb93a386Sopenharmony_ci            return nullptr;
448cb93a386Sopenharmony_ci        }
449cb93a386Sopenharmony_ci    } else {
450cb93a386Sopenharmony_ci        // we must skip the remaining data
451cb93a386Sopenharmony_ci        this->skip(sizeRecorded);
452cb93a386Sopenharmony_ci    }
453cb93a386Sopenharmony_ci    if (!this->isValid()) {
454cb93a386Sopenharmony_ci        return nullptr;
455cb93a386Sopenharmony_ci    }
456cb93a386Sopenharmony_ci    return obj.release();
457cb93a386Sopenharmony_ci}
458cb93a386Sopenharmony_ci
459cb93a386Sopenharmony_ci///////////////////////////////////////////////////////////////////////////////////////////////////
460cb93a386Sopenharmony_ci
461cb93a386Sopenharmony_ciint32_t SkReadBuffer::checkInt(int32_t min, int32_t max) {
462cb93a386Sopenharmony_ci    SkASSERT(min <= max);
463cb93a386Sopenharmony_ci    int32_t value = this->read32();
464cb93a386Sopenharmony_ci    if (value < min || value > max) {
465cb93a386Sopenharmony_ci        this->validate(false);
466cb93a386Sopenharmony_ci        value = min;
467cb93a386Sopenharmony_ci    }
468cb93a386Sopenharmony_ci    return value;
469cb93a386Sopenharmony_ci}
470cb93a386Sopenharmony_ci
471cb93a386Sopenharmony_ciSkLegacyFQ SkReadBuffer::checkFilterQuality() {
472cb93a386Sopenharmony_ci    return this->checkRange<SkLegacyFQ>(kNone_SkLegacyFQ, kLast_SkLegacyFQ);
473cb93a386Sopenharmony_ci}
474