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

#include "GrContext.h"
#include "GrContextFactory.h"
#include "GrRenderTarget.h"
#include "SkGpuDevice.h"
#include "gl/GrGLDefines.h"

#include "SkBitmap.h"
#include "SkCanvas.h"
#include "SkColor.h"
#include "SkGraphics.h"
#include "SkImageEncoder.h"
#include "SkOSFile.h"
#include "SkPicture.h"
#include "SkStream.h"
#include "SkString.h"
#include "SkTArray.h"
#include "SkTDArray.h"
#include "SkTaskGroup.h"
#include "SkTime.h"
#include "Test.h"

#if !SK_SUPPORT_GPU
#error "GPU support required"
#endif

#ifdef SK_BUILD_FOR_WIN
    #define PATH_SLASH "\\"
    #define IN_DIR "D:\\9-30-13\\"
    #define OUT_DIR "D:\\skpSkGr\\11\\"
    #define LINE_FEED "\r\n"
#else
    #define PATH_SLASH "/"
    #define IN_DIR "/usr/local/google/home/caryclark" PATH_SLASH "9-30-13-skp"
    #define OUT_DIR "/media/01CD75512A7F9EE0/4" PATH_SLASH
    #define LINE_FEED "\n"
#endif

#define PATH_STR_SIZE 512

static const struct {
    int directory;
    const char* filename;
} skipOverSkGr[] = {
    {1, "http___accuweather_com_.skp"},  // Couldn't convert bitmap to texture.http___absoku072_com_
};

static const size_t skipOverSkGrCount = SK_ARRAY_COUNT(skipOverSkGr);

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

class SkpSkGrThreadedRunnable;

enum TestStep {
    kCompareBits,
    kEncodeFiles,
};

enum {
    kMaxLength = 128,
    kMaxFiles = 128,
};

struct TestResult {
    void init(int dirNo) {
        fDirNo = dirNo;
        sk_bzero(fFilename, sizeof(fFilename));
        fTestStep = kCompareBits;
        fScaleOversized = true;
    }

    SkString status() {
        SkString outStr;
        outStr.printf("%s %d %d%s", fFilename, fPixelError, fTime, LINE_FEED);
        return outStr;
    }

    static void Test(int dirNo, const char* filename, TestStep testStep, bool verbose) {
        TestResult test;
        test.init(dirNo);
        test.fTestStep = testStep;
        strcpy(test.fFilename, filename);
        test.testOne();
        if (verbose) {
            SkDebugf("%s", test.status().c_str());
        }
    }

    void test(int dirNo, const SkString& filename) {
        init(dirNo);
        strcpy(fFilename, filename.c_str());
        testOne();
    }

    void testOne();

    char fFilename[kMaxLength];
    TestStep fTestStep;
    int fDirNo;
    int fPixelError;
    SkMSec fTime;
    bool fScaleOversized;
};

struct SkpSkGrThreadState {
    void init(int dirNo) {
        fResult.init(dirNo);
        fFoundCount = 0;
        fSmallestError = 0;
        sk_bzero(fFilesFound, sizeof(fFilesFound));
        sk_bzero(fDirsFound, sizeof(fDirsFound));
        sk_bzero(fError, sizeof(fError));
    }

    char fFilesFound[kMaxFiles][kMaxLength];
    int fDirsFound[kMaxFiles];
    int fError[kMaxFiles];
    int fFoundCount;
    int fSmallestError;
    skiatest::Reporter* fReporter;
    TestResult fResult;
};

struct SkpSkGrThreadedTestRunner {
    SkpSkGrThreadedTestRunner(skiatest::Reporter* reporter)
        : fReporter(reporter) {
    }

    ~SkpSkGrThreadedTestRunner();
    void render();
    SkTDArray<SkpSkGrThreadedRunnable*> fRunnables;
    skiatest::Reporter* fReporter;
};

class SkpSkGrThreadedRunnable {
public:
    SkpSkGrThreadedRunnable(void (*testFun)(SkpSkGrThreadState*), int dirNo, const char* str,
            SkpSkGrThreadedTestRunner* runner) {
        SkASSERT(strlen(str) < sizeof(fState.fResult.fFilename) - 1);
        fState.init(dirNo);
        strcpy(fState.fResult.fFilename, str);
        fState.fReporter = runner->fReporter;
        fTestFun = testFun;
    }

    void operator()() {
        SkGraphics::SetTLSFontCacheLimit(1 * 1024 * 1024);
        (*fTestFun)(&fState);
    }

    SkpSkGrThreadState fState;
    void (*fTestFun)(SkpSkGrThreadState*);
};

SkpSkGrThreadedTestRunner::~SkpSkGrThreadedTestRunner() {
    for (int index = 0; index < fRunnables.count(); index++) {
        delete fRunnables[index];
    }
}

void SkpSkGrThreadedTestRunner::render() {
    SkTaskGroup().batch(fRunnables.count(), [&](int i) {
        fRunnables[i]();
    });
}

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

static const char outGrDir[] = OUT_DIR "grTest";
static const char outSkDir[] = OUT_DIR "skTest";
static const char outSkpDir[] = OUT_DIR "skpTest";
static const char outDiffDir[] = OUT_DIR "outTest";
static const char outStatusDir[] = OUT_DIR "statusTest";

static SkString make_filepath(int dirIndex, const char* dir, const char* name) {
    SkString path(dir);
    if (dirIndex) {
        path.appendf("%d", dirIndex);
    }
    path.append(PATH_SLASH);
    path.append(name);
    return path;
}

static SkString make_in_dir_name(int dirIndex) {
    SkString dirName(IN_DIR);
    dirName.appendf("%d", dirIndex);
    if (!sk_exists(dirName.c_str())) {
        SkDebugf("could not read dir %s\n", dirName.c_str());
        return SkString();
    }
    return dirName;
}

static bool make_out_dirs() {
    SkString outDir = make_filepath(0, OUT_DIR, "");
    if (!sk_exists(outDir.c_str())) {
        if (!sk_mkdir(outDir.c_str())) {
            SkDebugf("could not create dir %s\n", outDir.c_str());
            return false;
        }
    }
    SkString grDir = make_filepath(0, outGrDir, "");
    if (!sk_exists(grDir.c_str())) {
        if (!sk_mkdir(grDir.c_str())) {
            SkDebugf("could not create dir %s\n", grDir.c_str());
            return false;
        }
    }
    SkString skDir = make_filepath(0, outSkDir, "");
    if (!sk_exists(skDir.c_str())) {
        if (!sk_mkdir(skDir.c_str())) {
            SkDebugf("could not create dir %s\n", skDir.c_str());
            return false;
        }
    }
    SkString skpDir = make_filepath(0, outSkpDir, "");
    if (!sk_exists(skpDir.c_str())) {
        if (!sk_mkdir(skpDir.c_str())) {
            SkDebugf("could not create dir %s\n", skpDir.c_str());
            return false;
        }
    }
    SkString diffDir = make_filepath(0, outDiffDir, "");
    if (!sk_exists(diffDir.c_str())) {
        if (!sk_mkdir(diffDir.c_str())) {
            SkDebugf("could not create dir %s\n", diffDir.c_str());
            return false;
        }
    }
    SkString statusDir = make_filepath(0, outStatusDir, "");
    if (!sk_exists(statusDir.c_str())) {
        if (!sk_mkdir(statusDir.c_str())) {
            SkDebugf("could not create dir %s\n", statusDir.c_str());
            return false;
        }
    }
    return true;
}

static SkString make_png_name(const char* filename) {
    SkString pngName = SkString(filename);
    pngName.remove(pngName.size() - 3, 3);
    pngName.append("png");
    return pngName;
}

typedef GrContextFactory::ContextType ContextType;
#ifdef SK_BUILD_FOR_WIN
static const ContextType kAngle = GrContextFactory::kANGLE_ContextType;
#else
static const ContextType kNative = GrContextFactory::kNativeGL_ContextType;
#endif

static int similarBits(const SkBitmap& gr, const SkBitmap& sk) {
    const int kRowCount = 3;
    const int kThreshold = 3;
    int width = SkTMin(gr.width(), sk.width());
    if (width < kRowCount) {
        return true;
    }
    int height = SkTMin(gr.height(), sk.height());
    if (height < kRowCount) {
        return true;
    }
    int errorTotal = 0;
    SkTArray<char, true> errorRows;
    errorRows.push_back_n(width * kRowCount);
    SkAutoLockPixels autoGr(gr);
    SkAutoLockPixels autoSk(sk);
    char* base = &errorRows[0];
    for (int y = 0; y < height; ++y) {
        SkPMColor* grRow = gr.getAddr32(0, y);
        SkPMColor* skRow = sk.getAddr32(0, y);
        char* cOut = &errorRows[(y % kRowCount) * width];
        for (int x = 0; x < width; ++x) {
            SkPMColor grColor = grRow[x];
            SkPMColor skColor = skRow[x];
            int dr = SkGetPackedR32(grColor) - SkGetPackedR32(skColor);
            int dg = SkGetPackedG32(grColor) - SkGetPackedG32(skColor);
            int db = SkGetPackedB32(grColor) - SkGetPackedB32(skColor);
            int error = SkTMax(SkAbs32(dr), SkTMax(SkAbs32(dg), SkAbs32(db)));
            if ((cOut[x] = error >= kThreshold) && x >= 2
                    && base[x - 2] && base[width + x - 2] && base[width * 2 + x - 2]
                    && base[x - 1] && base[width + x - 1] && base[width * 2 + x - 1]
                    && base[x - 0] && base[width + x - 0] && base[width * 2 + x - 0]) {
                errorTotal += error;
            }
        }
    }
    return errorTotal;
}

static bool addError(SkpSkGrThreadState* data) {
    bool foundSmaller = false;
    int dCount = data->fFoundCount;
    int pixelError = data->fResult.fPixelError;
    if (data->fFoundCount < kMaxFiles) {
        data->fError[dCount] = pixelError;
        strcpy(data->fFilesFound[dCount], data->fResult.fFilename);
        data->fDirsFound[dCount] = data->fResult.fDirNo;
        ++data->fFoundCount;
    } else if (pixelError > data->fSmallestError) {
        int smallest = SK_MaxS32;
        int smallestIndex = 0;
        for (int index = 0; index < kMaxFiles; ++index) {
            if (smallest > data->fError[index]) {
                smallest = data->fError[index];
                smallestIndex = index;
            }
        }
        data->fError[smallestIndex] = pixelError;
        strcpy(data->fFilesFound[smallestIndex], data->fResult.fFilename);
        data->fDirsFound[smallestIndex] = data->fResult.fDirNo;
        data->fSmallestError = SK_MaxS32;
        for (int index = 0; index < kMaxFiles; ++index) {
            if (data->fSmallestError > data->fError[index]) {
                data->fSmallestError = data->fError[index];
            }
        }
        SkDebugf("*%d*", data->fSmallestError);
        foundSmaller = true;
    }
    return foundSmaller;
}

static SkMSec timePict(SkPicture* pic, SkCanvas* canvas) {
    canvas->save();
    int pWidth = pic->width();
    int pHeight = pic->height();
    const int maxDimension = 1000;
    const int slices = 3;
    int xInterval = SkTMax(pWidth - maxDimension, 0) / (slices - 1);
    int yInterval = SkTMax(pHeight - maxDimension, 0) / (slices - 1);
    SkRect rect = {0, 0, SkIntToScalar(SkTMin(maxDimension, pWidth)),
            SkIntToScalar(SkTMin(maxDimension, pHeight))};
    canvas->clipRect(rect);
    skiatest::Timer timer;
    for (int x = 0; x < slices; ++x) {
        for (int y = 0; y < slices; ++y) {
            pic->draw(canvas);
            canvas->translate(0, SkIntToScalar(yInterval));
        }
        canvas->translate(SkIntToScalar(xInterval), SkIntToScalar(-yInterval * slices));
    }
    SkMSec elapsed = timer.elapsedMsInt();
    canvas->restore();
    return elapsed;
}

static void drawPict(SkPicture* pic, SkCanvas* canvas, int scale) {
    canvas->clear(SK_ColorWHITE);
    if (scale != 1) {
        canvas->save();
        canvas->scale(1.0f / scale, 1.0f / scale);
    }
    pic->draw(canvas);
    if (scale != 1) {
        canvas->restore();
    }
}

static void writePict(const SkBitmap& bitmap, const char* outDir, const char* pngName) {
    SkString outFile = make_filepath(0, outDir, pngName);
    if (!sk_tool_utils::EncodeImageToFile(outFile.c_str(), bitmap,
            SkEncodedImageFormat::kPNG, 100)) {
        SkDebugf("unable to encode gr %s (width=%d height=%d)br \n", pngName,
                    bitmap.width(), bitmap.height());
    }
}

void TestResult::testOne() {
    sk_sp<SkPicture> pic;
    {
        SkString d;
        d.printf("    {%d, \"%s\"},", fDirNo, fFilename);
        SkString path = make_filepath(fDirNo, IN_DIR, fFilename);
        SkFILEStream stream(path.c_str());
        if (!stream.isValid()) {
            SkDebugf("invalid stream %s\n", path.c_str());
            goto finish;
        }
        if (fTestStep == kEncodeFiles) {
            size_t length = stream.getLength();
            SkTArray<char, true> bytes;
            bytes.push_back_n(length);
            stream.read(&bytes[0], length);
            stream.rewind();
            SkString wPath = make_filepath(0, outSkpDir, fFilename);
            SkFILEWStream wStream(wPath.c_str());
            wStream.write(&bytes[0], length);
            wStream.flush();
        }
        pic = SkPicture::MakeFromStream(&stream);
        if (!pic) {
            SkDebugf("unable to decode %s\n", fFilename);
            goto finish;
        }
        int pWidth = pic->width();
        int pHeight = pic->height();
        int pLargerWH = SkTMax(pWidth, pHeight);
        GrContextFactory contextFactory;
#ifdef SK_BUILD_FOR_WIN
        GrContext* context = contextFactory.get(kAngle);
#else
        GrContext* context = contextFactory.get(kNative);
#endif
        if (nullptr == context) {
            SkDebugf("unable to allocate context for %s\n", fFilename);
            goto finish;
        }
        int maxWH = context->getMaxRenderTargetSize();
        int scale = 1;
        while (pLargerWH / scale > maxWH) {
            scale *= 2;
        }
        SkBitmap bitmap;
        SkIPoint dim;
        do {
            dim.fX = (pWidth + scale - 1) / scale;
            dim.fY = (pHeight + scale - 1) / scale;
            bool success = bitmap.allocN32Pixels(dim.fX, dim.fY);
            if (success) {
                break;
            }
            SkDebugf("-%d-", scale);
        } while ((scale *= 2) < 256);
        if (scale >= 256) {
            SkDebugf("unable to allocate bitmap for %s (w=%d h=%d) (sw=%d sh=%d)\n",
                    fFilename, pWidth, pHeight, dim.fX, dim.fY);
            return;
        }
        SkCanvas skCanvas(bitmap);
        drawPict(pic, &skCanvas, fScaleOversized ? scale : 1);
        GrTextureDesc desc;
        desc.fConfig = kRGBA_8888_GrPixelConfig;
        desc.fFlags = kRenderTarget_GrTextureFlagBit;
        desc.fWidth = dim.fX;
        desc.fHeight = dim.fY;
        desc.fSampleCnt = 0;
        sk_sp<GrTexture> texture(context->createUncachedTexture(desc, nullptr, 0));
        if (!texture) {
            SkDebugf("unable to allocate texture for %s (w=%d h=%d)\n", fFilename,
                dim.fX, dim.fY);
            return;
        }
        SkGpuDevice grDevice(context, texture.get());
        SkCanvas grCanvas(&grDevice);
        drawPict(pic.get(), &grCanvas, fScaleOversized ? scale : 1);

        SkBitmap grBitmap;
        grBitmap.allocPixels(grCanvas.imageInfo());
        grCanvas.readPixels(&grBitmap, 0, 0);

        if (fTestStep == kCompareBits) {
            fPixelError = similarBits(grBitmap, bitmap);
            SkMSec skTime = timePict(pic, &skCanvas);
            SkMSec grTime = timePict(pic, &grCanvas);
            fTime = skTime - grTime;
        } else if (fTestStep == kEncodeFiles) {
            SkString pngStr = make_png_name(fFilename);
            const char* pngName = pngStr.c_str();
            writePict(grBitmap, outGrDir, pngName);
            writePict(bitmap, outSkDir, pngName);
        }
    }
}

static SkString makeStatusString(int dirNo) {
    SkString statName;
    statName.printf("stats%d.txt", dirNo);
    SkString statusFile = make_filepath(0, outStatusDir, statName.c_str());
    return statusFile;
}

class PreParser {
public:
    PreParser(int dirNo)
        : fDirNo(dirNo)
        , fIndex(0)
        , fStatusPath(makeStatusString(dirNo)) {
        if (!sk_exists(fStatusPath.c_str())) {
            return;
        }
        SkFILEStream reader;
        reader.setPath(fStatusPath.c_str());
        while (fetch(reader, &fResults.push_back()))
            ;
        fResults.pop_back();
    }

    bool fetch(SkFILEStream& reader, TestResult* result) {
        char c;
        int i = 0;
        result->init(fDirNo);
        result->fPixelError = 0;
        result->fTime = 0;
        do {
            bool readOne = reader.read(&c, 1) != 0;
            if (!readOne) {
                SkASSERT(i == 0);
                return false;
            }
            if (c == ' ') {
                result->fFilename[i++] = '\0';
                break;
            }
            result->fFilename[i++] = c;
            SkASSERT(i < kMaxLength);
        } while (true);
        do {
            SkAssertResult(reader.read(&c, 1) != 0);
            if (c == ' ') {
                break;
            }
            SkASSERT(c >= '0' && c <= '9');
            result->fPixelError = result->fPixelError * 10 + (c - '0');
        } while (true);
        bool minus = false;
        do {
            if (reader.read(&c, 1) == 0) {
                break;
            }
            if (c == '\r' && reader.read(&c, 1) == 0) {
                break;
            }
            if (c == '\n') {
                break;
            }
            if (c == '-') {
                minus = true;
                continue;
            }
            SkASSERT(c >= '0' && c <= '9');
            result->fTime = result->fTime * 10 + (c - '0');
        } while (true);
        if (minus) {
            result->fTime = -result->fTime;
        }
        return true;
    }

    bool match(const SkString& filename, SkFILEWStream* stream, TestResult* result) {
        if (fIndex < fResults.count()) {
            *result = fResults[fIndex++];
            SkASSERT(filename.equals(result->fFilename));
            SkString outStr(result->status());
            stream->write(outStr.c_str(), outStr.size());
            stream->flush();
            return true;
        }
        return false;
    }

private:
    int fDirNo;
    int fIndex;
    SkTArray<TestResult, true> fResults;
    SkString fStatusPath;
};

static bool initTest() {
    return make_out_dirs();
}

DEF_TEST(SkpSkGr, reporter) {
    SkTArray<TestResult, true> errors;
    if (!initTest()) {
        return;
    }
    SkpSkGrThreadState state;
    state.init(0);
    int smallCount = 0;
    for (int dirNo = 1; dirNo <= 100; ++dirNo) {
        SkString pictDir = make_in_dir_name(dirNo);
        SkASSERT(pictDir.size());
        if (reporter->verbose()) {
            SkDebugf("dirNo=%d\n", dirNo);
        }
        SkOSFile::Iter iter(pictDir.c_str(), "skp");
        SkString filename;
        int testCount = 0;
        PreParser preParser(dirNo);
        SkFILEWStream statusStream(makeStatusString(dirNo).c_str());
        while (iter.next(&filename)) {
            for (size_t index = 0; index < skipOverSkGrCount; ++index) {
                if (skipOverSkGr[index].directory == dirNo
                        && strcmp(filename.c_str(), skipOverSkGr[index].filename) == 0) {
                    goto skipOver;
                }
            }
            if (preParser.match(filename, &statusStream, &state.fResult)) {
                addError(&state);
                ++testCount;
                goto checkEarlyExit;
            }
            if (state.fSmallestError > 5000000) {
                goto breakOut;
            }
            {
                TestResult& result = state.fResult;
                result.test(dirNo, filename);
                SkString outStr(result.status());
                statusStream.write(outStr.c_str(), outStr.size());
                statusStream.flush();
                if (1) {
                    SkDebugf("%s", outStr.c_str());
                }
                bool noMatch = addError(&state);
                if (noMatch) {
                    smallCount = 0;
                } else if (++smallCount > 10000) {
                    goto breakOut;
                }
            }
            ++testCount;
            if (reporter->verbose()) {
                if (testCount % 100 == 0) {
                    SkDebugf("#%d\n", testCount);
                }
            }
     skipOver:
             reporter->bumpTestCount();
    checkEarlyExit:
            if (1 && testCount == 20) {
                break;
            }
        }
    }
breakOut:
    if (reporter->verbose()) {
        for (int index = 0; index < state.fFoundCount; ++index) {
            SkDebugf("%d %s %d\n", state.fDirsFound[index], state.fFilesFound[index],
                     state.fError[index]);
        }
    }
    for (int index = 0; index < state.fFoundCount; ++index) {
        TestResult::Test(state.fDirsFound[index], state.fFilesFound[index], kEncodeFiles,
                reporter->verbose());
        if (reporter->verbose()) SkDebugf("+");
    }
}

static void bumpCount(skiatest::Reporter* reporter, bool skipping) {
    if (reporter->verbose()) {
        static int threadTestCount;
        sk_atomic_inc(&threadTestCount);
        if (!skipping && threadTestCount % 100 == 0) {
            SkDebugf("#%d\n", threadTestCount);
        }
        if (skipping && threadTestCount % 10000 == 0) {
            SkDebugf("#%d\n", threadTestCount);
        }
    }
}

static void testSkGrMain(SkpSkGrThreadState* data) {
    data->fResult.testOne();
    bumpCount(data->fReporter, false);
    data->fReporter->bumpTestCount();
}

DEF_TEST(SkpSkGrThreaded, reporter) {
    if (!initTest()) {
        return;
    }
    SkpSkGrThreadedTestRunner testRunner(reporter);
    for (int dirIndex = 1; dirIndex <= 100; ++dirIndex) {
        SkString pictDir = make_in_dir_name(dirIndex);
        if (pictDir.size() == 0) {
            continue;
        }
        SkOSFile::Iter iter(pictDir.c_str(), "skp");
        SkString filename;
        while (iter.next(&filename)) {
            SkString pngName = make_png_name(filename.c_str());
            SkString oldPng = make_filepath(dirIndex, outSkDir, pngName.c_str());
            SkString newPng = make_filepath(dirIndex, outGrDir, pngName.c_str());
            if (sk_exists(oldPng.c_str()) && sk_exists(newPng.c_str())) {
                bumpCount(reporter, true);
                continue;
            }
            for (size_t index = 0; index < skipOverSkGrCount; ++index) {
                if (skipOverSkGr[index].directory == dirIndex
                        && strcmp(filename.c_str(), skipOverSkGr[index].filename) == 0) {
                    bumpCount(reporter, true);
                    goto skipOver;
                }
            }
            *testRunner.fRunnables.append() = new SkpSkGrThreadedRunnable(
                    &testSkGrMain, dirIndex, filename.c_str(), &testRunner);
    skipOver:
            ;
        }
    }
    testRunner.render();
    SkpSkGrThreadState& max = testRunner.fRunnables[0]->fState;
    for (int dirIndex = 2; dirIndex <= 100; ++dirIndex) {
        SkpSkGrThreadState& state = testRunner.fRunnables[dirIndex - 1]->fState;
        for (int index = 0; index < state.fFoundCount; ++index) {
            int maxIdx = max.fFoundCount;
            if (maxIdx < kMaxFiles) {
                max.fError[maxIdx] = state.fError[index];
                strcpy(max.fFilesFound[maxIdx], state.fFilesFound[index]);
                max.fDirsFound[maxIdx] = state.fDirsFound[index];
                ++max.fFoundCount;
                continue;
            }
            for (maxIdx = 0; maxIdx < max.fFoundCount; ++maxIdx) {
                if (max.fError[maxIdx] < state.fError[index]) {
                    max.fError[maxIdx] = state.fError[index];
                    strcpy(max.fFilesFound[maxIdx], state.fFilesFound[index]);
                    max.fDirsFound[maxIdx] = state.fDirsFound[index];
                    break;
                }
            }
        }
    }
    TestResult encoder;
    encoder.fTestStep = kEncodeFiles;
    for (int index = 0; index < max.fFoundCount; ++index) {
        encoder.fDirNo = max.fDirsFound[index];
        strcpy(encoder.fFilename, max.fFilesFound[index]);
        encoder.testOne();
        SkDebugf("+");
    }
}

DEF_TEST(SkpSkGrOneOff, reporter) {
    if (!initTest()) {
        return;
    }
    int testIndex = 166;
    int dirIndex = skipOverSkGr[testIndex - 166].directory;
    SkString pictDir = make_in_dir_name(dirIndex);
    if (pictDir.size() == 0) {
        return;
    }
    SkString filename(skipOverSkGr[testIndex - 166].filename);
    TestResult::Test(dirIndex, filename.c_str(), kCompareBits, reporter->verbose());
    TestResult::Test(dirIndex, filename.c_str(), kEncodeFiles, reporter->verbose());
}
