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 |