/*
 * 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 "Resources.h"
#include "SkBitmap.h"
#include "SkCanvas.h"
#include "SkColor.h"
#include "SkColorPriv.h"
#include "SkData.h"
#include "SkDecodingImageGenerator.h"
#include "SkDiscardableMemoryPool.h"
#include "SkForceLinking.h"
#include "SkGradientShader.h"
#include "SkImageDecoder.h"
#include "SkImageEncoder.h"
#include "SkImageGeneratorPriv.h"
#include "SkImagePriv.h"
#include "SkOSFile.h"
#include "SkPoint.h"
#include "SkShader.h"
#include "SkStream.h"
#include "SkString.h"
#include "Test.h"

__SK_FORCE_IMAGE_DECODER_LINKING;

/**
 *  Interprets c as an unpremultiplied color, and returns the
 *  premultiplied equivalent.
 */
static SkPMColor premultiply_unpmcolor(SkPMColor c) {
    U8CPU a = SkGetPackedA32(c);
    U8CPU r = SkGetPackedR32(c);
    U8CPU g = SkGetPackedG32(c);
    U8CPU b = SkGetPackedB32(c);
    return SkPreMultiplyARGB(a, r, g, b);
}

/**
 *  Return true if this stream format should be skipped, due
 *  to do being an opaque format or not a valid format.
 */
static bool skip_image_format(SkImageDecoder::Format format) {
    switch (format) {
        case SkImageDecoder::kPNG_Format:
        case SkImageDecoder::kWEBP_Format:
            return false;
        // Skip unknown since it will not be decoded anyway.
        case SkImageDecoder::kUnknown_Format:
        // Technically ICO and BMP supports alpha channels, but our image
        // decoders do not, so skip them as well.
        case SkImageDecoder::kICO_Format:
        case SkImageDecoder::kBMP_Format:
        // KTX and ASTC are texture formats so it's not particularly clear how to 
        // decode the alpha from them.
        case SkImageDecoder::kKTX_Format:
        case SkImageDecoder::kASTC_Format:
        // The rest of these are opaque.
        case SkImageDecoder::kPKM_Format:
        case SkImageDecoder::kWBMP_Format:
        case SkImageDecoder::kGIF_Format:
        case SkImageDecoder::kJPEG_Format:
            return true;
    }
    SkASSERT(false);
    return true;
}

/**
 *  Test decoding an image in premultiplied mode and unpremultiplied mode and compare
 *  them.
 */
static void compare_unpremul(skiatest::Reporter* reporter, const SkString& filename) {
    // Decode a resource:
    SkBitmap bm8888;
    SkBitmap bm8888Unpremul;

    SkFILEStream stream(filename.c_str());

    SkImageDecoder::Format format = SkImageDecoder::GetStreamFormat(&stream);
    if (skip_image_format(format)) {
        return;
    }

    SkAutoTDelete<SkImageDecoder> decoder(SkImageDecoder::Factory(&stream));
    if (NULL == decoder.get()) {
        SkDebugf("couldn't decode %s\n", filename.c_str());
        return;
    }

    bool success = decoder->decode(&stream, &bm8888, kN32_SkColorType,
                                   SkImageDecoder::kDecodePixels_Mode) != SkImageDecoder::kFailure;
    if (!success) {
        return;
    }

    success = stream.rewind();
    REPORTER_ASSERT(reporter, success);
    if (!success) {
        return;
    }

    decoder->setRequireUnpremultipliedColors(true);
    success = decoder->decode(&stream, &bm8888Unpremul, kN32_SkColorType,
                              SkImageDecoder::kDecodePixels_Mode) != SkImageDecoder::kFailure;
    if (!success) {
        return;
    }

    bool dimensionsMatch = bm8888.width() == bm8888Unpremul.width()
                           && bm8888.height() == bm8888Unpremul.height();
    REPORTER_ASSERT(reporter, dimensionsMatch);
    if (!dimensionsMatch) {
        return;
    }

    // Only do the comparison if the two bitmaps are both 8888.
    if (bm8888.colorType() != kN32_SkColorType || bm8888Unpremul.colorType() != kN32_SkColorType) {
        return;
    }

    // Now compare the two bitmaps.
    for (int i = 0; i < bm8888.width(); ++i) {
        for (int j = 0; j < bm8888.height(); ++j) {
            // "c0" is the color of the premultiplied bitmap at (i, j).
            const SkPMColor c0 = *bm8888.getAddr32(i, j);
            // "c1" is the result of premultiplying the color of the unpremultiplied
            // bitmap at (i, j).
            const SkPMColor c1 = premultiply_unpmcolor(*bm8888Unpremul.getAddr32(i, j));
            // Compute the difference for each component.
            int da = SkAbs32(SkGetPackedA32(c0) - SkGetPackedA32(c1));
            int dr = SkAbs32(SkGetPackedR32(c0) - SkGetPackedR32(c1));
            int dg = SkAbs32(SkGetPackedG32(c0) - SkGetPackedG32(c1));
            int db = SkAbs32(SkGetPackedB32(c0) - SkGetPackedB32(c1));

            // Alpha component must be exactly the same.
            REPORTER_ASSERT(reporter, 0 == da);

            // Color components may not match exactly due to rounding error.
            REPORTER_ASSERT(reporter, dr <= 1);
            REPORTER_ASSERT(reporter, dg <= 1);
            REPORTER_ASSERT(reporter, db <= 1);
        }
    }
}

static void test_unpremul(skiatest::Reporter* reporter) {
    // This test cannot run if there is no resource path.
    SkString resourcePath = GetResourcePath();
    if (resourcePath.isEmpty()) {
        SkDebugf("Could not run unpremul test because resourcePath not specified.");
        return;
    }
    SkOSFile::Iter iter(resourcePath.c_str());
    SkString basename;
    if (iter.next(&basename)) {
        do {
            SkString filename = SkOSPath::Join(resourcePath.c_str(), basename.c_str());
            // SkDebugf("about to decode \"%s\"\n", filename.c_str());
            compare_unpremul(reporter, filename);
        } while (iter.next(&basename));
    } else {
        SkDebugf("Failed to find any files :(\n");
    }
}

#if defined(SK_BUILD_FOR_ANDROID) || defined(SK_BUILD_FOR_UNIX)
// Test that the alpha type is what we expect.
static void test_alphaType(skiatest::Reporter* reporter, const SkString& filename,
                           bool requireUnpremul) {
    SkBitmap bm;
    SkFILEStream stream(filename.c_str());

    SkAutoTDelete<SkImageDecoder> decoder(SkImageDecoder::Factory(&stream));
    if (NULL == decoder.get()) {
        return;
    }

    decoder->setRequireUnpremultipliedColors(requireUnpremul);

    // Decode just the bounds. This should always succeed.
    bool success = decoder->decode(&stream, &bm, kN32_SkColorType,
                                   SkImageDecoder::kDecodeBounds_Mode);
    REPORTER_ASSERT(reporter, success);
    if (!success) {
        return;
    }

    // Keep track of the alpha type for testing later. If the full decode
    // succeeds, the alpha type should be the same, unless the full decode
    // determined that the alpha type should actually be opaque, which may
    // not be known when only decoding the bounds.
    const SkAlphaType boundsAlphaType = bm.alphaType();

    // rewind should always succeed on SkFILEStream.
    success = stream.rewind();
    REPORTER_ASSERT(reporter, success);
    if (!success) {
        return;
    }

    success = decoder->decode(&stream, &bm, kN32_SkColorType, SkImageDecoder::kDecodePixels_Mode);

    if (!success) {
        // When the decoder is set to require unpremul, if it does not support
        // unpremul it will fail. This is the only reason the decode should
        // fail (since we know the files we are using to test can be decoded).
        REPORTER_ASSERT(reporter, requireUnpremul);
        return;
    }

    // The bounds decode should return with either the requested
    // premul/unpremul or opaque, if that value could be determined when only
    // decoding the bounds.
    if (requireUnpremul) {
        REPORTER_ASSERT(reporter, kUnpremul_SkAlphaType == boundsAlphaType
                                  || kOpaque_SkAlphaType == boundsAlphaType);
    } else {
        REPORTER_ASSERT(reporter, kPremul_SkAlphaType == boundsAlphaType
                                  || kOpaque_SkAlphaType == boundsAlphaType);
    }

    // When decoding the full image, the alpha type should match the one
    // returned by the bounds decode, unless the full decode determined that
    // the alpha type is actually opaque.
    REPORTER_ASSERT(reporter, bm.alphaType() == boundsAlphaType
                              || bm.alphaType() == kOpaque_SkAlphaType);
}

DEF_TEST(ImageDecoding_alphaType, reporter) {
    SkString resourcePath = GetResourcePath();
    if (resourcePath.isEmpty()) {
        SkDebugf("Could not run alphaType test because resourcePath not specified.");
        return;
    }

    SkOSFile::Iter iter(resourcePath.c_str());
    SkString basename;
    if (iter.next(&basename)) {
        do {
            SkString filename = SkOSPath::Join(resourcePath.c_str(), basename.c_str());
            for (int truth = 0; truth <= 1; ++truth) {
                test_alphaType(reporter, filename, SkToBool(truth));
            }
        } while (iter.next(&basename));
    } else {
        SkDebugf("Failed to find any files :(\n");
    }

}

// Using known images, test that decoding into unpremul and premul behave as expected.
DEF_TEST(ImageDecoding_unpremul, reporter) {
    SkString resourcePath = GetResourcePath();
    if (resourcePath.isEmpty()) {
        SkDebugf("Could not run unpremul test because resourcePath not specified.");
        return;
    }
    const char* root = "half-transparent-white-pixel";
    const char* suffixes[] = { ".png", ".webp" };

    for (size_t i = 0; i < SK_ARRAY_COUNT(suffixes); ++i) {
        SkString basename = SkStringPrintf("%s%s", root, suffixes[i]);
        SkString fullName = SkOSPath::Join(resourcePath.c_str(), basename.c_str());

        SkBitmap bm;
        SkFILEStream stream(fullName.c_str());

        if (!stream.isValid()) {
            SkDebugf("file %s missing from resource directoy %s\n",
                     basename.c_str(), resourcePath.c_str());
            continue;
        }

        // This should never fail since we know the images we're decoding.
        SkAutoTDelete<SkImageDecoder> decoder(SkImageDecoder::Factory(&stream));
        REPORTER_ASSERT(reporter, decoder.get());
        if (NULL == decoder.get()) {
            continue;
        }

        // Test unpremultiplied. We know what color this should result in.
        decoder->setRequireUnpremultipliedColors(true);
        bool success = decoder->decode(&stream, &bm, kN32_SkColorType,
                                       SkImageDecoder::kDecodePixels_Mode);
        REPORTER_ASSERT(reporter, success);
        if (!success) {
            continue;
        }

        REPORTER_ASSERT(reporter, bm.width() == 1 && bm.height() == 1);
        {
            SkAutoLockPixels alp(bm);
            REPORTER_ASSERT(reporter, bm.getAddr32(0, 0)[0] == 0x7fffffff);
        }

        success = stream.rewind();
        REPORTER_ASSERT(reporter, success);
        if (!success) {
            continue;
        }

        // Test premultiplied. Once again, we know which color this should
        // result in.
        decoder->setRequireUnpremultipliedColors(false);
        success = decoder->decode(&stream, &bm, kN32_SkColorType,
                                  SkImageDecoder::kDecodePixels_Mode);
        REPORTER_ASSERT(reporter, success);
        if (!success) {
            continue;
        }

        REPORTER_ASSERT(reporter, bm.width() == 1 && bm.height() == 1);
        {
            SkAutoLockPixels alp(bm);
            REPORTER_ASSERT(reporter, bm.getAddr32(0, 0)[0] == 0x7f7f7f7f);
        }
    }
}
#endif // SK_BUILD_FOR_UNIX/ANDROID skbug.com/2388

#ifdef SK_DEBUG
// Create a stream containing a bitmap encoded to Type type.
static SkMemoryStream* create_image_stream(SkImageEncoder::Type type) {
    SkBitmap bm;
    const int size = 50;
    bm.allocN32Pixels(size, size);
    SkCanvas canvas(bm);
    SkPoint points[2] = {
        { SkIntToScalar(0), SkIntToScalar(0) },
        { SkIntToScalar(size), SkIntToScalar(size) }
    };
    SkColor colors[2] = { SK_ColorWHITE, SK_ColorBLUE };
    SkShader* shader = SkGradientShader::CreateLinear(points, colors, NULL,
                                                      SK_ARRAY_COUNT(colors),
                                                      SkShader::kClamp_TileMode);
    SkPaint paint;
    paint.setShader(shader)->unref();
    canvas.drawPaint(paint);
    // Now encode it to a stream.
    SkAutoTUnref<SkData> data(SkImageEncoder::EncodeData(bm, type, 100));
    if (NULL == data.get()) {
        return NULL;
    }
    return SkNEW_ARGS(SkMemoryStream, (data.get()));
}

// For every format that supports tile based decoding, ensure that
// calling decodeSubset will not fail if the caller has unreffed the
// stream provided in buildTileIndex.
// Only runs in debug mode since we are testing for a crash.
static void test_stream_life() {
    const SkImageEncoder::Type gTypes[] = {
#ifdef SK_BUILD_FOR_ANDROID
        SkImageEncoder::kJPEG_Type,
        SkImageEncoder::kPNG_Type,
#endif
        SkImageEncoder::kWEBP_Type,
    };
    for (size_t i = 0; i < SK_ARRAY_COUNT(gTypes); ++i) {
        // SkDebugf("encoding to %i\n", i);
        SkAutoTUnref<SkMemoryStream> stream(create_image_stream(gTypes[i]));
        if (NULL == stream.get()) {
            SkDebugf("no stream\n");
            continue;
        }
        SkAutoTDelete<SkImageDecoder> decoder(SkImageDecoder::Factory(stream));
        if (NULL == decoder.get()) {
            SkDebugf("no decoder\n");
            continue;
        }
        int width, height;
        if (!decoder->buildTileIndex(stream.get(), &width, &height)) {
            SkDebugf("could not build a tile index\n");
            continue;
        }
        // Now unref the stream to make sure it survives
        stream.reset(NULL);
        SkBitmap bm;
        decoder->decodeSubset(&bm, SkIRect::MakeWH(width, height), kN32_SkColorType);
    }
}

// Test inside SkScaledBitmapSampler.cpp
extern void test_row_proc_choice();

#endif  // SK_DEBUG

DEF_TEST(ImageDecoding, reporter) {
    test_unpremul(reporter);
#ifdef SK_DEBUG
    test_stream_life();
    test_row_proc_choice();
#endif
}

// expected output for 8x8 bitmap
static const int kExpectedWidth = 8;
static const int kExpectedHeight = 8;
static const SkColor kExpectedPixels[] = {
    0xffbba570, 0xff395f5d, 0xffe25c39, 0xff197666,
    0xff3cba27, 0xffdefcb0, 0xffc13874, 0xfffa0093,
    0xffbda60e, 0xffc01db6, 0xff2bd688, 0xff9362d4,
    0xffc641b2, 0xffa5cede, 0xff606eba, 0xff8f4bf3,
    0xff3bf742, 0xff8f02a8, 0xff5509df, 0xffc7027e,
    0xff24aa8a, 0xff886c96, 0xff625481, 0xff403689,
    0xffc52152, 0xff78ccd6, 0xffdcb4ab, 0xff09d27d,
    0xffca00f3, 0xff605d47, 0xff446fb2, 0xff576e46,
    0xff273df9, 0xffb41a83, 0xfff812c3, 0xffccab67,
    0xff034218, 0xff7db9a7, 0xff821048, 0xfffe4ab4,
    0xff6fac98, 0xff941d27, 0xff5fe411, 0xfffbb283,
    0xffd86e99, 0xff169162, 0xff71128c, 0xff39cab4,
    0xffa7fe63, 0xff4c956b, 0xffbc22e0, 0xffb272e4,
    0xff129f4a, 0xffe34513, 0xff3d3742, 0xffbd190a,
    0xffb07222, 0xff2e23f8, 0xfff089d9, 0xffb35738,
    0xffa86022, 0xff3340fe, 0xff95fe71, 0xff6a71df
};
SK_COMPILE_ASSERT((kExpectedWidth * kExpectedHeight)
                  == SK_ARRAY_COUNT(kExpectedPixels), array_size_mismatch);

DEF_TEST(WebP, reporter) {
    const unsigned char encodedWebP[] = {
        0x52, 0x49, 0x46, 0x46, 0x2c, 0x01, 0x00, 0x00, 0x57, 0x45, 0x42, 0x50,
        0x56, 0x50, 0x38, 0x4c, 0x20, 0x01, 0x00, 0x00, 0x2f, 0x07, 0xc0, 0x01,
        0x00, 0xff, 0x01, 0x45, 0x03, 0x00, 0xe2, 0xd5, 0xae, 0x60, 0x2b, 0xad,
        0xd9, 0x68, 0x76, 0xb6, 0x8d, 0x6a, 0x1d, 0xc0, 0xe6, 0x19, 0xd6, 0x16,
        0xb7, 0xb4, 0xef, 0xcf, 0xc3, 0x15, 0x6c, 0xb3, 0xbd, 0x77, 0x0d, 0x85,
        0x6d, 0x1b, 0xa9, 0xb1, 0x2b, 0xdc, 0x3d, 0x83, 0xdb, 0x00, 0x00, 0xc8,
        0x26, 0xe5, 0x01, 0x99, 0x8a, 0xd5, 0xdd, 0xfc, 0x82, 0xcd, 0xcd, 0x9a,
        0x8c, 0x13, 0xcc, 0x1b, 0xba, 0xf5, 0x05, 0xdb, 0xee, 0x6a, 0xdb, 0x38,
        0x60, 0xfe, 0x43, 0x2c, 0xd4, 0x6a, 0x99, 0x4d, 0xc6, 0xc0, 0xd3, 0x28,
        0x1b, 0xc1, 0xb1, 0x17, 0x4e, 0x43, 0x0e, 0x3d, 0x27, 0xe9, 0xe4, 0x84,
        0x4f, 0x24, 0x62, 0x69, 0x85, 0x43, 0x8d, 0xc2, 0x04, 0x00, 0x07, 0x59,
        0x60, 0xfd, 0x8b, 0x4d, 0x60, 0x32, 0x72, 0xcf, 0x88, 0x0c, 0x2f, 0x2f,
        0xad, 0x62, 0xbd, 0x27, 0x09, 0x16, 0x70, 0x78, 0x6c, 0xd9, 0x82, 0xef,
        0x1a, 0xa2, 0xcc, 0xf0, 0xf1, 0x6f, 0xd8, 0x78, 0x2e, 0x39, 0xa1, 0xcf,
        0x14, 0x4b, 0x89, 0xb4, 0x1b, 0x48, 0x15, 0x7c, 0x48, 0x6f, 0x8c, 0x20,
        0xb7, 0x00, 0xcf, 0xfc, 0xdb, 0xd0, 0xe9, 0xe7, 0x42, 0x09, 0xa4, 0x03,
        0x40, 0xac, 0xda, 0x40, 0x01, 0x00, 0x5f, 0xa1, 0x3d, 0x64, 0xe1, 0xf4,
        0x03, 0x45, 0x29, 0xe0, 0xe2, 0x4a, 0xc3, 0xa2, 0xe8, 0xe0, 0x25, 0x12,
        0x74, 0xc6, 0xe8, 0xfb, 0x93, 0x4f, 0x9f, 0x5e, 0xc0, 0xa6, 0x91, 0x1b,
        0xa4, 0x24, 0x82, 0xc3, 0x61, 0x07, 0x4c, 0x49, 0x4f, 0x53, 0xae, 0x5f,
        0x5d, 0x39, 0x36, 0xc0, 0x5b, 0x57, 0x54, 0x60, 0x10, 0x00, 0x00, 0xd1,
        0x68, 0xb6, 0x6d, 0xdb, 0x36, 0x22, 0xfa, 0x1f, 0x35, 0x75, 0x22, 0xec,
        0x31, 0xbc, 0x5d, 0x8f, 0x87, 0x53, 0xa2, 0x05, 0x8c, 0x2f, 0xcd, 0xa8,
        0xa7, 0xf3, 0xa3, 0xbd, 0x83, 0x8b, 0x2a, 0xc8, 0x58, 0xf5, 0xac, 0x80,
        0xe3, 0xfe, 0x66, 0xa4, 0x7c, 0x1b, 0x6c, 0xd1, 0xa9, 0xd8, 0x14, 0xd0,
        0xc5, 0xb5, 0x39, 0x71, 0x97, 0x19, 0x19, 0x1b
    };
    SkAutoDataUnref encoded(SkData::NewWithCopy(encodedWebP,
                                                sizeof(encodedWebP)));
    SkBitmap bm;

    bool success = SkInstallDiscardablePixelRef(
        SkDecodingImageGenerator::Create(encoded,
            SkDecodingImageGenerator::Options()), &bm);

    REPORTER_ASSERT(reporter, success);
    if (!success) {
        return;
    }
    SkAutoLockPixels alp(bm);

    bool rightSize = ((kExpectedWidth == bm.width())
                      && (kExpectedHeight == bm.height()));
    REPORTER_ASSERT(reporter, rightSize);
    if (rightSize) {
        bool error = false;
        const SkColor* correctPixel = kExpectedPixels;
        for (int y = 0; y < bm.height(); ++y) {
            for (int x = 0; x < bm.width(); ++x) {
                error |= (*correctPixel != bm.getColor(x, y));
                ++correctPixel;
            }
        }
        REPORTER_ASSERT(reporter, !error);
    }
}

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

// example of how Android will do this inside their BitmapFactory
static SkPixelRef* install_pixel_ref(SkBitmap* bitmap,
                                     SkStreamRewindable* stream,
                                     int sampleSize, bool ditherImage) {
    SkASSERT(bitmap != NULL);
    SkASSERT(stream != NULL);
    SkASSERT(stream->rewind());
    SkASSERT(stream->unique());
    SkColorType colorType = bitmap->colorType();
    SkDecodingImageGenerator::Options opts(sampleSize, ditherImage, colorType);
    if (SkInstallDiscardablePixelRef(
                SkDecodingImageGenerator::Create(stream, opts), bitmap)) {
        return bitmap->pixelRef();
    }
    return NULL;
}
/**
 *  A test for the SkDecodingImageGenerator::Create and
 *  SkInstallDiscardablePixelRef functions.
 */
DEF_TEST(ImprovedBitmapFactory, reporter) {
    SkString pngFilename = GetResourcePath("randPixels.png");
    SkAutoTUnref<SkStreamRewindable> stream(SkStream::NewFromFile(pngFilename.c_str()));
    if (sk_exists(pngFilename.c_str())) {
        SkBitmap bm;
        SkAssertResult(bm.setInfo(SkImageInfo::MakeN32Premul(1, 1)));
        REPORTER_ASSERT(reporter,
            install_pixel_ref(&bm, stream.detach(), 1, true));
        SkAutoLockPixels alp(bm);
        REPORTER_ASSERT(reporter, bm.getPixels());
    }
}


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

#if defined(SK_BUILD_FOR_ANDROID) || defined(SK_BUILD_FOR_UNIX)
static inline bool check_rounding(int value, int dividend, int divisor) {
    // returns true if the value is greater than floor(dividend/divisor)
    // and less than SkNextPow2(ceil(dividend - divisor))
    return (((divisor * value) > (dividend - divisor))
            && value <= SkNextPow2(((dividend - 1) / divisor) + 1));
}
#endif  // SK_BUILD_FOR_ANDROID || SK_BUILD_FOR_UNIX


#if SK_PMCOLOR_BYTE_ORDER(B,G,R,A)
    #define kBackwards_SkColorType kRGBA_8888_SkColorType
#elif SK_PMCOLOR_BYTE_ORDER(R,G,B,A)
    #define kBackwards_SkColorType kBGRA_8888_SkColorType
#else
    #error "SK_*32_SHFIT values must correspond to BGRA or RGBA byte order"
#endif

static inline const char* SkColorType_to_string(SkColorType colorType) {
    switch(colorType) {
        case kAlpha_8_SkColorType:   return "Alpha_8";
        case kRGB_565_SkColorType:   return "RGB_565";
        case kARGB_4444_SkColorType: return "ARGB_4444";
        case kN32_SkColorType:       return "N32";
        case kBackwards_SkColorType: return "Backwards";
        case kIndex_8_SkColorType:   return "Index_8";
        default:                     return "ERROR";
    }
}

static inline const char* options_colorType(
        const SkDecodingImageGenerator::Options& opts) {
    if (opts.fUseRequestedColorType) {
        return SkColorType_to_string(opts.fRequestedColorType);
    } else {
        return "(none)";
    }
}

static inline const char* yn(bool value) {
    if (value) {
        return "yes";
    } else {
        return "no";
    }
}

/**
 * Given either a SkStream or a SkData, try to decode the encoded
 * image using the specified options and report errors.
 */
static void test_options(skiatest::Reporter* reporter,
                         const SkDecodingImageGenerator::Options& opts,
                         SkStreamRewindable* encodedStream,
                         SkData* encodedData,
                         bool useData,
                         const SkString& path) {
    SkBitmap bm;
    bool success = false;
    if (useData) {
        if (NULL == encodedData) {
            return;
        }
        success = SkInstallDiscardablePixelRef(
            SkDecodingImageGenerator::Create(encodedData, opts), &bm);
    } else {
        if (NULL == encodedStream) {
            return;
        }
        success = SkInstallDiscardablePixelRef(
            SkDecodingImageGenerator::Create(encodedStream->duplicate(), opts), &bm);
    }
    if (!success) {
        if (opts.fUseRequestedColorType
            && (kARGB_4444_SkColorType == opts.fRequestedColorType)) {
            return;  // Ignore known conversion inabilities.
        }
        // If we get here, it's a failure and we will need more
        // information about why it failed.
        ERRORF(reporter, "Bounds decode failed [sampleSize=%d dither=%s "
               "colorType=%s %s]", opts.fSampleSize, yn(opts.fDitherImage),
               options_colorType(opts), path.c_str());
        return;
    }
    #if defined(SK_BUILD_FOR_ANDROID) || defined(SK_BUILD_FOR_UNIX)
    // Android is the only system that use Skia's image decoders in
    // production.  For now, we'll only verify that samplesize works
    // on systems where it already is known to work.
    REPORTER_ASSERT(reporter, check_rounding(bm.height(), kExpectedHeight,
                                             opts.fSampleSize));
    REPORTER_ASSERT(reporter, check_rounding(bm.width(), kExpectedWidth,
                                             opts.fSampleSize));
    // The ImageDecoder API doesn't guarantee that SampleSize does
    // anything at all, but the decoders that this test excercises all
    // produce an output size in the following range:
    //    (((sample_size * out_size) > (in_size - sample_size))
    //     && out_size <= SkNextPow2(((in_size - 1) / sample_size) + 1));
    #endif  // SK_BUILD_FOR_ANDROID || SK_BUILD_FOR_UNIX
    SkAutoLockPixels alp(bm);
    if (bm.getPixels() == NULL) {
        ERRORF(reporter, "Pixel decode failed [sampleSize=%d dither=%s "
               "colorType=%s %s]", opts.fSampleSize, yn(opts.fDitherImage),
               options_colorType(opts), path.c_str());
        return;
    }

    SkColorType requestedColorType = opts.fRequestedColorType;
    REPORTER_ASSERT(reporter,
                    (!opts.fUseRequestedColorType)
                    || (bm.colorType() == requestedColorType));

    // Condition under which we should check the decoding results:
    if ((kN32_SkColorType == bm.colorType())
        && (!path.endsWith(".jpg"))  // lossy
        && (opts.fSampleSize == 1)) {  // scaled
        const SkColor* correctPixels = kExpectedPixels;
        SkASSERT(bm.height() == kExpectedHeight);
        SkASSERT(bm.width() == kExpectedWidth);
        int pixelErrors = 0;
        for (int y = 0; y < bm.height(); ++y) {
            for (int x = 0; x < bm.width(); ++x) {
                if (*correctPixels != bm.getColor(x, y)) {
                    ++pixelErrors;
                }
                ++correctPixels;
            }
        }
        if (pixelErrors != 0) {
            ERRORF(reporter, "Pixel-level mismatch (%d of %d) "
                   "[sampleSize=%d dither=%s colorType=%s %s]",
                   pixelErrors, kExpectedHeight * kExpectedWidth,
                   opts.fSampleSize, yn(opts.fDitherImage),
                   options_colorType(opts), path.c_str());
        }
    }
}

/**
 *  SkDecodingImageGenerator has an Options struct which lets the
 *  client of the generator set sample size, dithering, and bitmap
 *  config.  This test loops through many possible options and tries
 *  them on a set of 5 small encoded images (each in a different
 *  format).  We test both SkData and SkStreamRewindable decoding.
 */
DEF_TEST(ImageDecoderOptions, reporter) {
    const char* files[]  = {
        "randPixels.bmp",
        "randPixels.jpg",
        "randPixels.png",
        "randPixels.webp",
        #if !defined(SK_BUILD_FOR_WIN)
        // TODO(halcanary): Find out why this fails sometimes.
        "randPixels.gif",
        #endif
    };

    SkString resourceDir = GetResourcePath();
    if (!sk_exists(resourceDir.c_str())) {
        return;
    }

    int scaleList[] = {1, 2, 3, 4};
    bool ditherList[] = {true, false};
    SkColorType colorList[] = {
        kAlpha_8_SkColorType,
        kRGB_565_SkColorType,
        kARGB_4444_SkColorType,  // Most decoders will fail on 4444.
        kN32_SkColorType
        // Note that indexed color is left out of the list.  Lazy
        // decoding doesn't do indexed color.
    };
    const bool useDataList[] = {true, false};

    for (size_t fidx = 0; fidx < SK_ARRAY_COUNT(files); ++fidx) {
        SkString path = SkOSPath::Join(resourceDir.c_str(), files[fidx]);
        if (!sk_exists(path.c_str())) {
            continue;
        }

        SkAutoDataUnref encodedData(SkData::NewFromFileName(path.c_str()));
        REPORTER_ASSERT(reporter, encodedData.get() != NULL);
        SkAutoTUnref<SkStreamRewindable> encodedStream(
            SkStream::NewFromFile(path.c_str()));
        REPORTER_ASSERT(reporter, encodedStream.get() != NULL);

        for (size_t i = 0; i < SK_ARRAY_COUNT(scaleList); ++i) {
            for (size_t j = 0; j < SK_ARRAY_COUNT(ditherList); ++j) {
                for (size_t m = 0; m < SK_ARRAY_COUNT(useDataList); ++m) {
                    for (size_t k = 0; k < SK_ARRAY_COUNT(colorList); ++k) {
                        SkDecodingImageGenerator::Options opts(scaleList[i],
                                                               ditherList[j],
                                                               colorList[k]);
                        test_options(reporter, opts, encodedStream, encodedData,
                                     useDataList[m], path);

                    }
                    SkDecodingImageGenerator::Options options(scaleList[i],
                                                              ditherList[j]);
                    test_options(reporter, options, encodedStream, encodedData,
                                 useDataList[m], path);
                }
            }
        }
    }
}

DEF_TEST(DiscardablePixelRef_SecondLockColorTableCheck, r) {
    SkString resourceDir = GetResourcePath();
    SkString path = SkOSPath::Join(resourceDir.c_str(), "randPixels.gif");
    if (!sk_exists(path.c_str())) {
        return;
    }
    SkAutoDataUnref encoded(SkData::NewFromFileName(path.c_str()));
    SkBitmap bitmap;
    if (!SkInstallDiscardablePixelRef(
            SkDecodingImageGenerator::Create(
                    encoded, SkDecodingImageGenerator::Options()), &bitmap)) {
        #ifndef SK_BUILD_FOR_WIN
        ERRORF(r, "SkInstallDiscardablePixelRef [randPixels.gif] failed.");
        #endif
        return;
    }
    if (kIndex_8_SkColorType != bitmap.colorType()) {
        return;
    }
    {
        SkAutoLockPixels alp(bitmap);
        REPORTER_ASSERT(r, bitmap.getColorTable() && "first pass");
    }
    {
        SkAutoLockPixels alp(bitmap);
        REPORTER_ASSERT(r, bitmap.getColorTable() && "second pass");
    }
}


////////////////////////////////////////////////////////////////////////////////
namespace {
class SingleAllocator : public SkBitmap::Allocator {
public:
    SingleAllocator(void* p, size_t s) : fPixels(p), fSize(s) { }
    ~SingleAllocator() {}
    // If the pixels in fPixels are big enough, use them.
    virtual bool allocPixelRef(SkBitmap* bm, SkColorTable* ct) SK_OVERRIDE {
        SkASSERT(bm);
        if (bm->info().getSafeSize(bm->rowBytes()) <= fSize) {
            bm->setPixels(fPixels, ct);
            fPixels = NULL;
            fSize = 0;
            return true;
        }
        return bm->tryAllocPixels(NULL, ct);
    }
    bool ready() { return fPixels != NULL; }
private:
    void* fPixels;
    size_t fSize;
};
}  // namespace

/*  This tests for a bug in libjpeg where INT32 is typedefed to long
    and memory can be written to outside of the array. */
DEF_TEST(ImageDecoding_JpegOverwrite, r) {
    SkString resourceDir = GetResourcePath();
    SkString path = SkOSPath::Join(resourceDir.c_str(), "randPixels.jpg");
    SkAutoTUnref<SkStreamAsset> stream(
            SkStream::NewFromFile(path.c_str()));
    if (!stream.get()) {
        SkDebugf("\nPath '%s' missing.\n", path.c_str());
        return;
    }
    SkAutoTDelete<SkImageDecoder> decoder(SkImageDecoder::Factory(stream));
    if (NULL == decoder.get()) {
        ERRORF(r, "\nSkImageDecoder::Factory failed.\n");
        return;
    }
    SkAssertResult(stream->rewind());

    static const uint16_t sentinal = 0xBEEF;
    static const int pixelCount = 16;
    SkAutoTMalloc<uint16_t> pixels(pixelCount + 1);
    // pixels.get() should be 4-byte aligned.
    // This is necessary to reproduce the bug.

    pixels[pixelCount] = sentinal;  // This value should not be changed.

    SkAutoTUnref<SingleAllocator> allocator(
            SkNEW_ARGS(SingleAllocator,
                       ((void*)pixels.get(), sizeof(uint16_t) * pixelCount)));
    decoder->setAllocator(allocator);
    decoder->setSampleSize(2);
    SkBitmap bitmap;
    bool success = decoder->decode(stream, &bitmap, kRGB_565_SkColorType,
                                   SkImageDecoder::kDecodePixels_Mode) != SkImageDecoder::kFailure;
    REPORTER_ASSERT(r, success);
    REPORTER_ASSERT(r, !allocator->ready());  // Decoder used correct memory
    REPORTER_ASSERT(r, sentinal == pixels[pixelCount]);
}
