/*
 * 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 "SkDeduper.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"

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,
                   SkTypefaceDeserializer* tfd)
        : fImages(images)
        , fPictures(pictures)
        , fTypefaces(typefaces)
        , fFactories(factories)
        , fTFDeserializer(tfd)
    {}
    
    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 setTypefaceDeserializer(SkTypefaceDeserializer* tfd) {
        fTFDeserializer = tfd;
    }

    sk_sp<SkTypeface> makeTypeface(const void* data, size_t size);

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

    SkTypefaceDeserializer*             fTFDeserializer;
};

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

template <typename T> const T* skip(SkReadBuffer& reader, int count = 1) {
    return (const T*)reader.skip(count * sizeof(T));
}

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(skip<SkScalar>(reader, 9));
    } else if (tm & SkMatrix::kAffine_Mask) {
        const SkScalar* tmp = skip<SkScalar>(reader, 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 = skip<SkScalar>(reader, 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 = skip<SkScalar>(reader, 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) {
    uint32_t packedFlags = reader.read32();
    uint32_t extra = reader.read32();
    unsigned nondef = extra >> 16;
    SkXfermode::Mode mode = (SkXfermode::Mode)((extra >> 8) & 0xFF);
    SkASSERT((extra & 0xFF) == 0);

    SkPaint paint;

    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(Xfermode);
    CHECK_SET_FLATTENABLE(MaskFilter);
    CHECK_SET_FLATTENABLE(ColorFilter);
    CHECK_SET_FLATTENABLE(Rasterizer);
    CHECK_SET_FLATTENABLE(ImageFilter);
    CHECK_SET_FLATTENABLE(DrawLooper);

    if (!(nondef & kXfermode_NonDef)) {
        paint.setXfermodeMode(mode);
    }

    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;
    }
    
    void readPaint(SkPaint* paint) override {
        *paint = read_paint(*this);
    }
};

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

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) ? skip<SkRect>(reader) : 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();
    }
    SkCanvas::SaveLayerFlags flags = (SkCanvas::SaveLayerFlags)(extra & kFlags_SaveLayerMask);

    // unremap this wacky flag
    if (extra & kDontClipToLayer_SaveLayerMask) {
        flags |= (1 << 31);//SkCanvas::kDontClipToLayer_PrivateSaveLayerFlag;
    }

    canvas->saveLayer(SkCanvas::SaveLayerRec(bounds, paint, backdrop.get(), 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));
    SkRegion::Op op = (SkRegion::Op)(unpack_verb_extra(packedVerb) >> 1);
    bool isAA = unpack_verb_extra(packedVerb) & 1;
    canvas->clipRect(*skip<SkRect>(reader), op, isAA);
}

static void clipRRect_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
    SkASSERT(SkPipeVerb::kClipRRect == unpack_verb(packedVerb));
    SkRegion::Op op = (SkRegion::Op)(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));
    SkRegion::Op op = (SkRegion::Op)(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));
    SkRegion::Op op = (SkRegion::Op)(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 = skip<SkScalar>(reader, 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));
    SkXfermode::Mode mode = (SkXfermode::Mode)(packedVerb & kMode_DrawAtlasMask);
    sk_sp<SkImage> image(reader.readImage());
    int count = reader.read32();
    const SkRSXform* xform = skip<SkRSXform>(reader, count);
    const SkRect* rect = skip<SkRect>(reader, count);
    const SkColor* color = nullptr;
    if (packedVerb & kHasColors_DrawAtlasMask) {
        color = skip<SkColor>(reader, count);
    }
    const SkRect* cull = nullptr;
    if (packedVerb & kHasCull_DrawAtlasMask) {
        cull = skip<SkRect>(reader);
    }
    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 = skip<SkPoint>(reader, 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 = skip<SkScalar>(reader, 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 = skip<SkRSXform>(reader, count);
    const SkRect* cull = (packedVerb & 1) ? skip<SkRect>(reader) : 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 = skip<SkPoint>(reader, 12);
    if (packedVerb & kHasColors_DrawPatchExtraMask) {
        colors = skip<SkColor>(reader, 4);
    }
    if (packedVerb & kHasTexture_DrawPatchExtraMask) {
        tex = skip<SkPoint>(reader, 4);
    }
    sk_sp<SkXfermode> xfer;
    unsigned mode = packedVerb & kModeEnum_DrawPatchExtraMask;
    if (kExplicitXfer_DrawPatchExtraValue == mode) {
        xfer = reader.readXfermode();
    } else {
        if (mode != SkXfermode::kSrcOver_Mode) {
            xfer = SkXfermode::Make((SkXfermode::Mode)mode);
        }
    }
    canvas->drawPatch(cubics, colors, tex, xfer.get(), 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 = skip<SkRect>(reader);
    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(skip<char>(reader, SkAlign4(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 = skip<SkRect>(reader);
    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 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 = skip<SkPoint>(reader, 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) ?
                        skip<SkRect>(reader) : nullptr;
    const SkRect* dst = skip<SkRect>(reader);
    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 = skip<SkIRect>(reader);
    const SkRect* dst = skip<SkRect>(reader);
    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;
    lattice.fXCount = (packedVerb >> kXCount_DrawImageLatticeShift) & kCount_DrawImageLatticeMask;
    if (lattice.fXCount == kCount_DrawImageLatticeMask) {
        lattice.fXCount = reader.read32();
    }
    lattice.fYCount = (packedVerb >> kXCount_DrawImageLatticeShift) & kCount_DrawImageLatticeMask;
    if (lattice.fYCount == kCount_DrawImageLatticeMask) {
        lattice.fYCount = reader.read32();
    }
    lattice.fXDivs = skip<int32_t>(reader, lattice.fXCount);
    lattice.fYDivs = skip<int32_t>(reader, lattice.fYCount);
    if (packedVerb & kHasFlags_DrawImageLatticeMask) {
        int32_t count = (lattice.fXCount + 1) * (lattice.fYCount + 1);
        SkASSERT(count > 0);
        lattice.fFlags = skip<SkCanvas::Lattice::Flags>(reader, SkAlign4(count));
    } else {
        lattice.fFlags = nullptr;
    }
    const SkRect* dst = skip<SkRect>(reader);

    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));
    SkCanvas::VertexMode vmode = (SkCanvas::VertexMode)
            ((packedVerb & kVMode_DrawVerticesMask) >> kVMode_DrawVerticesShift);
    int vertexCount = packedVerb & kVCount_DrawVerticesMask;
    if (0 == vertexCount) {
        vertexCount = reader.read32();
    }
    sk_sp<SkXfermode> xfer;
    unsigned xmode = (packedVerb & kXMode_DrawVerticesMask) >> kXMode_DrawVerticesShift;
    if (0xFF == xmode) {
        xfer = reader.readXfermode();
    } else {
        xfer = SkXfermode::Make((SkXfermode::Mode)xmode);
    }
    const SkPoint* vertices = skip<SkPoint>(reader, vertexCount);
    const SkPoint* texs = nullptr;
    if (packedVerb & kHasTex_DrawVerticesMask) {
        texs = skip<SkPoint>(reader, vertexCount);
    }
    const SkColor* colors = nullptr;
    if (packedVerb & kHasColors_DrawVerticesMask) {
        colors = skip<SkColor>(reader, vertexCount);
    }
    int indexCount = 0;
    const uint16_t* indices = nullptr;
    if (packedVerb & kHasIndices_DrawVerticesMask) {
        indexCount = reader.read32();
        indices = skip<uint16_t>(reader, indexCount);
    }

    canvas->drawVertices(vmode, vertexCount, vertices, texs, colors, xfer.get(),
                         indices, indexCount, 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 = skip<SkRect>(reader);

    // len includes the key's trailing 0
    uint32_t len = unpack_verb_extra(packedVerb) >> 1;
    if (0 == len) {
        len = reader.read32();
    }
    const char* key = skip<char>(reader, 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

static sk_sp<SkImage> make_from_skiaimageformat(const void* encoded, size_t encodedSize) {
    if (encodedSize < 24) {
        return nullptr;
    }

    SkMemoryStream stream(encoded, encodedSize);
    char signature[8];
    stream.read(signature, 8);
    if (memcmp(signature, "skiaimgf", 8)) {
        return nullptr;
    }

    int width = stream.readU32();
    int height = stream.readU32();
    SkColorType ct = (SkColorType)stream.readU16();
    SkAlphaType at = (SkAlphaType)stream.readU16();
    SkASSERT(kAlpha_8_SkColorType == ct);

    SkDEBUGCODE(size_t colorSpaceSize =) stream.readU32();
    SkASSERT(0 == colorSpaceSize);

    SkImageInfo info = SkImageInfo::Make(width, height, ct, at);
    size_t size = width * height;
    sk_sp<SkData> pixels = SkData::MakeUninitialized(size);
    stream.read(pixels->writable_data(), size);
    SkASSERT(encodedSize == SkAlign4(stream.getPosition()));
    return SkImage::MakeRasterData(info, pixels, width);
}

static sk_sp<SkImage> make_from_encoded(const sk_sp<SkData>& data) {
    sk_sp<SkImage> image = make_from_skiaimageformat(data->data(), data->size());
    if (!image) {
        image = SkImage::MakeFromEncoded(data);
    }
    return image;
}

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 = make_from_encoded(data);
        if (!image) {
            SkDebugf("-- failed to decode\n");
        }
        inflator->setImage(index, image.get());
    }
}

sk_sp<SkTypeface> SkPipeInflator::makeTypeface(const void* data, size_t size) {
    if (fTFDeserializer) {
        return fTFDeserializer->deserialize(data, size);
    }
    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 = inflator->makeTypeface(data->data(), data->size());
        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 = skip<SkRect>(reader);
        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_throw();     // 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(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;

    SkTypefaceDeserializer*             fTFDeserializer = nullptr;
};

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

void SkPipeDeserializer::setTypefaceDeserializer(SkTypefaceDeserializer* tfd) {
    fImpl->fTFDeserializer = tfd;
}

sk_sp<SkPicture> SkPipeDeserializer::readPicture(const void* data, size_t size) {
    if (size < sizeof(uint32_t) + sizeof(SkRect)) {
        return nullptr;
    }

    uint32_t header;
    memcpy(&header, data, 4); size -= 4; data = (const char*)data + 4;
    if (kDefinePicture_ExtPipeVerb != header) {
        return nullptr;
    }
    SkRect cull;
    memcpy(&cull, data, sizeof(SkRect));
    size -= sizeof(SkRect); data = (const char*)data + sizeof(SkRect);

    SkPictureRecorder recorder;
    this->playback(data, size, recorder.beginRecording(cull));
    return recorder.finishRecordingAsPicture();
}

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->fTFDeserializer);
        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));
}

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->fTFDeserializer);
    SkPipeReader reader(this, data, size);
    reader.setInflator(&inflator);
    return do_playback(reader, canvas);
}

