/*
 * Copyright 2007 The Android Open Source Project
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */


#include "SkScaledBitmapSampler.h"
#include "SkBitmap.h"
#include "SkColorPriv.h"
#include "SkDither.h"
#include "SkTypes.h"

// 8888

static bool Sample_Gray_D8888(void* SK_RESTRICT dstRow,
                              const uint8_t* SK_RESTRICT src,
                              int width, int deltaSrc, int, const SkPMColor[]) {
    SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
    for (int x = 0; x < width; x++) {
        dst[x] = SkPackARGB32(0xFF, src[0], src[0], src[0]);
        src += deltaSrc;
    }
    return false;
}

static SkScaledBitmapSampler::RowProc
get_gray_to_8888_proc(const SkScaledBitmapSampler::Options& opts) {
    // Dither, unpremul, and skipZeroes have no effect
    return Sample_Gray_D8888;
}

static bool Sample_RGBx_D8888(void* SK_RESTRICT dstRow,
                              const uint8_t* SK_RESTRICT src,
                              int width, int deltaSrc, int, const SkPMColor[]) {
    SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
    for (int x = 0; x < width; x++) {
        dst[x] = SkPackARGB32(0xFF, src[0], src[1], src[2]);
        src += deltaSrc;
    }
    return false;
}

static SkScaledBitmapSampler::RowProc
get_RGBx_to_8888_proc(const SkScaledBitmapSampler::Options& opts) {
    // Dither, unpremul, and skipZeroes have no effect
    return Sample_RGBx_D8888;
}

static bool Sample_RGBA_D8888(void* SK_RESTRICT dstRow,
                              const uint8_t* SK_RESTRICT src,
                              int width, int deltaSrc, int, const SkPMColor[]) {
    SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
    unsigned alphaMask = 0xFF;
    for (int x = 0; x < width; x++) {
        unsigned alpha = src[3];
        dst[x] = SkPreMultiplyARGB(alpha, src[0], src[1], src[2]);
        src += deltaSrc;
        alphaMask &= alpha;
    }
    return alphaMask != 0xFF;
}

static bool Sample_RGBA_D8888_Unpremul(void* SK_RESTRICT dstRow,
                                       const uint8_t* SK_RESTRICT src,
                                       int width, int deltaSrc, int,
                                       const SkPMColor[]) {
    uint32_t* SK_RESTRICT dst = reinterpret_cast<uint32_t*>(dstRow);
    unsigned alphaMask = 0xFF;
    for (int x = 0; x < width; x++) {
        unsigned alpha = src[3];
        dst[x] = SkPackARGB32NoCheck(alpha, src[0], src[1], src[2]);
        src += deltaSrc;
        alphaMask &= alpha;
    }
    return alphaMask != 0xFF;
}

static bool Sample_RGBA_D8888_SkipZ(void* SK_RESTRICT dstRow,
                                    const uint8_t* SK_RESTRICT src,
                                    int width, int deltaSrc, int,
                                    const SkPMColor[]) {
    SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
    unsigned alphaMask = 0xFF;
    for (int x = 0; x < width; x++) {
        unsigned alpha = src[3];
        if (0 != alpha) {
            dst[x] = SkPreMultiplyARGB(alpha, src[0], src[1], src[2]);
        }
        src += deltaSrc;
        alphaMask &= alpha;
    }
    return alphaMask != 0xFF;
}

static SkScaledBitmapSampler::RowProc
get_RGBA_to_8888_proc(const SkScaledBitmapSampler::Options& opts) {
    // Dither has no effect.
    if (!opts.fPremultiplyAlpha) {
        // We could check each component for a zero, at the expense of extra checks.
        // For now, just return unpremul.
        return Sample_RGBA_D8888_Unpremul;
    }
    // Supply the versions that premultiply the colors
    if (opts.fSkipZeros) {
        return Sample_RGBA_D8888_SkipZ;
    }
    return Sample_RGBA_D8888;
}

// 565

static bool Sample_Gray_D565(void* SK_RESTRICT dstRow,
                             const uint8_t* SK_RESTRICT src,
                             int width, int deltaSrc, int, const SkPMColor[]) {
    uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow;
    for (int x = 0; x < width; x++) {
        dst[x] = SkPack888ToRGB16(src[0], src[0], src[0]);
        src += deltaSrc;
    }
    return false;
}

static bool Sample_Gray_D565_D(void* SK_RESTRICT dstRow,
                               const uint8_t* SK_RESTRICT src,
                           int width, int deltaSrc, int y, const SkPMColor[]) {
    uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow;
    DITHER_565_SCAN(y);
    for (int x = 0; x < width; x++) {
        dst[x] = SkDitherRGBTo565(src[0], src[0], src[0], DITHER_VALUE(x));
        src += deltaSrc;
    }
    return false;
}

static SkScaledBitmapSampler::RowProc
get_gray_to_565_proc(const SkScaledBitmapSampler::Options& opts) {
    // Unpremul and skip zeroes make no difference
    if (opts.fDither) {
        return Sample_Gray_D565_D;
    }
    return Sample_Gray_D565;
}

static bool Sample_RGBx_D565(void* SK_RESTRICT dstRow,
                             const uint8_t* SK_RESTRICT src,
                             int width, int deltaSrc, int, const SkPMColor[]) {
    uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow;
    for (int x = 0; x < width; x++) {
        dst[x] = SkPack888ToRGB16(src[0], src[1], src[2]);
        src += deltaSrc;
    }
    return false;
}

static bool Sample_RGBx_D565_D(void* SK_RESTRICT dstRow,
                               const uint8_t* SK_RESTRICT src,
                               int width, int deltaSrc, int y,
                               const SkPMColor[]) {
    uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow;
    DITHER_565_SCAN(y);
    for (int x = 0; x < width; x++) {
        dst[x] = SkDitherRGBTo565(src[0], src[1], src[2], DITHER_VALUE(x));
        src += deltaSrc;
    }
    return false;
}

static SkScaledBitmapSampler::RowProc
get_RGBx_to_565_proc(const SkScaledBitmapSampler::Options& opts) {
    // Unpremul and skip zeroes make no difference
    if (opts.fDither) {
        return Sample_RGBx_D565_D;
    }
    return Sample_RGBx_D565;
}


static bool Sample_D565_D565(void* SK_RESTRICT dstRow,
                             const uint8_t* SK_RESTRICT src,
                             int width, int deltaSrc, int, const SkPMColor[]) {
    uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow;
    uint16_t* SK_RESTRICT castedSrc = (uint16_t*) src;
    for (int x = 0; x < width; x++) {
        dst[x] = castedSrc[0];
        castedSrc += deltaSrc >> 1;
    }
    return false;
}

static SkScaledBitmapSampler::RowProc
get_565_to_565_proc(const SkScaledBitmapSampler::Options& opts) {
    // Unpremul, dither, and skip zeroes have no effect
    return Sample_D565_D565;
}

// 4444

static bool Sample_Gray_D4444(void* SK_RESTRICT dstRow,
                              const uint8_t* SK_RESTRICT src,
                              int width, int deltaSrc, int, const SkPMColor[]) {
    SkPMColor16* SK_RESTRICT dst = (SkPMColor16*)dstRow;
    for (int x = 0; x < width; x++) {
        unsigned gray = src[0] >> 4;
        dst[x] = SkPackARGB4444(0xF, gray, gray, gray);
        src += deltaSrc;
    }
    return false;
}

static bool Sample_Gray_D4444_D(void* SK_RESTRICT dstRow,
                                const uint8_t* SK_RESTRICT src,
                            int width, int deltaSrc, int y, const SkPMColor[]) {
    SkPMColor16* SK_RESTRICT dst = (SkPMColor16*)dstRow;
    DITHER_4444_SCAN(y);
    for (int x = 0; x < width; x++) {
        dst[x] = SkDitherARGB32To4444(0xFF, src[0], src[0], src[0],
                                      DITHER_VALUE(x));
        src += deltaSrc;
    }
    return false;
}

static SkScaledBitmapSampler::RowProc
get_gray_to_4444_proc(const SkScaledBitmapSampler::Options& opts) {
    // Skip zeroes and unpremul make no difference
    if (opts.fDither) {
        return Sample_Gray_D4444_D;
    }
    return Sample_Gray_D4444;
}

static bool Sample_RGBx_D4444(void* SK_RESTRICT dstRow,
                              const uint8_t* SK_RESTRICT src,
                              int width, int deltaSrc, int, const SkPMColor[]) {
    SkPMColor16* SK_RESTRICT dst = (SkPMColor16*)dstRow;
    for (int x = 0; x < width; x++) {
        dst[x] = SkPackARGB4444(0xF, src[0] >> 4, src[1] >> 4, src[2] >> 4);
        src += deltaSrc;
    }
    return false;
}

static bool Sample_RGBx_D4444_D(void* SK_RESTRICT dstRow,
                                const uint8_t* SK_RESTRICT src,
                            int width, int deltaSrc, int y, const SkPMColor[]) {
    SkPMColor16* dst = (SkPMColor16*)dstRow;
    DITHER_4444_SCAN(y);

    for (int x = 0; x < width; x++) {
        dst[x] = SkDitherARGB32To4444(0xFF, src[0], src[1], src[2],
                                      DITHER_VALUE(x));
        src += deltaSrc;
    }
    return false;
}

static SkScaledBitmapSampler::RowProc
get_RGBx_to_4444_proc(const SkScaledBitmapSampler::Options& opts) {
    // Skip zeroes and unpremul make no difference
    if (opts.fDither) {
        return Sample_RGBx_D4444_D;
    }
    return Sample_RGBx_D4444;
}

static bool Sample_RGBA_D4444(void* SK_RESTRICT dstRow,
                              const uint8_t* SK_RESTRICT src,
                              int width, int deltaSrc, int, const SkPMColor[]) {
    SkPMColor16* SK_RESTRICT dst = (SkPMColor16*)dstRow;
    unsigned alphaMask = 0xFF;

    for (int x = 0; x < width; x++) {
        unsigned alpha = src[3];
        SkPMColor c = SkPreMultiplyARGB(alpha, src[0], src[1], src[2]);
        dst[x] = SkPixel32ToPixel4444(c);
        src += deltaSrc;
        alphaMask &= alpha;
    }
    return alphaMask != 0xFF;
}

static bool Sample_RGBA_D4444_SkipZ(void* SK_RESTRICT dstRow,
                                    const uint8_t* SK_RESTRICT src,
                                    int width, int deltaSrc, int,
                                    const SkPMColor[]) {
    SkPMColor16* SK_RESTRICT dst = (SkPMColor16*)dstRow;
    unsigned alphaMask = 0xFF;

    for (int x = 0; x < width; x++) {
        unsigned alpha = src[3];
        if (alpha != 0) {
            SkPMColor c = SkPreMultiplyARGB(alpha, src[0], src[1], src[2]);
            dst[x] = SkPixel32ToPixel4444(c);
        }
        src += deltaSrc;
        alphaMask &= alpha;
    }
    return alphaMask != 0xFF;
}


static bool Sample_RGBA_D4444_D(void* SK_RESTRICT dstRow,
                                const uint8_t* SK_RESTRICT src,
                                int width, int deltaSrc, int y,
                                const SkPMColor[]) {
    SkPMColor16* SK_RESTRICT dst = (SkPMColor16*)dstRow;
    unsigned alphaMask = 0xFF;
    DITHER_4444_SCAN(y);

    for (int x = 0; x < width; x++) {
        unsigned alpha = src[3];
        SkPMColor c = SkPreMultiplyARGB(alpha, src[0], src[1], src[2]);
        dst[x] = SkDitherARGB32To4444(c, DITHER_VALUE(x));
        src += deltaSrc;
        alphaMask &= alpha;
    }
    return alphaMask != 0xFF;
}

static bool Sample_RGBA_D4444_D_SkipZ(void* SK_RESTRICT dstRow,
                                      const uint8_t* SK_RESTRICT src,
                                      int width, int deltaSrc, int y,
                                      const SkPMColor[]) {
    SkPMColor16* SK_RESTRICT dst = (SkPMColor16*)dstRow;
    unsigned alphaMask = 0xFF;
    DITHER_4444_SCAN(y);

    for (int x = 0; x < width; x++) {
        unsigned alpha = src[3];
        if (alpha != 0) {
            SkPMColor c = SkPreMultiplyARGB(alpha, src[0], src[1], src[2]);
            dst[x] = SkDitherARGB32To4444(c, DITHER_VALUE(x));
        }
        src += deltaSrc;
        alphaMask &= alpha;
    }
    return alphaMask != 0xFF;
}

static SkScaledBitmapSampler::RowProc
get_RGBA_to_4444_proc(const SkScaledBitmapSampler::Options& opts) {
    if (!opts.fPremultiplyAlpha) {
        // Unpremultiplied is not supported for 4444
        return NULL;
    }
    if (opts.fSkipZeros) {
        if (opts.fDither) {
            return Sample_RGBA_D4444_D_SkipZ;
        }
        return Sample_RGBA_D4444_SkipZ;
    }
    if (opts.fDither) {
        return Sample_RGBA_D4444_D;
    }
    return Sample_RGBA_D4444;
}

// Index

#define A32_MASK_IN_PLACE   (SkPMColor)(SK_A32_MASK << SK_A32_SHIFT)

static bool Sample_Index_D8888(void* SK_RESTRICT dstRow,
                               const uint8_t* SK_RESTRICT src,
                       int width, int deltaSrc, int, const SkPMColor ctable[]) {

    SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
    SkPMColor cc = A32_MASK_IN_PLACE;
    for (int x = 0; x < width; x++) {
        SkPMColor c = ctable[*src];
        cc &= c;
        dst[x] = c;
        src += deltaSrc;
    }
    return cc != A32_MASK_IN_PLACE;
}

static bool Sample_Index_D8888_SkipZ(void* SK_RESTRICT dstRow,
                                     const uint8_t* SK_RESTRICT src,
                                     int width, int deltaSrc, int,
                                     const SkPMColor ctable[]) {

    SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
    SkPMColor cc = A32_MASK_IN_PLACE;
    for (int x = 0; x < width; x++) {
        SkPMColor c = ctable[*src];
        cc &= c;
        if (c != 0) {
            dst[x] = c;
        }
        src += deltaSrc;
    }
    return cc != A32_MASK_IN_PLACE;
}

static SkScaledBitmapSampler::RowProc
get_index_to_8888_proc(const SkScaledBitmapSampler::Options& opts) {
    if (!opts.fPremultiplyAlpha) {
        // Unpremultiplied is not supported for an index source.
        return NULL;
    }
    // Dither makes no difference
    if (opts.fSkipZeros) {
        return Sample_Index_D8888_SkipZ;
    }
    return Sample_Index_D8888;
}

static bool Sample_Index_D565(void* SK_RESTRICT dstRow,
                               const uint8_t* SK_RESTRICT src,
                       int width, int deltaSrc, int, const SkPMColor ctable[]) {

    uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow;
    for (int x = 0; x < width; x++) {
        dst[x] = SkPixel32ToPixel16(ctable[*src]);
        src += deltaSrc;
    }
    return false;
}

static bool Sample_Index_D565_D(void* SK_RESTRICT dstRow,
                                const uint8_t* SK_RESTRICT src, int width,
                                int deltaSrc, int y, const SkPMColor ctable[]) {

    uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow;
    DITHER_565_SCAN(y);

    for (int x = 0; x < width; x++) {
        SkPMColor c = ctable[*src];
        dst[x] = SkDitherRGBTo565(SkGetPackedR32(c), SkGetPackedG32(c),
                                  SkGetPackedB32(c), DITHER_VALUE(x));
        src += deltaSrc;
    }
    return false;
}

static SkScaledBitmapSampler::RowProc
get_index_to_565_proc(const SkScaledBitmapSampler::Options& opts) {
    // Unpremultiplied and skip zeroes make no difference
    if (opts.fDither) {
        return Sample_Index_D565_D;
    }
    return Sample_Index_D565;
}

static bool Sample_Index_D4444(void* SK_RESTRICT dstRow,
                               const uint8_t* SK_RESTRICT src, int width,
                               int deltaSrc, int y, const SkPMColor ctable[]) {

    SkPMColor16* SK_RESTRICT dst = (SkPMColor16*)dstRow;
    SkPMColor cc = A32_MASK_IN_PLACE;
    for (int x = 0; x < width; x++) {
        SkPMColor c = ctable[*src];
        cc &= c;
        dst[x] = SkPixel32ToPixel4444(c);
        src += deltaSrc;
    }
    return cc != A32_MASK_IN_PLACE;
}

static bool Sample_Index_D4444_D(void* SK_RESTRICT dstRow,
                                 const uint8_t* SK_RESTRICT src, int width,
                                int deltaSrc, int y, const SkPMColor ctable[]) {

    SkPMColor16* SK_RESTRICT dst = (SkPMColor16*)dstRow;
    SkPMColor cc = A32_MASK_IN_PLACE;
    DITHER_4444_SCAN(y);

    for (int x = 0; x < width; x++) {
        SkPMColor c = ctable[*src];
        cc &= c;
        dst[x] = SkDitherARGB32To4444(c, DITHER_VALUE(x));
        src += deltaSrc;
    }
    return cc != A32_MASK_IN_PLACE;
}

static bool Sample_Index_D4444_SkipZ(void* SK_RESTRICT dstRow,
                                     const uint8_t* SK_RESTRICT src, int width,
                                     int deltaSrc, int y, const SkPMColor ctable[]) {

    SkPMColor16* SK_RESTRICT dst = (SkPMColor16*)dstRow;
    SkPMColor cc = A32_MASK_IN_PLACE;
    for (int x = 0; x < width; x++) {
        SkPMColor c = ctable[*src];
        cc &= c;
        if (c != 0) {
            dst[x] = SkPixel32ToPixel4444(c);
        }
        src += deltaSrc;
    }
    return cc != A32_MASK_IN_PLACE;
}

static bool Sample_Index_D4444_D_SkipZ(void* SK_RESTRICT dstRow,
                                       const uint8_t* SK_RESTRICT src, int width,
                                       int deltaSrc, int y, const SkPMColor ctable[]) {

    SkPMColor16* SK_RESTRICT dst = (SkPMColor16*)dstRow;
    SkPMColor cc = A32_MASK_IN_PLACE;
    DITHER_4444_SCAN(y);

    for (int x = 0; x < width; x++) {
        SkPMColor c = ctable[*src];
        cc &= c;
        if (c != 0) {
            dst[x] = SkDitherARGB32To4444(c, DITHER_VALUE(x));
        }
        src += deltaSrc;
    }
    return cc != A32_MASK_IN_PLACE;
}

static SkScaledBitmapSampler::RowProc
get_index_to_4444_proc(const SkScaledBitmapSampler::Options& opts) {
    // Unpremul not allowed
    if (!opts.fPremultiplyAlpha) {
        return NULL;
    }
    if (opts.fSkipZeros) {
        if (opts.fDither) {
            return Sample_Index_D4444_D_SkipZ;
        }
        return Sample_Index_D4444_SkipZ;
    }
    if (opts.fDither) {
        return Sample_Index_D4444_D;
    }
    return Sample_Index_D4444;
}

static bool Sample_Index_DI(void* SK_RESTRICT dstRow,
                            const uint8_t* SK_RESTRICT src,
                            int width, int deltaSrc, int, const SkPMColor[]) {
    if (1 == deltaSrc) {
        memcpy(dstRow, src, width);
    } else {
        uint8_t* SK_RESTRICT dst = (uint8_t*)dstRow;
        for (int x = 0; x < width; x++) {
            dst[x] = src[0];
            src += deltaSrc;
        }
    }
    return false;
}

static SkScaledBitmapSampler::RowProc
get_index_to_index_proc(const SkScaledBitmapSampler::Options& opts) {
    // Unpremul not allowed
    if (!opts.fPremultiplyAlpha) {
        return NULL;
    }
    // Ignore dither and skip zeroes
    return Sample_Index_DI;
}

// A8
static bool Sample_Gray_DA8(void* SK_RESTRICT dstRow,
                            const uint8_t* SK_RESTRICT src,
                            int width, int deltaSrc, int,
                            const SkPMColor[]) {
    // Sampling Gray to A8 uses the same function as Index to Index8,
    // except we assume that there is alpha for speed, since an A8
    // bitmap with no alpha is not interesting.
    (void) Sample_Index_DI(dstRow, src, width, deltaSrc, /* y unused */ 0,
                           /* ctable unused */ NULL);
    return true;
}

static SkScaledBitmapSampler::RowProc
get_gray_to_A8_proc(const SkScaledBitmapSampler::Options& opts) {
    if (!opts.fPremultiplyAlpha) {
        return NULL;
    }
    // Ignore skip and dither.
    return Sample_Gray_DA8;
}

typedef SkScaledBitmapSampler::RowProc (*RowProcChooser)(const SkScaledBitmapSampler::Options&);
///////////////////////////////////////////////////////////////////////////////

#include "SkScaledBitmapSampler.h"

SkScaledBitmapSampler::SkScaledBitmapSampler(int width, int height,
                                             int sampleSize) {
    fCTable = NULL;
    fDstRow = NULL;
    fRowProc = NULL;

    if (width <= 0 || height <= 0) {
        sk_throw();
    }

    SkDEBUGCODE(fSampleMode = kUninitialized_SampleMode);

    if (sampleSize <= 1) {
        fScaledWidth = width;
        fScaledHeight = height;
        fX0 = fY0 = 0;
        fDX = fDY = 1;
        return;
    }

    int dx = SkMin32(sampleSize, width);
    int dy = SkMin32(sampleSize, height);

    fScaledWidth = width / dx;
    fScaledHeight = height / dy;

    SkASSERT(fScaledWidth > 0);
    SkASSERT(fScaledHeight > 0);

    fX0 = dx >> 1;
    fY0 = dy >> 1;

    SkASSERT(fX0 >= 0 && fX0 < width);
    SkASSERT(fY0 >= 0 && fY0 < height);

    fDX = dx;
    fDY = dy;

    SkASSERT(fDX > 0 && (fX0 + fDX * (fScaledWidth - 1)) < width);
    SkASSERT(fDY > 0 && (fY0 + fDY * (fScaledHeight - 1)) < height);
}

bool SkScaledBitmapSampler::begin(SkBitmap* dst, SrcConfig sc,
                                  const Options& opts,
                                  const SkPMColor ctable[]) {
    static const RowProcChooser gProcChoosers[] = {
        get_gray_to_8888_proc,
        get_RGBx_to_8888_proc,
        get_RGBA_to_8888_proc,
        get_index_to_8888_proc,
        NULL, // 565 to 8888

        get_gray_to_565_proc,
        get_RGBx_to_565_proc,
        get_RGBx_to_565_proc, // The source alpha will be ignored.
        get_index_to_565_proc,
        get_565_to_565_proc,

        get_gray_to_4444_proc,
        get_RGBx_to_4444_proc,
        get_RGBA_to_4444_proc,
        get_index_to_4444_proc,
        NULL, // 565 to 4444

        NULL, // gray to index
        NULL, // rgbx to index
        NULL, // rgba to index
        get_index_to_index_proc,
        NULL, // 565 to index

        get_gray_to_A8_proc,
        NULL, // rgbx to a8
        NULL, // rgba to a8
        NULL, // index to a8
        NULL, // 565 to a8
    };

    // The jump between dst configs in the table
    static const int gProcDstConfigSpan = 5;
    SK_COMPILE_ASSERT(SK_ARRAY_COUNT(gProcChoosers) == 5 * gProcDstConfigSpan,
                      gProcs_has_the_wrong_number_of_entries);

    fCTable = ctable;

    int index = 0;
    switch (sc) {
        case SkScaledBitmapSampler::kGray:
            fSrcPixelSize = 1;
            index += 0;
            break;
        case SkScaledBitmapSampler::kRGB:
            fSrcPixelSize = 3;
            index += 1;
            break;
        case SkScaledBitmapSampler::kRGBX:
            fSrcPixelSize = 4;
            index += 1;
            break;
        case SkScaledBitmapSampler::kRGBA:
            fSrcPixelSize = 4;
            index += 2;
            break;
        case SkScaledBitmapSampler::kIndex:
            fSrcPixelSize = 1;
            index += 3;
            break;
        case SkScaledBitmapSampler::kRGB_565:
            fSrcPixelSize = 2;
            index += 4;
            break;
        default:
            return false;
    }

    switch (dst->colorType()) {
        case kN32_SkColorType:
            index += 0 * gProcDstConfigSpan;
            break;
        case kRGB_565_SkColorType:
            index += 1 * gProcDstConfigSpan;
            break;
        case kARGB_4444_SkColorType:
            index += 2 * gProcDstConfigSpan;
            break;
        case kIndex_8_SkColorType:
            index += 3 * gProcDstConfigSpan;
            break;
        case kAlpha_8_SkColorType:
            index += 4 * gProcDstConfigSpan;
            break;
        default:
            return false;
    }

    RowProcChooser chooser = gProcChoosers[index];
    if (NULL == chooser) {
        fRowProc = NULL;
    } else {
        fRowProc = chooser(opts);
    }
    fDstRow = (char*)dst->getPixels();
    fDstRowBytes = dst->rowBytes();
    fCurrY = 0;
    return fRowProc != NULL;
}

bool SkScaledBitmapSampler::begin(SkBitmap* dst, SrcConfig sc,
                                  const SkImageDecoder& decoder,
                                  const SkPMColor ctable[]) {
    return this->begin(dst, sc, Options(decoder), ctable);
}

bool SkScaledBitmapSampler::next(const uint8_t* SK_RESTRICT src) {
    SkASSERT(kInterlaced_SampleMode != fSampleMode);
    SkDEBUGCODE(fSampleMode = kConsecutive_SampleMode);
    SkASSERT((unsigned)fCurrY < (unsigned)fScaledHeight);

    bool hadAlpha = fRowProc(fDstRow, src + fX0 * fSrcPixelSize, fScaledWidth,
                             fDX * fSrcPixelSize, fCurrY, fCTable);
    fDstRow += fDstRowBytes;
    fCurrY += 1;
    return hadAlpha;
}

bool SkScaledBitmapSampler::sampleInterlaced(const uint8_t* SK_RESTRICT src, int srcY) {
    SkASSERT(kConsecutive_SampleMode != fSampleMode);
    SkDEBUGCODE(fSampleMode = kInterlaced_SampleMode);
    // Any line that should be a part of the destination can be created by the formula:
    // fY0 + (some multiplier) * fDY
    // so if srcY - fY0 is not an integer multiple of fDY that srcY will be skipped.
    const int srcYMinusY0 = srcY - fY0;
    if (srcYMinusY0 % fDY != 0) {
        // This line is not part of the output, so return false for alpha, since we have
        // not added an alpha to the output.
        return false;
    }
    // Unlike in next(), where the data is used sequentially, this function skips around,
    // so fDstRow and fCurrY are never updated. fDstRow must always be the starting point
    // of the destination bitmap's pixels, which is used to calculate the destination row
    // each time this function is called.
    const int dstY = srcYMinusY0 / fDY;
    if (dstY >= fScaledHeight) {
        return false;
    }
    char* dstRow = fDstRow + dstY * fDstRowBytes;
    return fRowProc(dstRow, src + fX0 * fSrcPixelSize, fScaledWidth,
                    fDX * fSrcPixelSize, dstY, fCTable);
}

#ifdef SK_DEBUG
// The following code is for a test to ensure that changing the method to get the right row proc
// did not change the row proc unintentionally. Tested by ImageDecodingTest.cpp

// friend of SkScaledBitmapSampler solely for the purpose of accessing fRowProc.
class RowProcTester {
public:
    static SkScaledBitmapSampler::RowProc getRowProc(const SkScaledBitmapSampler& sampler) {
        return sampler.fRowProc;
    }
};


// Table showing the expected RowProc for each combination of inputs.
// Table formated as follows:
// Each group of 5 consecutive rows represents sampling from a single
// SkScaledBitmapSampler::SrcConfig.
// Within each set, each row represents a different destination SkBitmap::Config
// Each column represents a different combination of dither and unpremul.
// D = dither   ~D = no dither
// U = unpremul ~U = no unpremul
//  ~D~U                D~U                     ~DU                         DU
SkScaledBitmapSampler::RowProc gTestProcs[] = {
    // Gray
    Sample_Gray_DA8,    Sample_Gray_DA8,        NULL,                       NULL,                       // to A8
    NULL,               NULL,                   NULL,                       NULL,                       // to Index8
    Sample_Gray_D565,   Sample_Gray_D565_D,     Sample_Gray_D565,           Sample_Gray_D565_D,         // to 565
    Sample_Gray_D4444,  Sample_Gray_D4444_D,    Sample_Gray_D4444,          Sample_Gray_D4444_D,        // to 4444
    Sample_Gray_D8888,  Sample_Gray_D8888,      Sample_Gray_D8888,          Sample_Gray_D8888,          // to 8888
    // Index
    NULL,               NULL,                   NULL,                       NULL,                       // to A8
    Sample_Index_DI,    Sample_Index_DI,        NULL,                       NULL,                       // to Index8
    Sample_Index_D565,  Sample_Index_D565_D,    Sample_Index_D565,          Sample_Index_D565_D,        // to 565
    Sample_Index_D4444, Sample_Index_D4444_D,   NULL,                       NULL,                       // to 4444
    Sample_Index_D8888, Sample_Index_D8888,     NULL,                       NULL,                       // to 8888
    // RGB
    NULL,               NULL,                   NULL,                       NULL,                       // to A8
    NULL,               NULL,                   NULL,                       NULL,                       // to Index8
    Sample_RGBx_D565,   Sample_RGBx_D565_D,     Sample_RGBx_D565,           Sample_RGBx_D565_D,         // to 565
    Sample_RGBx_D4444,  Sample_RGBx_D4444_D,    Sample_RGBx_D4444,          Sample_RGBx_D4444_D,        // to 4444
    Sample_RGBx_D8888,  Sample_RGBx_D8888,      Sample_RGBx_D8888,          Sample_RGBx_D8888,          // to 8888
    // RGBx is the same as RGB
    NULL,               NULL,                   NULL,                       NULL,                       // to A8
    NULL,               NULL,                   NULL,                       NULL,                       // to Index8
    Sample_RGBx_D565,   Sample_RGBx_D565_D,     Sample_RGBx_D565,           Sample_RGBx_D565_D,         // to 565
    Sample_RGBx_D4444,  Sample_RGBx_D4444_D,    Sample_RGBx_D4444,          Sample_RGBx_D4444_D,        // to 4444
    Sample_RGBx_D8888,  Sample_RGBx_D8888,      Sample_RGBx_D8888,          Sample_RGBx_D8888,          // to 8888
    // RGBA
    NULL,               NULL,                   NULL,                       NULL,                       // to A8
    NULL,               NULL,                   NULL,                       NULL,                       // to Index8
    Sample_RGBx_D565,   Sample_RGBx_D565_D,     Sample_RGBx_D565,           Sample_RGBx_D565_D,         // to 565
    Sample_RGBA_D4444,  Sample_RGBA_D4444_D,    NULL,                       NULL,                       // to 4444
    Sample_RGBA_D8888,  Sample_RGBA_D8888,      Sample_RGBA_D8888_Unpremul, Sample_RGBA_D8888_Unpremul, // to 8888
    // RGB_565
    NULL,               NULL,                   NULL,                       NULL,                       // to A8
    NULL,               NULL,                   NULL,                       NULL,                       // to Index8
    Sample_D565_D565,   Sample_D565_D565,       Sample_D565_D565,           Sample_D565_D565,           // to 565
    NULL,               NULL,                   NULL,                       NULL,                       // to 4444
    NULL,               NULL,                   NULL,                       NULL,                       // to 8888
};

// Dummy class that allows instantiation of an ImageDecoder, so begin can query its fields.
class DummyDecoder : public SkImageDecoder {
public:
    DummyDecoder() {}
protected:
    virtual bool onDecode(SkStream*, SkBitmap*, SkImageDecoder::Mode) SK_OVERRIDE {
        return false;
    }
};

void test_row_proc_choice();
void test_row_proc_choice() {
    const SkColorType colorTypes[] = {
        kAlpha_8_SkColorType, kIndex_8_SkColorType, kRGB_565_SkColorType, kARGB_4444_SkColorType,
        kN32_SkColorType
    };

    SkBitmap dummyBitmap;
    DummyDecoder dummyDecoder;
    size_t procCounter = 0;
    for (int sc = SkScaledBitmapSampler::kGray; sc <= SkScaledBitmapSampler::kRGB_565; ++sc) {
        for (size_t c = 0; c < SK_ARRAY_COUNT(colorTypes); ++c) {
            for (int unpremul = 0; unpremul <= 1; ++unpremul) {
                for (int dither = 0; dither <= 1; ++dither) {
                    // Arbitrary width/height/sampleSize to allow SkScaledBitmapSampler to
                    // be considered valid.
                    SkScaledBitmapSampler sampler(10, 10, 1);
                    dummyBitmap.setInfo(SkImageInfo::Make(10, 10,
                                                          colorTypes[c], kPremul_SkAlphaType));
                    dummyDecoder.setDitherImage(SkToBool(dither));
                    dummyDecoder.setRequireUnpremultipliedColors(SkToBool(unpremul));
                    sampler.begin(&dummyBitmap, (SkScaledBitmapSampler::SrcConfig) sc,
                                  dummyDecoder);
                    SkScaledBitmapSampler::RowProc expected = gTestProcs[procCounter];
                    SkScaledBitmapSampler::RowProc actual = RowProcTester::getRowProc(sampler);
                    SkASSERT(expected == actual);
                    procCounter++;
                }
            }
        }
    }
    SkASSERT(SK_ARRAY_COUNT(gTestProcs) == procCounter);
}
#endif // SK_DEBUG
