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

#include "SkDebugCanvas.h"
#include "SkDevice.h"
#include "SkForceLinking.h"
#include "SkGraphics.h"
#include "SkImageDecoder.h"
#include "SkImageEncoder.h"
#include "SkOSFile.h"
#include "SkPicture.h"
#include "SkPicturePlayback.h"
#include "SkPictureRecord.h"
#include "SkPictureRecorder.h"
#include "SkStream.h"
#include "picture_utils.h"

__SK_FORCE_IMAGE_DECODER_LINKING;

static void usage() {
    SkDebugf("Usage: filter -i inFile [-o outFile] [--input-dir path] [--output-dir path]\n");
    SkDebugf("                        [-h|--help]\n\n");
    SkDebugf("    -i inFile  : file to filter.\n");
    SkDebugf("    -o outFile : result of filtering.\n");
    SkDebugf("    --input-dir : process all files in dir with .skp extension.\n");
    SkDebugf("    --output-dir : results of filtering the input dir.\n");
    SkDebugf("    -h|--help  : Show this help message.\n");
}

// Is the supplied paint simply a color?
static bool is_simple(const SkPaint& p) {
    return NULL == p.getPathEffect() &&
           NULL == p.getShader() &&
           NULL == p.getXfermode() &&
           NULL == p.getMaskFilter() &&
           NULL == p.getColorFilter() &&
           NULL == p.getRasterizer() &&
           NULL == p.getLooper() &&
           NULL == p.getImageFilter();
}


// Check for:
//    SAVE_LAYER
//        DRAW_BITMAP_RECT_TO_RECT
//    RESTORE
// where the saveLayer's color can be moved into the drawBitmapRect
static bool check_0(SkDebugCanvas* canvas, int curCommand) {
    if (SAVE_LAYER != canvas->getDrawCommandAt(curCommand)->getType() ||
        canvas->getSize() <= curCommand+2 ||
        DRAW_BITMAP_RECT_TO_RECT != canvas->getDrawCommandAt(curCommand+1)->getType() ||
        RESTORE != canvas->getDrawCommandAt(curCommand+2)->getType()) {
        return false;
    }

    SkSaveLayerCommand* saveLayer =
        (SkSaveLayerCommand*) canvas->getDrawCommandAt(curCommand);
    SkDrawBitmapRectCommand* dbmr =
        (SkDrawBitmapRectCommand*) canvas->getDrawCommandAt(curCommand+1);

    const SkPaint* saveLayerPaint = saveLayer->paint();
    SkPaint* dbmrPaint = dbmr->paint();

    // For this optimization we only fold the saveLayer and drawBitmapRect
    // together if the saveLayer's draw is simple (i.e., no fancy effects)
    // and the only difference in the colors is their alpha value
    SkColor layerColor = saveLayerPaint->getColor() | 0xFF000000; // force opaque
    SkColor dbmrColor = dbmrPaint->getColor() | 0xFF000000;       // force opaque

    // If either operation lacks a paint then the collapse is trivial
    return NULL == saveLayerPaint ||
           NULL == dbmrPaint ||
           (is_simple(*saveLayerPaint) && dbmrColor == layerColor);
}

// Fold the saveLayer's alpha into the drawBitmapRect and remove the saveLayer
// and restore
static void apply_0(SkDebugCanvas* canvas, int curCommand) {
    SkSaveLayerCommand* saveLayer =
        (SkSaveLayerCommand*) canvas->getDrawCommandAt(curCommand);
    const SkPaint* saveLayerPaint = saveLayer->paint();

    // if (NULL == saveLayerPaint) the dbmr's paint doesn't need to be changed
    if (NULL != saveLayerPaint) {
        SkDrawBitmapRectCommand* dbmr =
            (SkDrawBitmapRectCommand*) canvas->getDrawCommandAt(curCommand+1);
        SkPaint* dbmrPaint = dbmr->paint();

        if (NULL == dbmrPaint) {
            // if the DBMR doesn't have a paint just use the saveLayer's
            dbmr->setPaint(*saveLayerPaint);
        } else if (NULL != saveLayerPaint) {
            // Both paints are present so their alphas need to be combined
            SkColor color = saveLayerPaint->getColor();
            int a0 = SkColorGetA(color);

            color = dbmrPaint->getColor();
            int a1 = SkColorGetA(color);

            int newA = SkMulDiv255Round(a0, a1);
            SkASSERT(newA <= 0xFF);

            SkColor newColor = SkColorSetA(color, newA);
            dbmrPaint->setColor(newColor);
        }
    }

    canvas->deleteDrawCommandAt(curCommand+2);  // restore
    canvas->deleteDrawCommandAt(curCommand);    // saveLayer
}

// Check for:
//    SAVE_LAYER
//        SAVE
//            CLIP_RECT
//            DRAW_BITMAP_RECT_TO_RECT
//        RESTORE
//    RESTORE
// where the saveLayer's color can be moved into the drawBitmapRect
static bool check_1(SkDebugCanvas* canvas, int curCommand) {
    if (SAVE_LAYER != canvas->getDrawCommandAt(curCommand)->getType() ||
        canvas->getSize() <= curCommand+5 ||
        SAVE != canvas->getDrawCommandAt(curCommand+1)->getType() ||
        CLIP_RECT != canvas->getDrawCommandAt(curCommand+2)->getType() ||
        DRAW_BITMAP_RECT_TO_RECT != canvas->getDrawCommandAt(curCommand+3)->getType() ||
        RESTORE != canvas->getDrawCommandAt(curCommand+4)->getType() ||
        RESTORE != canvas->getDrawCommandAt(curCommand+5)->getType()) {
        return false;
    }

    SkSaveLayerCommand* saveLayer =
        (SkSaveLayerCommand*) canvas->getDrawCommandAt(curCommand);
    SkDrawBitmapRectCommand* dbmr =
        (SkDrawBitmapRectCommand*) canvas->getDrawCommandAt(curCommand+3);

    const SkPaint* saveLayerPaint = saveLayer->paint();
    SkPaint* dbmrPaint = dbmr->paint();

    // For this optimization we only fold the saveLayer and drawBitmapRect
    // together if the saveLayer's draw is simple (i.e., no fancy effects) and
    // and the only difference in the colors is that the saveLayer's can have
    // an alpha while the drawBitmapRect's is opaque.
    // TODO: it should be possible to fold them together even if they both
    // have different non-255 alphas but this is low priority since we have
    // never seen that case
    // If either operation lacks a paint then the collapse is trivial
    SkColor layerColor = saveLayerPaint->getColor() | 0xFF000000; // force opaque

    return NULL == saveLayerPaint ||
           NULL == dbmrPaint ||
           (is_simple(*saveLayerPaint) && dbmrPaint->getColor() == layerColor);
}

// Fold the saveLayer's alpha into the drawBitmapRect and remove the saveLayer
// and restore
static void apply_1(SkDebugCanvas* canvas, int curCommand) {
    SkSaveLayerCommand* saveLayer =
        (SkSaveLayerCommand*) canvas->getDrawCommandAt(curCommand);
    const SkPaint* saveLayerPaint = saveLayer->paint();

    // if (NULL == saveLayerPaint) the dbmr's paint doesn't need to be changed
    if (NULL != saveLayerPaint) {
        SkDrawBitmapRectCommand* dbmr =
            (SkDrawBitmapRectCommand*) canvas->getDrawCommandAt(curCommand+3);
        SkPaint* dbmrPaint = dbmr->paint();

        if (NULL == dbmrPaint) {
            dbmr->setPaint(*saveLayerPaint);
        } else {
            SkColor newColor = SkColorSetA(dbmrPaint->getColor(),
                                           SkColorGetA(saveLayerPaint->getColor()));
            dbmrPaint->setColor(newColor);
        }
    }

    canvas->deleteDrawCommandAt(curCommand+5);    // restore
    canvas->deleteDrawCommandAt(curCommand);      // saveLayer
}

// Check for:
//    SAVE
//        CLIP_RECT
//        DRAW_RECT
//    RESTORE
// where the rect is entirely within the clip and the clip is an intersect
static bool check_2(SkDebugCanvas* canvas, int curCommand) {
    if (SAVE != canvas->getDrawCommandAt(curCommand)->getType() ||
        canvas->getSize() <= curCommand+4 ||
        CLIP_RECT != canvas->getDrawCommandAt(curCommand+1)->getType() ||
        DRAW_RECT != canvas->getDrawCommandAt(curCommand+2)->getType() ||
        RESTORE != canvas->getDrawCommandAt(curCommand+3)->getType()) {
        return false;
    }

    SkClipRectCommand* cr =
        (SkClipRectCommand*) canvas->getDrawCommandAt(curCommand+1);
    SkDrawRectCommand* dr =
        (SkDrawRectCommand*) canvas->getDrawCommandAt(curCommand+2);

    if (SkRegion::kIntersect_Op != cr->op()) {
        return false;
    }

    return cr->rect().contains(dr->rect());
}

// Remove everything but the drawRect
static void apply_2(SkDebugCanvas* canvas, int curCommand) {
    canvas->deleteDrawCommandAt(curCommand+3);   // restore
    // drawRect
    canvas->deleteDrawCommandAt(curCommand+1);   // clipRect
    canvas->deleteDrawCommandAt(curCommand);     // save
}

// Check for:
//    SAVE
//        CLIP_RRECT
//        DRAW_RECT
//    RESTORE
// where the rect entirely encloses the clip
static bool check_3(SkDebugCanvas* canvas, int curCommand) {
    if (SAVE != canvas->getDrawCommandAt(curCommand)->getType() ||
        canvas->getSize() <= curCommand+4 ||
        CLIP_RRECT != canvas->getDrawCommandAt(curCommand+1)->getType() ||
        DRAW_RECT != canvas->getDrawCommandAt(curCommand+2)->getType() ||
        RESTORE != canvas->getDrawCommandAt(curCommand+3)->getType()) {
        return false;
    }

    SkClipRRectCommand* crr =
        (SkClipRRectCommand*) canvas->getDrawCommandAt(curCommand+1);
    SkDrawRectCommand* dr  =
        (SkDrawRectCommand*) canvas->getDrawCommandAt(curCommand+2);

    if (SkRegion::kIntersect_Op != crr->op()) {
        return false;
    }

    return dr->rect().contains(crr->rrect().rect());
}

// Replace everything with a drawRRect with the paint from the drawRect
// and the AA settings from the clipRRect
static void apply_3(SkDebugCanvas* canvas, int curCommand) {

    canvas->deleteDrawCommandAt(curCommand+3);    // restore

    SkClipRRectCommand* crr =
        (SkClipRRectCommand*) canvas->getDrawCommandAt(curCommand+1);
    SkDrawRectCommand* dr  =
        (SkDrawRectCommand*) canvas->getDrawCommandAt(curCommand+2);

    // TODO: could skip paint re-creation if the AA settings already match
    SkPaint newPaint = dr->paint();
    newPaint.setAntiAlias(crr->doAA());
    SkDrawRRectCommand* drr = new SkDrawRRectCommand(crr->rrect(), newPaint);
    canvas->setDrawCommandAt(curCommand+2, drr);

    canvas->deleteDrawCommandAt(curCommand+1);    // clipRRect
    canvas->deleteDrawCommandAt(curCommand);      // save
}

// Check for:
//    SAVE
//        CLIP_RECT
//        DRAW_BITMAP_RECT_TO_RECT
//    RESTORE
// where the rect and drawBitmapRect dst exactly match
static bool check_4(SkDebugCanvas* canvas, int curCommand) {
    if (SAVE != canvas->getDrawCommandAt(curCommand)->getType() ||
        canvas->getSize() <= curCommand+4 ||
        CLIP_RECT != canvas->getDrawCommandAt(curCommand+1)->getType() ||
        DRAW_BITMAP_RECT_TO_RECT != canvas->getDrawCommandAt(curCommand+2)->getType() ||
        RESTORE != canvas->getDrawCommandAt(curCommand+3)->getType()) {
        return false;
    }

    SkClipRectCommand* cr =
        (SkClipRectCommand*) canvas->getDrawCommandAt(curCommand+1);
    SkDrawBitmapRectCommand* dbmr  =
        (SkDrawBitmapRectCommand*) canvas->getDrawCommandAt(curCommand+2);

    if (SkRegion::kIntersect_Op != cr->op()) {
        return false;
    }

    return dbmr->dstRect() == cr->rect();
}

// Remove everything but the drawBitmapRect
static void apply_4(SkDebugCanvas* canvas, int curCommand) {
    canvas->deleteDrawCommandAt(curCommand+3);    // restore
    // drawBitmapRectToRect
    canvas->deleteDrawCommandAt(curCommand+1);    // clipRect
    canvas->deleteDrawCommandAt(curCommand);      // save
}

// Check for:
//    TRANSLATE
// where the translate is zero
static bool check_5(SkDebugCanvas* canvas, int curCommand) {
    if (TRANSLATE != canvas->getDrawCommandAt(curCommand)->getType()) {
        return false;
    }

    SkTranslateCommand* t =
        (SkTranslateCommand*) canvas->getDrawCommandAt(curCommand);

    return 0 == t->x() && 0 == t->y();
}

// Just remove the translate
static void apply_5(SkDebugCanvas* canvas, int curCommand) {
    canvas->deleteDrawCommandAt(curCommand);    // translate
}

// Check for:
//    SCALE
// where the scale is 1,1
static bool check_6(SkDebugCanvas* canvas, int curCommand) {
    if (SCALE != canvas->getDrawCommandAt(curCommand)->getType()) {
        return false;
    }

    SkScaleCommand* s = (SkScaleCommand*) canvas->getDrawCommandAt(curCommand);

    return SK_Scalar1 == s->x() && SK_Scalar1 == s->y();
}

// Just remove the scale
static void apply_6(SkDebugCanvas* canvas, int curCommand) {
    canvas->deleteDrawCommandAt(curCommand);   // scale
}

// Check for:
//  SAVE
//      CLIP_RECT
//      SAVE_LAYER
//          SAVE
//              CLIP_RECT
//              SAVE_LAYER
//                  SAVE
//                      CLIP_RECT
//                      DRAWBITMAPRECTTORECT
//                  RESTORE
//              RESTORE
//          RESTORE
//      RESTORE
//  RESTORE
// where:
//      all the clipRect's are BW, nested, intersections
//      the drawBitmapRectToRect is a 1-1 copy from src to dest
//      the last (smallest) clip rect is a subset of the drawBitmapRectToRect's dest rect
//      all the saveLayer's paints can be rolled into the drawBitmapRectToRect's paint
// This pattern is used by Google spreadsheet when drawing the toolbar buttons
static bool check_7(SkDebugCanvas* canvas, int curCommand) {
    if (SAVE != canvas->getDrawCommandAt(curCommand)->getType() ||
        canvas->getSize() <= curCommand+13 ||
        CLIP_RECT != canvas->getDrawCommandAt(curCommand+1)->getType() ||
        SAVE_LAYER != canvas->getDrawCommandAt(curCommand+2)->getType() ||
        SAVE != canvas->getDrawCommandAt(curCommand+3)->getType() ||
        CLIP_RECT != canvas->getDrawCommandAt(curCommand+4)->getType() ||
        SAVE_LAYER != canvas->getDrawCommandAt(curCommand+5)->getType() ||
        SAVE != canvas->getDrawCommandAt(curCommand+6)->getType() ||
        CLIP_RECT != canvas->getDrawCommandAt(curCommand+7)->getType() ||
        DRAW_BITMAP_RECT_TO_RECT != canvas->getDrawCommandAt(curCommand+8)->getType() ||
        RESTORE != canvas->getDrawCommandAt(curCommand+9)->getType() ||
        RESTORE != canvas->getDrawCommandAt(curCommand+10)->getType() ||
        RESTORE != canvas->getDrawCommandAt(curCommand+11)->getType() ||
        RESTORE != canvas->getDrawCommandAt(curCommand+12)->getType() ||
        RESTORE != canvas->getDrawCommandAt(curCommand+13)->getType()) {
        return false;
    }

    SkClipRectCommand* clip0 =
        (SkClipRectCommand*) canvas->getDrawCommandAt(curCommand+1);
    SkSaveLayerCommand* saveLayer0 =
        (SkSaveLayerCommand*) canvas->getDrawCommandAt(curCommand+2);
    SkClipRectCommand* clip1 =
        (SkClipRectCommand*) canvas->getDrawCommandAt(curCommand+4);
    SkSaveLayerCommand* saveLayer1 =
        (SkSaveLayerCommand*) canvas->getDrawCommandAt(curCommand+5);
    SkClipRectCommand* clip2 =
        (SkClipRectCommand*) canvas->getDrawCommandAt(curCommand+7);
    SkDrawBitmapRectCommand* dbmr =
        (SkDrawBitmapRectCommand*) canvas->getDrawCommandAt(curCommand+8);

    if (clip0->doAA() || clip1->doAA() || clip2->doAA()) {
        return false;
    }

    if (SkRegion::kIntersect_Op != clip0->op() ||
        SkRegion::kIntersect_Op != clip1->op() ||
        SkRegion::kIntersect_Op != clip2->op()) {
        return false;
    }

    if (!clip0->rect().contains(clip1->rect()) ||
        !clip1->rect().contains(clip2->rect())) {
        return false;
    }

    // The src->dest mapping needs to be 1-to-1
    if (NULL == dbmr->srcRect()) {
        if (dbmr->bitmap().width() != dbmr->dstRect().width() ||
            dbmr->bitmap().height() != dbmr->dstRect().height()) {
            return false;
        }
    } else {
        if (dbmr->srcRect()->width() != dbmr->dstRect().width() ||
            dbmr->srcRect()->height() != dbmr->dstRect().height()) {
            return false;
        }
    }

    if (!dbmr->dstRect().contains(clip2->rect())) {
        return false;
    }

    const SkPaint* saveLayerPaint0 = saveLayer0->paint();
    const SkPaint* saveLayerPaint1 = saveLayer1->paint();

    if ((NULL != saveLayerPaint0 && !is_simple(*saveLayerPaint0)) ||
        (NULL != saveLayerPaint1 && !is_simple(*saveLayerPaint1))) {
        return false;
    }

    SkPaint* dbmrPaint = dbmr->paint();

    if (NULL == dbmrPaint) {
        return true;
    }

    if (NULL != saveLayerPaint0) {
        SkColor layerColor0 = saveLayerPaint0->getColor() | 0xFF000000; // force opaque
        if (dbmrPaint->getColor() != layerColor0) {
            return false;
        }
    }

    if (NULL != saveLayerPaint1) {
        SkColor layerColor1 = saveLayerPaint1->getColor() | 0xFF000000; // force opaque
        if (dbmrPaint->getColor() != layerColor1) {
            return false;
        }
    }

    return true;
}

// Reduce to a single drawBitmapRectToRect call by folding the clipRect's into
// the src and dst Rects and the saveLayer paints into the drawBitmapRectToRect's
// paint.
static void apply_7(SkDebugCanvas* canvas, int curCommand) {
    SkSaveLayerCommand* saveLayer0 =
        (SkSaveLayerCommand*) canvas->getDrawCommandAt(curCommand+2);
    SkSaveLayerCommand* saveLayer1 =
        (SkSaveLayerCommand*) canvas->getDrawCommandAt(curCommand+5);
    SkClipRectCommand* clip2 =
        (SkClipRectCommand*) canvas->getDrawCommandAt(curCommand+7);
    SkDrawBitmapRectCommand* dbmr =
        (SkDrawBitmapRectCommand*) canvas->getDrawCommandAt(curCommand+8);

    SkScalar newSrcLeft = dbmr->srcRect()->fLeft + clip2->rect().fLeft - dbmr->dstRect().fLeft;
    SkScalar newSrcTop = dbmr->srcRect()->fTop + clip2->rect().fTop - dbmr->dstRect().fTop;

    SkRect newSrc = SkRect::MakeXYWH(newSrcLeft, newSrcTop,
                                     clip2->rect().width(), clip2->rect().height());

    dbmr->setSrcRect(newSrc);
    dbmr->setDstRect(clip2->rect());

    SkColor color = 0xFF000000;
    int a0, a1;

    const SkPaint* saveLayerPaint0 = saveLayer0->paint();
    if (NULL != saveLayerPaint0) {
        color = saveLayerPaint0->getColor();
        a0 = SkColorGetA(color);
    } else {
        a0 = 0xFF;
    }

    const SkPaint* saveLayerPaint1 = saveLayer1->paint();
    if (NULL != saveLayerPaint1) {
        color = saveLayerPaint1->getColor();
        a1 = SkColorGetA(color);
    } else {
        a1 = 0xFF;
    }

    int newA = SkMulDiv255Round(a0, a1);
    SkASSERT(newA <= 0xFF);

    SkPaint* dbmrPaint = dbmr->paint();

    if (NULL != dbmrPaint) {
        SkColor newColor = SkColorSetA(dbmrPaint->getColor(), newA);
        dbmrPaint->setColor(newColor);
    } else {
        SkColor newColor = SkColorSetA(color, newA);

        SkPaint newPaint;
        newPaint.setColor(newColor);
        dbmr->setPaint(newPaint);
    }

    // remove everything except the drawbitmaprect
    canvas->deleteDrawCommandAt(curCommand+13);   // restore
    canvas->deleteDrawCommandAt(curCommand+12);   // restore
    canvas->deleteDrawCommandAt(curCommand+11);   // restore
    canvas->deleteDrawCommandAt(curCommand+10);   // restore
    canvas->deleteDrawCommandAt(curCommand+9);    // restore
    canvas->deleteDrawCommandAt(curCommand+7);    // clipRect
    canvas->deleteDrawCommandAt(curCommand+6);    // save
    canvas->deleteDrawCommandAt(curCommand+5);    // saveLayer
    canvas->deleteDrawCommandAt(curCommand+4);    // clipRect
    canvas->deleteDrawCommandAt(curCommand+3);    // save
    canvas->deleteDrawCommandAt(curCommand+2);    // saveLayer
    canvas->deleteDrawCommandAt(curCommand+1);    // clipRect
    canvas->deleteDrawCommandAt(curCommand);      // save
}

// Check for:
//    SAVE
//       CLIP_RECT
//       DRAWBITMAPRECTTORECT
//    RESTORE
// where:
//      the drawBitmapRectToRect is a 1-1 copy from src to dest
//      the clip rect is BW and a subset of the drawBitmapRectToRect's dest rect
static bool check_8(SkDebugCanvas* canvas, int curCommand) {
    if (SAVE != canvas->getDrawCommandAt(curCommand)->getType() ||
        canvas->getSize() <= curCommand+4 ||
        CLIP_RECT != canvas->getDrawCommandAt(curCommand+1)->getType() ||
        DRAW_BITMAP_RECT_TO_RECT != canvas->getDrawCommandAt(curCommand+2)->getType() ||
        RESTORE != canvas->getDrawCommandAt(curCommand+3)->getType()) {
        return false;
    }

    SkClipRectCommand* clip =
        (SkClipRectCommand*) canvas->getDrawCommandAt(curCommand+1);
    SkDrawBitmapRectCommand* dbmr =
        (SkDrawBitmapRectCommand*) canvas->getDrawCommandAt(curCommand+2);

    if (clip->doAA() || SkRegion::kIntersect_Op != clip->op()) {
        return false;
    }

    // The src->dest mapping needs to be 1-to-1
    if (NULL == dbmr->srcRect()) {
        if (dbmr->bitmap().width() != dbmr->dstRect().width() ||
            dbmr->bitmap().height() != dbmr->dstRect().height()) {
            return false;
        }
    } else {
        if (dbmr->srcRect()->width() != dbmr->dstRect().width() ||
            dbmr->srcRect()->height() != dbmr->dstRect().height()) {
            return false;
        }
    }

    if (!dbmr->dstRect().contains(clip->rect())) {
        return false;
    }

    return true;
}

// Fold the clipRect into the drawBitmapRectToRect's src and dest rects
static void apply_8(SkDebugCanvas* canvas, int curCommand) {
    SkClipRectCommand* clip =
        (SkClipRectCommand*) canvas->getDrawCommandAt(curCommand+1);
    SkDrawBitmapRectCommand* dbmr =
        (SkDrawBitmapRectCommand*) canvas->getDrawCommandAt(curCommand+2);

    SkScalar newSrcLeft, newSrcTop;

    if (NULL != dbmr->srcRect()) {
        newSrcLeft = dbmr->srcRect()->fLeft + clip->rect().fLeft - dbmr->dstRect().fLeft;
        newSrcTop  = dbmr->srcRect()->fTop + clip->rect().fTop - dbmr->dstRect().fTop;
    } else {
        newSrcLeft = clip->rect().fLeft - dbmr->dstRect().fLeft;
        newSrcTop  = clip->rect().fTop - dbmr->dstRect().fTop;
    }

    SkRect newSrc = SkRect::MakeXYWH(newSrcLeft, newSrcTop,
                                     clip->rect().width(), clip->rect().height());

    dbmr->setSrcRect(newSrc);
    dbmr->setDstRect(clip->rect());

    // remove everything except the drawbitmaprect
    canvas->deleteDrawCommandAt(curCommand+3);
    canvas->deleteDrawCommandAt(curCommand+1);
    canvas->deleteDrawCommandAt(curCommand);
}

// Check for:
//  SAVE
//    CLIP_RECT
//    DRAWBITMAPRECTTORECT
//  RESTORE
// where:
//      clipRect is BW and encloses the DBMR2R's dest rect
static bool check_9(SkDebugCanvas* canvas, int curCommand) {
    if (SAVE != canvas->getDrawCommandAt(curCommand)->getType() ||
        canvas->getSize() <= curCommand+4 ||
        CLIP_RECT != canvas->getDrawCommandAt(curCommand+1)->getType() ||
        DRAW_BITMAP_RECT_TO_RECT != canvas->getDrawCommandAt(curCommand+2)->getType() ||
        RESTORE != canvas->getDrawCommandAt(curCommand+3)->getType()) {
        return false;
    }

    SkClipRectCommand* clip =
        (SkClipRectCommand*) canvas->getDrawCommandAt(curCommand+1);
    SkDrawBitmapRectCommand* dbmr =
        (SkDrawBitmapRectCommand*) canvas->getDrawCommandAt(curCommand+2);

    if (clip->doAA() || SkRegion::kIntersect_Op != clip->op()) {
        return false;
    }

    if (!clip->rect().contains(dbmr->dstRect())) {
        return false;
    }

    return true;
}

// remove everything except the drawbitmaprect
static void apply_9(SkDebugCanvas* canvas, int curCommand) {
    canvas->deleteDrawCommandAt(curCommand+3);   // restore
    // drawBitmapRectToRect
    canvas->deleteDrawCommandAt(curCommand+1);   // clipRect
    canvas->deleteDrawCommandAt(curCommand);     // save
}

typedef bool (*PFCheck)(SkDebugCanvas* canvas, int curCommand);
typedef void (*PFApply)(SkDebugCanvas* canvas, int curCommand);

struct OptTableEntry {
    PFCheck fCheck;
    PFApply fApply;
    int fNumTimesApplied;
} gOptTable[] = {
    { check_0, apply_0, 0 },
    { check_1, apply_1, 0 },
    { check_2, apply_2, 0 },
    { check_3, apply_3, 0 },
    { check_4, apply_4, 0 },
    { check_5, apply_5, 0 },
    { check_6, apply_6, 0 },
    { check_7, apply_7, 0 },
    { check_8, apply_8, 0 },
    { check_9, apply_9, 0 },
};


static int filter_picture(const SkString& inFile, const SkString& outFile) {
    SkAutoTDelete<SkPicture> inPicture;

    SkFILEStream inStream(inFile.c_str());
    if (inStream.isValid()) {
        inPicture.reset(SkPicture::CreateFromStream(&inStream));
    }

    if (NULL == inPicture.get()) {
        SkDebugf("Could not read file %s\n", inFile.c_str());
        return -1;
    }

    int localCount[SK_ARRAY_COUNT(gOptTable)];

    memset(localCount, 0, sizeof(localCount));

    SkDebugCanvas debugCanvas(inPicture->width(), inPicture->height());
    debugCanvas.setBounds(inPicture->width(), inPicture->height());
    inPicture->draw(&debugCanvas);

    // delete the initial save and restore since replaying the commands will
    // re-add them
    if (debugCanvas.getSize() > 1) {
        debugCanvas.deleteDrawCommandAt(0);
        debugCanvas.deleteDrawCommandAt(debugCanvas.getSize()-1);
    }

    bool changed = true;
    int numBefore = debugCanvas.getSize();

    while (changed) {
        changed = false;
        for (int i = 0; i < debugCanvas.getSize(); ++i) {
            for (size_t opt = 0; opt < SK_ARRAY_COUNT(gOptTable); ++opt) {
                if ((*gOptTable[opt].fCheck)(&debugCanvas, i)) {
                    (*gOptTable[opt].fApply)(&debugCanvas, i);

                    ++gOptTable[opt].fNumTimesApplied;
                    ++localCount[opt];

                    if (debugCanvas.getSize() == i) {
                        // the optimization removed all the remaining operations
                        break;
                    }

                    opt = 0;          // try all the opts all over again
                    changed = true;
                }
            }
        }
    }

    int numAfter = debugCanvas.getSize();

    if (!outFile.isEmpty()) {
        SkPictureRecorder recorder;
        SkCanvas* canvas = recorder.beginRecording(inPicture->width(), inPicture->height(), NULL, 0);
        debugCanvas.draw(canvas);
        SkAutoTUnref<SkPicture> outPicture(recorder.endRecording());

        SkFILEWStream outStream(outFile.c_str());

        outPicture->serialize(&outStream);
    }

    bool someOptFired = false;
    for (size_t opt = 0; opt < SK_ARRAY_COUNT(gOptTable); ++opt) {
        if (0 != localCount[opt]) {
            SkDebugf("%d: %d ", opt, localCount[opt]);
            someOptFired = true;
        }
    }

    if (!someOptFired) {
        SkDebugf("No opts fired\n");
    } else {
        SkDebugf("\t before: %d after: %d delta: %d\n",
                 numBefore, numAfter, numBefore-numAfter);
    }

    return 0;
}

// This function is not marked as 'static' so it can be referenced externally
// in the iOS build.
int tool_main(int argc, char** argv); // suppress a warning on mac

int tool_main(int argc, char** argv) {
#if SK_ENABLE_INST_COUNT
    gPrintInstCount = true;
#endif

    SkGraphics::Init();

    if (argc < 3) {
        usage();
        return -1;
    }

    SkString inFile, outFile, inDir, outDir;

    char* const* stop = argv + argc;
    for (++argv; argv < stop; ++argv) {
        if (strcmp(*argv, "-i") == 0) {
            argv++;
            if (argv < stop && **argv) {
                inFile.set(*argv);
            } else {
                SkDebugf("missing arg for -i\n");
                usage();
                return -1;
            }
        } else if (strcmp(*argv, "--input-dir") == 0) {
            argv++;
            if (argv < stop && **argv) {
                inDir.set(*argv);
            } else {
                SkDebugf("missing arg for --input-dir\n");
                usage();
                return -1;
            }
        } else if (strcmp(*argv, "--output-dir") == 0) {
            argv++;
            if (argv < stop && **argv) {
                outDir.set(*argv);
            } else {
                SkDebugf("missing arg for --output-dir\n");
                usage();
                return -1;
            }
        } else if (strcmp(*argv, "-o") == 0) {
            argv++;
            if (argv < stop && **argv) {
                outFile.set(*argv);
            } else {
                SkDebugf("missing arg for -o\n");
                usage();
                return -1;
            }
        } else if (strcmp(*argv, "--help") == 0 || strcmp(*argv, "-h") == 0) {
            usage();
            return 0;
        } else {
            SkDebugf("unknown arg %s\n", *argv);
            usage();
            return -1;
        }
    }

    SkOSFile::Iter iter(inDir.c_str(), "skp");

    SkString inputFilename, outputFilename;
    if (iter.next(&inputFilename)) {

        do {
            inFile = SkOSPath::SkPathJoin(inDir.c_str(), inputFilename.c_str());
            if (!outDir.isEmpty()) {
                outFile = SkOSPath::SkPathJoin(outDir.c_str(), inputFilename.c_str());
            }
            SkDebugf("Executing %s\n", inputFilename.c_str());
            filter_picture(inFile, outFile);
        } while(iter.next(&inputFilename));

    } else if (!inFile.isEmpty()) {
        filter_picture(inFile, outFile);
    } else {
        usage();
        return -1;
    }

    for (size_t opt = 0; opt < SK_ARRAY_COUNT(gOptTable); ++opt) {
        SkDebugf("opt %d: %d\n", opt, gOptTable[opt].fNumTimesApplied);
    }

    SkGraphics::Term();
    return 0;
}

#if !defined SK_BUILD_FOR_IOS
int main(int argc, char * const argv[]) {
    return tool_main(argc, (char**) argv);
}
#endif
