/*
 * 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 "SkTextBlob.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, SkImage* img) {
        return fImages->set(index - 1, img);
    }
    bool setPicture(int index, SkPicture* pic) {
        return fPictures->set(index - 1, pic);
    }
    bool setTypeface(int index, SkTypeface* face) {
        return fTypefaces->set(index - 1, 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 drawTextOnPath_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
    SkASSERT(SkPipeVerb::kDrawTextOnPath == unpack_verb(packedVerb));
    uint32_t byteLength = packedVerb & kTextLength_DrawTextOnPathMask;
    SkMatrix::TypeMask tm = (SkMatrix::TypeMask)
            ((packedVerb & kMatrixType_DrawTextOnPathMask) >> kMatrixType_DrawTextOnPathShift);

    if (0 == byteLength) {
        byteLength = reader.read32();
    }
    const void* text = reader.skip(SkAlign4(byteLength));
    SkPath path;
    reader.readPath(&path);
    const SkMatrix* matrix = nullptr;
    SkMatrix matrixStorage;
    if (tm != SkMatrix::kIdentity_Mask) {
        matrixStorage = read_sparse_matrix(reader, tm);
        matrix = &matrixStorage;
    }
    canvas->drawTextOnPath(text, byteLength, path, matrix, read_paint(reader));
}

static void drawTextBlob_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
    sk_sp<SkTextBlob> tb = SkTextBlob::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);
    if (sk_sp<SkData> data = reader.readByteArrayAsData()) {
        canvas->drawVertices(SkVertices::Decode(data->data(), data->size()), 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, image.get());
    }
}

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, tf.get());
    }
}

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, picture.get());
    }
}

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(drawTextOnPath),
    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);
}

