| Index: src/images/SkScaledBitmapSampler.cpp
|
| diff --git a/src/images/SkScaledBitmapSampler.cpp b/src/images/SkScaledBitmapSampler.cpp
|
| index 021f86ba868c14204af1c9d0ce27017f30943244..3bab8de9fd918079579c68d39da70d4f5998884f 100644
|
| --- a/src/images/SkScaledBitmapSampler.cpp
|
| +++ b/src/images/SkScaledBitmapSampler.cpp
|
| @@ -25,6 +25,11 @@ static bool Sample_Gray_D8888(void* SK_RESTRICT dstRow,
|
| return false;
|
| }
|
|
|
| +static SkScaledBitmapSampler::RowProc get_gray_to_8888_proc(const SkImageDecoder& decoder) {
|
| + // 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[]) {
|
| @@ -36,6 +41,11 @@ static bool Sample_RGBx_D8888(void* SK_RESTRICT dstRow,
|
| return false;
|
| }
|
|
|
| +static SkScaledBitmapSampler::RowProc get_RGBx_to_8888_proc(const SkImageDecoder& decoder) {
|
| + // 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[]) {
|
| @@ -50,6 +60,52 @@ static bool Sample_RGBA_D8888(void* SK_RESTRICT dstRow,
|
| 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 SkImageDecoder& decoder) {
|
| + // Dither has no effect.
|
| + if (decoder.getRequireUnpremultipliedColors()) {
|
| + // 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 (decoder.getSkipWritingZeroes()) {
|
| + return Sample_RGBA_D8888_SkipZ;
|
| + }
|
| + return Sample_RGBA_D8888;
|
| +}
|
| +
|
| // 565
|
|
|
| static bool Sample_Gray_D565(void* SK_RESTRICT dstRow,
|
| @@ -75,6 +131,14 @@ static bool Sample_Gray_D565_D(void* SK_RESTRICT dstRow,
|
| return false;
|
| }
|
|
|
| +static SkScaledBitmapSampler::RowProc get_gray_to_565_proc(const SkImageDecoder& decoder) {
|
| + // Unpremul and skip zeroes make no difference
|
| + if (decoder.getDitherImage()) {
|
| + 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[]) {
|
| @@ -86,6 +150,28 @@ static bool Sample_RGBx_D565(void* SK_RESTRICT dstRow,
|
| 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 SkImageDecoder& decoder) {
|
| + // Unpremul and skip zeroes make no difference
|
| + if (decoder.getDitherImage()) {
|
| + 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[]) {
|
| @@ -98,16 +184,9 @@ static bool Sample_D565_D565(void* SK_RESTRICT dstRow,
|
| 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_565_to_565_proc(const SkImageDecoder& decoder) {
|
| + // Unpremul, dither, and skip zeroes have no effect
|
| + return Sample_D565_D565;
|
| }
|
|
|
| // 4444
|
| @@ -137,6 +216,14 @@ static bool Sample_Gray_D4444_D(void* SK_RESTRICT dstRow,
|
| return false;
|
| }
|
|
|
| +static SkScaledBitmapSampler::RowProc get_gray_to_4444_proc(const SkImageDecoder& decoder) {
|
| + // Skip zeroes and unpremul make no difference
|
| + if (decoder.getDitherImage()) {
|
| + 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[]) {
|
| @@ -162,6 +249,14 @@ static bool Sample_RGBx_D4444_D(void* SK_RESTRICT dstRow,
|
| return false;
|
| }
|
|
|
| +static SkScaledBitmapSampler::RowProc get_RGBx_to_4444_proc(const SkImageDecoder& decoder) {
|
| + // Skip zeroes and unpremul make no difference
|
| + if (decoder.getDitherImage()) {
|
| + 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[]) {
|
| @@ -178,9 +273,30 @@ static bool Sample_RGBA_D4444(void* SK_RESTRICT dstRow,
|
| 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[]) {
|
| + int width, int deltaSrc, int y,
|
| + const SkPMColor[]) {
|
| SkPMColor16* SK_RESTRICT dst = (SkPMColor16*)dstRow;
|
| unsigned alphaMask = 0xFF;
|
| DITHER_4444_SCAN(y);
|
| @@ -195,6 +311,44 @@ static bool Sample_RGBA_D4444_D(void* SK_RESTRICT dstRow,
|
| 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 SkImageDecoder& decoder) {
|
| + if (decoder.getRequireUnpremultipliedColors()) {
|
| + // Unpremultiplied is not supported for 4444
|
| + return NULL;
|
| + }
|
| + const bool dither = decoder.getDitherImage();
|
| + if (decoder.getSkipWritingZeroes()) {
|
| + if (dither) {
|
| + return Sample_RGBA_D4444_D_SkipZ;
|
| + }
|
| + return Sample_RGBA_D4444_SkipZ;
|
| + }
|
| + if (dither) {
|
| + return Sample_RGBA_D4444_D;
|
| + }
|
| + return Sample_RGBA_D4444;
|
| +}
|
| +
|
| // Index
|
|
|
| #define A32_MASK_IN_PLACE (SkPMColor)(SK_A32_MASK << SK_A32_SHIFT)
|
| @@ -214,6 +368,36 @@ static bool Sample_Index_D8888(void* SK_RESTRICT dstRow,
|
| 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 SkImageDecoder& decoder) {
|
| + if (decoder.getRequireUnpremultipliedColors()) {
|
| + // Unpremultiplied is not supported for an index source.
|
| + return NULL;
|
| + }
|
| + // Dither makes no difference
|
| + if (decoder.getSkipWritingZeroes()) {
|
| + 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[]) {
|
| @@ -242,6 +426,14 @@ static bool Sample_Index_D565_D(void* SK_RESTRICT dstRow,
|
| return false;
|
| }
|
|
|
| +static SkScaledBitmapSampler::RowProc get_index_to_565_proc(const SkImageDecoder& decoder) {
|
| + // Unpremultiplied and skip zeroes make no difference
|
| + if (decoder.getDitherImage()) {
|
| + 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[]) {
|
| @@ -274,6 +466,60 @@ static bool Sample_Index_D4444_D(void* SK_RESTRICT dstRow,
|
| 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 SkImageDecoder& decoder) {
|
| + // Unpremul not allowed
|
| + if (decoder.getRequireUnpremultipliedColors()) {
|
| + return NULL;
|
| + }
|
| + const bool dither = decoder.getDitherImage();
|
| + if (decoder.getSkipWritingZeroes()) {
|
| + if (dither) {
|
| + return Sample_Index_D4444_D_SkipZ;
|
| + }
|
| + return Sample_Index_D4444_SkipZ;
|
| + }
|
| + if (dither) {
|
| + 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[]) {
|
| @@ -289,6 +535,15 @@ static bool Sample_Index_DI(void* SK_RESTRICT dstRow,
|
| return false;
|
| }
|
|
|
| +static SkScaledBitmapSampler::RowProc get_index_to_index_proc(const SkImageDecoder& decoder) {
|
| + // Unpremul not allowed
|
| + if (decoder.getRequireUnpremultipliedColors()) {
|
| + 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,
|
| @@ -298,41 +553,15 @@ static bool Sample_Gray_DA8(void* SK_RESTRICT dstRow,
|
| return true;
|
| }
|
|
|
| -// 8888 Unpremul
|
| -
|
| -static bool Sample_Gray_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);
|
| - for (int x = 0; x < width; x++) {
|
| - dst[x] = SkPackARGB32NoCheck(0xFF, src[0], src[0], src[0]);
|
| - src += deltaSrc;
|
| - }
|
| - return false;
|
| -}
|
| -
|
| -// Sample_RGBx_D8888_Unpremul is no different from Sample_RGBx_D8888, since alpha
|
| -// is 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;
|
| +static SkScaledBitmapSampler::RowProc get_gray_to_A8_proc(const SkImageDecoder& decoder) {
|
| + if (decoder.getRequireUnpremultipliedColors()) {
|
| + return NULL;
|
| }
|
| - return alphaMask != 0xFF;
|
| + // Ignore skip and dither.
|
| + return Sample_Gray_DA8;
|
| }
|
|
|
| -// Sample_Index_D8888_Unpremul is the same as Sample_Index_D8888, since the
|
| -// color table has its colors inserted unpremultiplied.
|
| -
|
| +typedef SkScaledBitmapSampler::RowProc (*RowProcChooser)(const SkImageDecoder& decoder);
|
| ///////////////////////////////////////////////////////////////////////////////
|
|
|
| #include "SkScaledBitmapSampler.h"
|
| @@ -377,58 +606,49 @@ SkScaledBitmapSampler::SkScaledBitmapSampler(int width, int height,
|
| SkASSERT(fDY > 0 && (fY0 + fDY * (fScaledHeight - 1)) < height);
|
| }
|
|
|
| -bool SkScaledBitmapSampler::begin(SkBitmap* dst, SrcConfig sc, bool dither,
|
| - const SkPMColor ctable[],
|
| - bool requireUnpremul) {
|
| - static const RowProc gProcs[] = {
|
| - // 8888 (no dither distinction)
|
| - Sample_Gray_D8888, Sample_Gray_D8888,
|
| - Sample_RGBx_D8888, Sample_RGBx_D8888,
|
| - Sample_RGBA_D8888, Sample_RGBA_D8888,
|
| - Sample_Index_D8888, Sample_Index_D8888,
|
| - NULL, NULL,
|
| - // 565 (no alpha distinction)
|
| - Sample_Gray_D565, Sample_Gray_D565_D,
|
| - Sample_RGBx_D565, Sample_RGBx_D565_D,
|
| - Sample_RGBx_D565, Sample_RGBx_D565_D,
|
| - Sample_Index_D565, Sample_Index_D565_D,
|
| - Sample_D565_D565, Sample_D565_D565,
|
| - // 4444
|
| - Sample_Gray_D4444, Sample_Gray_D4444_D,
|
| - Sample_RGBx_D4444, Sample_RGBx_D4444_D,
|
| - Sample_RGBA_D4444, Sample_RGBA_D4444_D,
|
| - Sample_Index_D4444, Sample_Index_D4444_D,
|
| - NULL, NULL,
|
| - // Index8
|
| - NULL, NULL,
|
| - NULL, NULL,
|
| - NULL, NULL,
|
| - Sample_Index_DI, Sample_Index_DI,
|
| - NULL, NULL,
|
| - // A8
|
| - Sample_Gray_DA8, Sample_Gray_DA8,
|
| - NULL, NULL,
|
| - NULL, NULL,
|
| - NULL, NULL,
|
| - NULL, NULL,
|
| - // 8888 Unpremul (no dither distinction)
|
| - Sample_Gray_D8888_Unpremul, Sample_Gray_D8888_Unpremul,
|
| - Sample_RGBx_D8888, Sample_RGBx_D8888,
|
| - Sample_RGBA_D8888_Unpremul, Sample_RGBA_D8888_Unpremul,
|
| - Sample_Index_D8888, Sample_Index_D8888,
|
| - NULL, NULL,
|
| +bool SkScaledBitmapSampler::begin(SkBitmap* dst, SrcConfig sc,
|
| + const SkImageDecoder& decoder,
|
| + 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 = 10;
|
| - SK_COMPILE_ASSERT(SK_ARRAY_COUNT(gProcs) == 6 * gProcDstConfigSpan,
|
| + 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;
|
| - if (dither) {
|
| - index += 1;
|
| - }
|
| switch (sc) {
|
| case SkScaledBitmapSampler::kGray:
|
| fSrcPixelSize = 1;
|
| @@ -436,23 +656,23 @@ bool SkScaledBitmapSampler::begin(SkBitmap* dst, SrcConfig sc, bool dither,
|
| break;
|
| case SkScaledBitmapSampler::kRGB:
|
| fSrcPixelSize = 3;
|
| - index += 2;
|
| + index += 1;
|
| break;
|
| case SkScaledBitmapSampler::kRGBX:
|
| fSrcPixelSize = 4;
|
| - index += 2;
|
| + index += 1;
|
| break;
|
| case SkScaledBitmapSampler::kRGBA:
|
| fSrcPixelSize = 4;
|
| - index += 4;
|
| + index += 2;
|
| break;
|
| case SkScaledBitmapSampler::kIndex:
|
| fSrcPixelSize = 1;
|
| - index += 6;
|
| + index += 3;
|
| break;
|
| case SkScaledBitmapSampler::kRGB_565:
|
| fSrcPixelSize = 2;
|
| - index += 8;
|
| + index += 4;
|
| break;
|
| default:
|
| return false;
|
| @@ -478,14 +698,12 @@ bool SkScaledBitmapSampler::begin(SkBitmap* dst, SrcConfig sc, bool dither,
|
| return false;
|
| }
|
|
|
| - if (requireUnpremul) {
|
| - if (dst->config() != SkBitmap::kARGB_8888_Config) {
|
| - return false;
|
| - }
|
| - index += 5 * gProcDstConfigSpan;
|
| + RowProcChooser chooser = gProcChoosers[index];
|
| + if (NULL == chooser) {
|
| + fRowProc = NULL;
|
| + } else {
|
| + fRowProc = chooser(decoder);
|
| }
|
| -
|
| - fRowProc = gProcs[index];
|
| fDstRow = (char*)dst->getPixels();
|
| fDstRowBytes = dst->rowBytes();
|
| fCurrY = 0;
|
| @@ -501,3 +719,102 @@ bool SkScaledBitmapSampler::next(const uint8_t* SK_RESTRICT src) {
|
| fCurrY += 1;
|
| return hadAlpha;
|
| }
|
| +
|
| +#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() {
|
| + SkBitmap dummyBitmap;
|
| + DummyDecoder dummyDecoder;
|
| + size_t procCounter = 0;
|
| + for (int sc = SkScaledBitmapSampler::kGray; sc <= SkScaledBitmapSampler::kRGB_565; ++sc) {
|
| + for (int c = SkBitmap::kA8_Config; c <= SkBitmap::kARGB_8888_Config; ++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.setConfig((SkBitmap::Config) c, 10, 10);
|
| + 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
|
|
|