/*
 * Copyright 2016 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "SkCanvas.h"
#include "SkCanvasPriv.h"
#include "SkDeduper.h"
#include "SkDrawShadowInfo.h"
#include "SkPicture.h"
#include "SkPictureRecorder.h"
#include "SkPipe.h"
#include "SkPipeFormat.h"
#include "SkReadBuffer.h"
#include "SkRefSet.h"
#include "SkRSXform.h"
#include "SkTextBlobPriv.h"
#include "SkTypeface.h"
#include "SkVertices.h"

class SkPipeReader;

static bool do_playback(SkPipeReader& reader, SkCanvas* canvas, int* endPictureIndex = nullptr);

///////////////////////////////////////////////////////////////////////////////////////////////////

class SkPipeInflator : public SkInflator {
public:
    SkPipeInflator(SkRefSet<SkImage>* images, SkRefSet<SkPicture>* pictures,
                   SkRefSet<SkTypeface>* typefaces, SkTDArray<SkFlattenable::Factory>* factories,
                   const SkDeserialProcs& procs)
        : fImages(images)
        , fPictures(pictures)
        , fTypefaces(typefaces)
        , fFactories(factories)
        , fProcs(procs)
    {}

    SkImage* getImage(int index) override {
        return index ? fImages->get(index - 1) : nullptr;
    }
    SkPicture* getPicture(int index) override {
        return index ? fPictures->get(index - 1) : nullptr;
    }
    SkTypeface* getTypeface(int index) override {
        return fTypefaces->get(index - 1);
    }
    SkFlattenable::Factory getFactory(int index) override {
        return index ? fFactories->getAt(index - 1) : nullptr;
    }

    bool setImage(int index, sk_sp<SkImage> img) {
        return fImages->set(index - 1, std::move(img));
    }
    bool setPicture(int index, sk_sp<SkPicture> pic) {
        return fPictures->set(index - 1, std::move(pic));
    }
    bool setTypeface(int index, sk_sp<SkTypeface> face) {
        return fTypefaces->set(index - 1, std::move(face));
    }
    bool setFactory(int index, SkFlattenable::Factory factory) {
        SkASSERT(index > 0);
        SkASSERT(factory);
        index -= 1;
        if ((unsigned)index < (unsigned)fFactories->count()) {
            (*fFactories)[index] = factory;
            return true;
        }
        if (fFactories->count() == index) {
            *fFactories->append() = factory;
            return true;
        }
        SkDebugf("setFactory: index [%d] out of range %d\n", index, fFactories->count());
        return false;
    }

    void setDeserialProcs(const SkDeserialProcs& procs) {
        fProcs = procs;
    }

    sk_sp<SkTypeface> makeTypeface(const void* data, size_t size);
    sk_sp<SkImage> makeImage(const sk_sp<SkData>&);

private:
    SkRefSet<SkImage>*                  fImages;
    SkRefSet<SkPicture>*                fPictures;
    SkRefSet<SkTypeface>*               fTypefaces;
    SkTDArray<SkFlattenable::Factory>*  fFactories;
    SkDeserialProcs                     fProcs;
};

///////////////////////////////////////////////////////////////////////////////////////////////////

static SkRRect read_rrect(SkReadBuffer& reader) {
    SkRRect rrect;
    rrect.readFromMemory(reader.skip(SkRRect::kSizeInMemory), SkRRect::kSizeInMemory);
    return rrect;
}

static SkMatrix read_sparse_matrix(SkReadBuffer& reader, SkMatrix::TypeMask tm) {
    SkMatrix matrix;
    matrix.reset();

    if (tm & SkMatrix::kPerspective_Mask) {
        matrix.set9(reader.skipT<SkScalar>(9));
    } else if (tm & SkMatrix::kAffine_Mask) {
        const SkScalar* tmp = reader.skipT<SkScalar>(6);
        matrix[SkMatrix::kMScaleX] = tmp[0];
        matrix[SkMatrix::kMSkewX]  = tmp[1];
        matrix[SkMatrix::kMTransX] = tmp[2];
        matrix[SkMatrix::kMScaleY] = tmp[3];
        matrix[SkMatrix::kMSkewY]  = tmp[4];
        matrix[SkMatrix::kMTransY] = tmp[5];
    } else if (tm & SkMatrix::kScale_Mask) {
        const SkScalar* tmp = reader.skipT<SkScalar>(4);
        matrix[SkMatrix::kMScaleX] = tmp[0];
        matrix[SkMatrix::kMTransX] = tmp[1];
        matrix[SkMatrix::kMScaleY] = tmp[2];
        matrix[SkMatrix::kMTransY] = tmp[3];
    } else if (tm & SkMatrix::kTranslate_Mask) {
        const SkScalar* tmp = reader.skipT<SkScalar>(2);
        matrix[SkMatrix::kMTransX] = tmp[0];
        matrix[SkMatrix::kMTransY] = tmp[1];
    }
    // else read nothing for Identity
    return matrix;
}

///////////////////////////////////////////////////////////////////////////////////////////////////

#define CHECK_SET_SCALAR(Field)                 \
    do { if (nondef & k##Field##_NonDef) {      \
        paint.set##Field(reader.readScalar());  \
    }} while (0)

#define CHECK_SET_FLATTENABLE(Field)            \
    do { if (nondef & k##Field##_NonDef) {      \
        paint.set##Field(reader.read##Field()); \
    }} while (0)

/*
 *  Header:
 *      paint flags     : 32
 *      non_def bits    : 16
 *      xfermode enum   : 8
 *      pad zeros       : 8
 */
static SkPaint read_paint(SkReadBuffer& reader) {
    SkPaint paint;

    uint32_t packedFlags = reader.read32();
    uint32_t extra = reader.read32();
    unsigned nondef = extra >> 16;
    paint.setBlendMode(SkBlendMode((extra >> 8) & 0xFF));
    SkASSERT((extra & 0xFF) == 0);  // zero pad byte

    packedFlags >>= 2;  // currently unused
    paint.setTextEncoding((SkPaint::TextEncoding)(packedFlags & 3));    packedFlags >>= 2;
    paint.setTextAlign((SkPaint::Align)(packedFlags & 3));              packedFlags >>= 2;
    paint.setHinting((SkPaint::Hinting)(packedFlags & 3));              packedFlags >>= 2;
    paint.setStrokeJoin((SkPaint::Join)(packedFlags & 3));              packedFlags >>= 2;
    paint.setStrokeCap((SkPaint::Cap)(packedFlags & 3));                packedFlags >>= 2;
    paint.setStyle((SkPaint::Style)(packedFlags & 3));                  packedFlags >>= 2;
    paint.setFilterQuality((SkFilterQuality)(packedFlags & 3));         packedFlags >>= 2;
    paint.setFlags(packedFlags);

    CHECK_SET_SCALAR(TextSize);
    CHECK_SET_SCALAR(TextScaleX);
    CHECK_SET_SCALAR(TextSkewX);
    CHECK_SET_SCALAR(StrokeWidth);
    CHECK_SET_SCALAR(StrokeMiter);

    if (nondef & kColor_NonDef) {
        paint.setColor(reader.read32());
    }

    CHECK_SET_FLATTENABLE(Typeface);
    CHECK_SET_FLATTENABLE(PathEffect);
    CHECK_SET_FLATTENABLE(Shader);
    CHECK_SET_FLATTENABLE(MaskFilter);
    CHECK_SET_FLATTENABLE(ColorFilter);
    CHECK_SET_FLATTENABLE(ImageFilter);
    CHECK_SET_FLATTENABLE(DrawLooper);

    return paint;
}

class SkPipeReader : public SkReadBuffer {
public:
    SkPipeReader(SkPipeDeserializer* sink, const void* data, size_t size)
    : SkReadBuffer(data, size)
    , fSink(sink)
    {}

    SkPipeDeserializer* fSink;

    SkFlattenable::Factory findFactory(const char name[]) {
        SkFlattenable::Factory factory;
        // Check if a custom Factory has been specified for this flattenable.
        if (!(factory = this->getCustomFactory(SkString(name)))) {
            // If there is no custom Factory, check for a default.
            factory = SkFlattenable::NameToFactory(name);
        }
        return factory;
    }

    bool readPaint(SkPaint* paint) override {
        *paint = read_paint(*this);
        return this->isValid();
    }
};

///////////////////////////////////////////////////////////////////////////////////////////////////

typedef void (*SkPipeHandler)(SkPipeReader&, uint32_t packedVerb, SkCanvas*);

static void save_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
    SkASSERT(SkPipeVerb::kSave == unpack_verb(packedVerb));
    canvas->save();
}

static void saveLayer_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
    SkASSERT(SkPipeVerb::kSaveLayer == unpack_verb(packedVerb));
    unsigned extra = unpack_verb_extra(packedVerb);
    const SkRect* bounds = (extra & kHasBounds_SaveLayerMask) ? reader.skipT<SkRect>() : nullptr;
    SkPaint paintStorage, *paint = nullptr;
    if (extra & kHasPaint_SaveLayerMask) {
        paintStorage = read_paint(reader);
        paint = &paintStorage;
    }
    sk_sp<SkImageFilter> backdrop;
    if (extra & kHasBackdrop_SaveLayerMask) {
        backdrop = reader.readImageFilter();
    }
    sk_sp<SkImage> clipMask;
    if (extra & kHasClipMask_SaveLayerMask) {
        clipMask = reader.readImage();
    }
    SkMatrix clipMatrix;
    if (extra & kHasClipMatrix_SaveLayerMask) {
        reader.readMatrix(&clipMatrix);
    }
    SkCanvas::SaveLayerFlags flags = (SkCanvas::SaveLayerFlags)(extra & kFlags_SaveLayerMask);

    // unremap this wacky flag
    if (extra & kDontClipToLayer_SaveLayerMask) {
        flags |= SkCanvasPriv::kDontClipToLayer_SaveLayerFlag;
    }

    canvas->saveLayer(SkCanvas::SaveLayerRec(bounds, paint, backdrop.get(), clipMask.get(),
                      (extra & kHasClipMatrix_SaveLayerMask) ? &clipMatrix : nullptr, flags));
}

static void restore_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
    SkASSERT(SkPipeVerb::kRestore == unpack_verb(packedVerb));
    canvas->restore();
}

static void concat_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
    SkASSERT(SkPipeVerb::kConcat == unpack_verb(packedVerb));
    SkMatrix::TypeMask tm = (SkMatrix::TypeMask)(packedVerb & kTypeMask_ConcatMask);
    const SkMatrix matrix = read_sparse_matrix(reader, tm);
    if (packedVerb & kSetMatrix_ConcatMask) {
        canvas->setMatrix(matrix);
    } else {
        canvas->concat(matrix);
    }
}

static void clipRect_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
    SkASSERT(SkPipeVerb::kClipRect == unpack_verb(packedVerb));
    SkClipOp op = (SkClipOp)(unpack_verb_extra(packedVerb) >> 1);
    bool isAA = unpack_verb_extra(packedVerb) & 1;
    canvas->clipRect(*reader.skipT<SkRect>(), op, isAA);
}

static void clipRRect_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
    SkASSERT(SkPipeVerb::kClipRRect == unpack_verb(packedVerb));
    SkClipOp op = (SkClipOp)(unpack_verb_extra(packedVerb) >> 1);
    bool isAA = unpack_verb_extra(packedVerb) & 1;
    canvas->clipRRect(read_rrect(reader), op, isAA);
}

static void clipPath_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
    SkASSERT(SkPipeVerb::kClipPath == unpack_verb(packedVerb));
    SkClipOp op = (SkClipOp)(unpack_verb_extra(packedVerb) >> 1);
    bool isAA = unpack_verb_extra(packedVerb) & 1;
    SkPath path;
    reader.readPath(&path);
    canvas->clipPath(path, op, isAA);
}

static void clipRegion_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
    SkASSERT(SkPipeVerb::kClipRegion == unpack_verb(packedVerb));
    SkClipOp op = (SkClipOp)(unpack_verb_extra(packedVerb) >> 1);
    SkRegion region;
    reader.readRegion(&region);
    canvas->clipRegion(region, op);
}

static void drawArc_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
    SkASSERT(SkPipeVerb::kDrawArc == unpack_verb(packedVerb));
    const bool useCenter = (bool)(unpack_verb_extra(packedVerb) & 1);
    const SkScalar* scalars = reader.skipT<SkScalar>(6);    // bounds[0..3], start[4], sweep[5]
    const SkRect* bounds = (const SkRect*)scalars;
    canvas->drawArc(*bounds, scalars[4], scalars[5], useCenter, read_paint(reader));
}

static void drawAtlas_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
    SkASSERT(SkPipeVerb::kDrawAtlas == unpack_verb(packedVerb));
    SkBlendMode mode = (SkBlendMode)(packedVerb & kMode_DrawAtlasMask);
    sk_sp<SkImage> image(reader.readImage());
    int count = reader.read32();
    const SkRSXform* xform = reader.skipT<SkRSXform>(count);
    const SkRect* rect = reader.skipT<SkRect>(count);
    const SkColor* color = nullptr;
    if (packedVerb & kHasColors_DrawAtlasMask) {
        color = reader.skipT<SkColor>(count);
    }
    const SkRect* cull = nullptr;
    if (packedVerb & kHasCull_DrawAtlasMask) {
        cull = reader.skipT<SkRect>();
    }
    SkPaint paintStorage, *paint = nullptr;
    if (packedVerb & kHasPaint_DrawAtlasMask) {
        paintStorage = read_paint(reader);
        paint = &paintStorage;
    }
    canvas->drawAtlas(image, xform, rect, color, count, mode, cull, paint);
}

static void drawDRRect_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
    SkASSERT(SkPipeVerb::kDrawDRRect == unpack_verb(packedVerb));
    const SkRRect outer = read_rrect(reader);
    const SkRRect inner = read_rrect(reader);
    canvas->drawDRRect(outer, inner, read_paint(reader));
}

static void drawText_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
    SkASSERT(SkPipeVerb::kDrawText == unpack_verb(packedVerb));
    uint32_t len = unpack_verb_extra(packedVerb);
    if (0 == len) {
        len = reader.read32();
    }
    const void* text = reader.skip(SkAlign4(len));
    SkScalar x = reader.readScalar();
    SkScalar y = reader.readScalar();
    canvas->drawText(text, len, x, y, read_paint(reader));
}

static void drawPosText_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
    SkASSERT(SkPipeVerb::kDrawPosText == unpack_verb(packedVerb));
    uint32_t len = unpack_verb_extra(packedVerb);
    if (0 == len) {
        len = reader.read32();
    }
    const void* text = reader.skip(SkAlign4(len));
    int count = reader.read32();
    const SkPoint* pos = reader.skipT<SkPoint>(count);
    SkPaint paint = read_paint(reader);
    SkASSERT(paint.countText(text, len) == count);
    canvas->drawPosText(text, len, pos, paint);
}

static void drawPosTextH_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
    SkASSERT(SkPipeVerb::kDrawPosTextH == unpack_verb(packedVerb));
    uint32_t len = unpack_verb_extra(packedVerb);
    if (0 == len) {
        len = reader.read32();
    }
    const void* text = reader.skip(SkAlign4(len));
    int count = reader.read32();
    const SkScalar* xpos = reader.skipT<SkScalar>(count);
    SkScalar constY = reader.readScalar();
    SkPaint paint = read_paint(reader);
    SkASSERT(paint.countText(text, len) == count);
    canvas->drawPosTextH(text, len, xpos, constY, paint);
}

static void drawTextBlob_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
    sk_sp<SkTextBlob> tb = SkTextBlobPriv::MakeFromBuffer(reader);
    SkScalar x = reader.readScalar();
    SkScalar y = reader.readScalar();
    canvas->drawTextBlob(tb, x, y, read_paint(reader));
}

static void drawTextRSXform_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
    SkASSERT(SkPipeVerb::kDrawTextRSXform == unpack_verb(packedVerb));
    uint32_t len = unpack_verb_extra(packedVerb) >> 1;
    if (0 == len) {
        len = reader.read32();
    }
    const void* text = reader.skip(SkAlign4(len));
    int count = reader.read32();
    const SkRSXform* xform = reader.skipT<SkRSXform>(count);
    const SkRect* cull = (packedVerb & 1) ? reader.skipT<SkRect>() : nullptr;
    SkPaint paint = read_paint(reader);
    SkASSERT(paint.countText(text, len) == count);
    canvas->drawTextRSXform(text, len, xform, cull, paint);
}

static void drawPatch_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
    SkASSERT(SkPipeVerb::kDrawPatch == unpack_verb(packedVerb));
    const SkColor* colors = nullptr;
    const SkPoint* tex = nullptr;
    const SkPoint* cubics = reader.skipT<SkPoint>(12);
    if (packedVerb & kHasColors_DrawPatchExtraMask) {
        colors = reader.skipT<SkColor>(4);
    }
    if (packedVerb & kHasTexture_DrawPatchExtraMask) {
        tex = reader.skipT<SkPoint>(4);
    }
    SkBlendMode mode = (SkBlendMode)(packedVerb & kModeEnum_DrawPatchExtraMask);
    canvas->drawPatch(cubics, colors, tex, mode, read_paint(reader));
}

static void drawPaint_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
    SkASSERT(SkPipeVerb::kDrawPaint == unpack_verb(packedVerb));
    canvas->drawPaint(read_paint(reader));
}

static void drawRect_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
    SkASSERT(SkPipeVerb::kDrawRect == unpack_verb(packedVerb));
    const SkRect* rect = reader.skipT<SkRect>();
    canvas->drawRect(*rect, read_paint(reader));
}

static void drawRegion_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
    SkASSERT(SkPipeVerb::kDrawRegion == unpack_verb(packedVerb));
    size_t size = unpack_verb_extra(packedVerb);
    if (0 == size) {
        size = reader.read32();
    }
    SkRegion region;
    region.readFromMemory(reader.skipT<char>(size), size);
    canvas->drawRegion(region, read_paint(reader));
}

static void drawOval_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
    SkASSERT(SkPipeVerb::kDrawOval == unpack_verb(packedVerb));
    const SkRect* rect = reader.skipT<SkRect>();
    canvas->drawOval(*rect, read_paint(reader));
}

static void drawRRect_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
    SkASSERT(SkPipeVerb::kDrawRRect == unpack_verb(packedVerb));
    SkRRect rrect = read_rrect(reader);
    canvas->drawRRect(rrect, read_paint(reader));
}

static void drawPath_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
    SkASSERT(SkPipeVerb::kDrawPath == unpack_verb(packedVerb));
    SkPath path;
    reader.readPath(&path);
    canvas->drawPath(path, read_paint(reader));
}

static void drawShadowRec_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
    SkASSERT(SkPipeVerb::kDrawShadowRec == unpack_verb(packedVerb));
    SkPath path;
    reader.readPath(&path);
    SkDrawShadowRec rec;
    reader.readPad32(&rec, sizeof(rec));
    canvas->private_draw_shadow_rec(path, rec);
}

static void drawPoints_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
    SkASSERT(SkPipeVerb::kDrawPoints == unpack_verb(packedVerb));
    SkCanvas::PointMode mode = (SkCanvas::PointMode)unpack_verb_extra(packedVerb);
    int count = reader.read32();
    const SkPoint* points = reader.skipT<SkPoint>(count);
    canvas->drawPoints(mode, count, points, read_paint(reader));
}

static void drawImage_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
    SkASSERT(SkPipeVerb::kDrawImage == unpack_verb(packedVerb));
    sk_sp<SkImage> image(reader.readImage());
    SkScalar x = reader.readScalar();
    SkScalar y = reader.readScalar();
    SkPaint paintStorage, *paint = nullptr;
    if (packedVerb & kHasPaint_DrawImageMask) {
        paintStorage = read_paint(reader);
        paint = &paintStorage;
    }
    canvas->drawImage(image, x, y, paint);
}

static void drawImageRect_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
    SkASSERT(SkPipeVerb::kDrawImageRect == unpack_verb(packedVerb));
    sk_sp<SkImage> image(reader.readImage());
    SkCanvas::SrcRectConstraint constraint =
            (SkCanvas::SrcRectConstraint)(packedVerb & kConstraint_DrawImageRectMask);
    const SkRect* src = (packedVerb & kHasSrcRect_DrawImageRectMask) ?
                        reader.skipT<SkRect>() : nullptr;
    const SkRect* dst = reader.skipT<SkRect>();
    SkPaint paintStorage, *paint = nullptr;
    if (packedVerb & kHasPaint_DrawImageRectMask) {
        paintStorage = read_paint(reader);
        paint = &paintStorage;
    }
    if (src) {
        canvas->drawImageRect(image, *src, *dst, paint, constraint);
    } else {
        canvas->drawImageRect(image, *dst, paint);
    }
}

static void drawImageNine_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
    SkASSERT(SkPipeVerb::kDrawImageNine == unpack_verb(packedVerb));
    sk_sp<SkImage> image(reader.readImage());
    const SkIRect* center = reader.skipT<SkIRect>();
    const SkRect* dst = reader.skipT<SkRect>();
    SkPaint paintStorage, *paint = nullptr;
    if (packedVerb & kHasPaint_DrawImageNineMask) {
        paintStorage = read_paint(reader);
        paint = &paintStorage;
    }
    canvas->drawImageNine(image, *center, *dst, paint);
}

static void drawImageLattice_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
    SkASSERT(SkPipeVerb::kDrawImageLattice == unpack_verb(packedVerb));
    sk_sp<SkImage> image(reader.readImage());

    SkCanvas::Lattice lattice;
    if (!SkCanvasPriv::ReadLattice(reader, &lattice)) {
        return;
    }
    const SkRect* dst = reader.skipT<SkRect>();

    SkPaint paintStorage, *paint = nullptr;
    if (packedVerb & kHasPaint_DrawImageLatticeMask) {
        paintStorage = read_paint(reader);
        paint = &paintStorage;
    }
    canvas->drawImageLattice(image.get(), lattice, *dst, paint);
}

static void drawVertices_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
    SkASSERT(SkPipeVerb::kDrawVertices == unpack_verb(packedVerb));
    SkBlendMode bmode = (SkBlendMode)unpack_verb_extra(packedVerb);
    sk_sp<SkVertices> vertices = nullptr;
    if (sk_sp<SkData> data = reader.readByteArrayAsData()) {
        vertices = SkVertices::Decode(data->data(), data->size());
    }
    int boneCount = reader.read32();
    const SkVertices::Bone* bones = boneCount ? reader.skipT<SkVertices::Bone>(boneCount) : nullptr;
    if (vertices) {
        canvas->drawVertices(vertices, bones, boneCount, bmode, read_paint(reader));
    }
}

static void drawPicture_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
    SkASSERT(SkPipeVerb::kDrawPicture == unpack_verb(packedVerb));
    unsigned extra = unpack_verb_extra(packedVerb);
    int index = extra & kIndex_ObjectDefinitionMask;
    SkPicture* pic = reader.getInflator()->getPicture(index);
    SkMatrix matrixStorage, *matrix = nullptr;
    SkPaint paintStorage, *paint = nullptr;
    if (extra & kHasMatrix_DrawPictureExtra) {
        reader.readMatrix(&matrixStorage);
        matrix = &matrixStorage;
    }
    if (extra & kHasPaint_DrawPictureExtra) {
        paintStorage = read_paint(reader);
        paint = &paintStorage;
    }
    canvas->drawPicture(pic, matrix, paint);
}

static void drawAnnotation_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
    SkASSERT(SkPipeVerb::kDrawAnnotation == unpack_verb(packedVerb));
    const SkRect* rect = reader.skipT<SkRect>();

    // len includes the key's trailing 0
    uint32_t len = unpack_verb_extra(packedVerb) >> 1;
    if (0 == len) {
        len = reader.read32();
    }
    const char* key = reader.skipT<char>(len);
    sk_sp<SkData> data;
    if (packedVerb & 1) {
        uint32_t size = reader.read32();
        data = SkData::MakeWithCopy(reader.skip(SkAlign4(size)), size);
    }
    canvas->drawAnnotation(*rect, key, data);
}

#if 0
        stream.write("skiacodc", 8);
        stream.write32(pmap.width());
        stream.write32(pmap.height());
        stream.write16(pmap.colorType());
        stream.write16(pmap.alphaType());
        stream.write32(0);  // no colorspace for now
        for (int y = 0; y < pmap.height(); ++y) {
            stream.write(pmap.addr8(0, y), pmap.width());
        }
#endif

sk_sp<SkImage> SkPipeInflator::makeImage(const sk_sp<SkData>& data) {
    if (fProcs.fImageProc) {
        return fProcs.fImageProc(data->data(), data->size(), fProcs.fImageCtx);
    }
    return SkImage::MakeFromEncoded(data);
}


static void defineImage_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas*) {
    SkASSERT(SkPipeVerb::kDefineImage == unpack_verb(packedVerb));
    SkPipeInflator* inflator = (SkPipeInflator*)reader.getInflator();
    uint32_t extra = unpack_verb_extra(packedVerb);
    int index = extra & kIndex_ObjectDefinitionMask;

    if (extra & kUndef_ObjectDefinitionMask) {
        // zero-index means we are "forgetting" that cache entry
        inflator->setImage(index, nullptr);
    } else {
        // we are defining a new image
        sk_sp<SkData> data = reader.readByteArrayAsData();
        sk_sp<SkImage> image = data ? inflator->makeImage(data) : nullptr;
        if (!image) {
            SkDebugf("-- failed to decode\n");
        }
        inflator->setImage(index, std::move(image));
    }
}

sk_sp<SkTypeface> SkPipeInflator::makeTypeface(const void* data, size_t size) {
    if (fProcs.fTypefaceProc) {
        return fProcs.fTypefaceProc(data, size, fProcs.fTypefaceCtx);
    }
    SkMemoryStream stream(data, size, false);
    return SkTypeface::MakeDeserialize(&stream);
}

static void defineTypeface_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
    SkASSERT(SkPipeVerb::kDefineTypeface == unpack_verb(packedVerb));
    SkPipeInflator* inflator = (SkPipeInflator*)reader.getInflator();
    uint32_t extra = unpack_verb_extra(packedVerb);
    int index = extra & kIndex_ObjectDefinitionMask;

    if (extra & kUndef_ObjectDefinitionMask) {
        // zero-index means we are "forgetting" that cache entry
        inflator->setTypeface(index, nullptr);
    } else {
        // we are defining a new image
        sk_sp<SkData> data = reader.readByteArrayAsData();
        // TODO: seems like we could "peek" to see the array, and not need to copy it.
        sk_sp<SkTypeface> tf = data ? inflator->makeTypeface(data->data(), data->size()) : nullptr;
        inflator->setTypeface(index, std::move(tf));
    }
}

static void defineFactory_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
    SkASSERT(SkPipeVerb::kDefineFactory == unpack_verb(packedVerb));
    SkPipeInflator* inflator = (SkPipeInflator*)reader.getInflator();
    uint32_t extra = unpack_verb_extra(packedVerb);
    int index = extra >> kNameLength_DefineFactoryExtraBits;
    size_t len = extra & kNameLength_DefineFactoryExtraMask;
    // +1 for the trailing null char
    const char* name = (const char*)reader.skip(SkAlign4(len + 1));
    SkFlattenable::Factory factory = reader.findFactory(name);
    if (factory) {
        inflator->setFactory(index, factory);
    }
}

static void definePicture_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
    SkASSERT(SkPipeVerb::kDefinePicture == unpack_verb(packedVerb));
    int deleteIndex = unpack_verb_extra(packedVerb);

    SkPipeInflator* inflator = (SkPipeInflator*)reader.getInflator();

    if (deleteIndex) {
        inflator->setPicture(deleteIndex - 1, nullptr);
    } else {
        SkPictureRecorder recorder;
        int pictureIndex = -1;  // invalid
        const SkRect* cull = reader.skipT<SkRect>();
        if (!cull) {
            return;
        }
        do_playback(reader, recorder.beginRecording(*cull), &pictureIndex);
        SkASSERT(pictureIndex > 0);
        sk_sp<SkPicture> picture = recorder.finishRecordingAsPicture();
        inflator->setPicture(pictureIndex, std::move(picture));
    }
}

static void endPicture_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
    SK_ABORT("not reached");  // never call me
}

///////////////////////////////////////////////////////////////////////////////////////////////////

struct HandlerRec {
    SkPipeHandler   fProc;
    const char*     fName;
};

#define HANDLER(name)   { name##_handler, #name }
const HandlerRec gPipeHandlers[] = {
    HANDLER(save),
    HANDLER(saveLayer),
    HANDLER(restore),
    HANDLER(concat),

    HANDLER(clipRect),
    HANDLER(clipRRect),
    HANDLER(clipPath),
    HANDLER(clipRegion),

    HANDLER(drawArc),
    HANDLER(drawAtlas),
    HANDLER(drawDRRect),
    HANDLER(drawText),
    HANDLER(drawPosText),
    HANDLER(drawPosTextH),
    HANDLER(drawRegion),
    HANDLER(drawTextBlob),
    HANDLER(drawTextRSXform),
    HANDLER(drawPatch),
    HANDLER(drawPaint),
    HANDLER(drawPoints),
    HANDLER(drawRect),
    HANDLER(drawPath),
    HANDLER(drawShadowRec),
    HANDLER(drawOval),
    HANDLER(drawRRect),

    HANDLER(drawImage),
    HANDLER(drawImageRect),
    HANDLER(drawImageNine),
    HANDLER(drawImageLattice),

    HANDLER(drawVertices),

    HANDLER(drawPicture),
    HANDLER(drawAnnotation),

    HANDLER(defineImage),
    HANDLER(defineTypeface),
    HANDLER(defineFactory),
    HANDLER(definePicture),
    HANDLER(endPicture),        // handled special -- should never be called
};
#undef HANDLER

///////////////////////////////////////////////////////////////////////////////////////////////////

class SkPipeDeserializer::Impl {
public:
    SkRefSet<SkImage>                   fImages;
    SkRefSet<SkPicture>                 fPictures;
    SkRefSet<SkTypeface>                fTypefaces;
    SkTDArray<SkFlattenable::Factory>   fFactories;
    SkDeserialProcs                     fProcs;
};

SkPipeDeserializer::SkPipeDeserializer() : fImpl(new Impl) {}
SkPipeDeserializer::~SkPipeDeserializer() {}

void SkPipeDeserializer::setDeserialProcs(const SkDeserialProcs& procs) {
    fImpl->fProcs = procs;
}

sk_sp<SkImage> SkPipeDeserializer::readImage(const void* data, size_t size) {
    if (size < sizeof(uint32_t)) {
        SkDebugf("-------- data length too short for readImage %d\n", size);
        return nullptr;
    }

    const uint32_t* ptr = (const uint32_t*)data;
    uint32_t packedVerb = *ptr++;
    size -= 4;

    if (SkPipeVerb::kDefineImage == unpack_verb(packedVerb)) {
        SkPipeInflator inflator(&fImpl->fImages, &fImpl->fPictures,
                                &fImpl->fTypefaces, &fImpl->fFactories,
                                fImpl->fProcs);
        SkPipeReader reader(this, ptr, size);
        reader.setInflator(&inflator);
        defineImage_handler(reader, packedVerb, nullptr);
        packedVerb = reader.read32();  // read the next verb
    }
    if (SkPipeVerb::kWriteImage != unpack_verb(packedVerb)) {
        SkDebugf("-------- unexpected verb for readImage %d\n", unpack_verb(packedVerb));
        return nullptr;
    }
    int index = unpack_verb_extra(packedVerb);
    if (0 == index) {
        return nullptr; // writer failed
    }
    return sk_ref_sp(fImpl->fImages.get(index - 1));
}

sk_sp<SkPicture> SkPipeDeserializer::readPicture(const void* data, size_t size) {
    if (size < sizeof(uint32_t)) {
        SkDebugf("-------- data length too short for readPicture %d\n", size);
        return nullptr;
    }

    const uint32_t* ptr = (const uint32_t*)data;
    uint32_t packedVerb = *ptr++;
    size -= 4;

    if (SkPipeVerb::kDefinePicture == unpack_verb(packedVerb)) {
        SkPipeInflator inflator(&fImpl->fImages, &fImpl->fPictures,
                                &fImpl->fTypefaces, &fImpl->fFactories,
                                fImpl->fProcs);
        SkPipeReader reader(this, ptr, size);
        reader.setInflator(&inflator);
        definePicture_handler(reader, packedVerb, nullptr);
        packedVerb = reader.read32();  // read the next verb
    }
    if (SkPipeVerb::kWritePicture != unpack_verb(packedVerb)) {
        SkDebugf("-------- unexpected verb for readPicture %d\n", unpack_verb(packedVerb));
        return nullptr;
    }
    int index = unpack_verb_extra(packedVerb);
    if (0 == index) {
        return nullptr; // writer failed
    }
    return sk_ref_sp(fImpl->fPictures.get(index - 1));
}

static bool do_playback(SkPipeReader& reader, SkCanvas* canvas, int* endPictureIndex) {
    int indent = 0;

    const bool showEachVerb = false;
    int counter = 0;
    while (!reader.eof()) {
        uint32_t prevOffset = reader.offset();
        uint32_t packedVerb = reader.read32();
        SkPipeVerb verb = unpack_verb(packedVerb);
        if ((unsigned)verb >= SK_ARRAY_COUNT(gPipeHandlers)) {
            SkDebugf("------- bad verb %d\n", verb);
            return false;
        }
        if (SkPipeVerb::kRestore == verb) {
            indent -= 1;
            SkASSERT(indent >= 0);
        }

        if (SkPipeVerb::kEndPicture == verb) {
            if (endPictureIndex) {
                *endPictureIndex = unpack_verb_extra(packedVerb);
            }
            return true;
        }
        HandlerRec rec = gPipeHandlers[(unsigned)verb];
        rec.fProc(reader, packedVerb, canvas);
        if (showEachVerb) {
            for (int i = 0; i < indent; ++i) {
                SkDebugf("    ");
            }
            SkDebugf("%d [%d] %s %d\n", prevOffset, counter++, rec.fName, reader.offset() - prevOffset);
        }
        if (!reader.isValid()) {
            SkDebugf("-------- bad reader\n");
            return false;
        }

        switch (verb) {
            case SkPipeVerb::kSave:
            case SkPipeVerb::kSaveLayer:
                indent += 1;
                break;
            default:
                break;
        }
    }
    return true;
}

bool SkPipeDeserializer::playback(const void* data, size_t size, SkCanvas* canvas) {
    SkPipeInflator inflator(&fImpl->fImages, &fImpl->fPictures,
                            &fImpl->fTypefaces, &fImpl->fFactories,
                            fImpl->fProcs);
    SkPipeReader reader(this, data, size);
    reader.setInflator(&inflator);
    return do_playback(reader, canvas);
}

