Index: src/codec/SkSwizzler.cpp |
diff --git a/src/codec/SkSwizzler.cpp b/src/codec/SkSwizzler.cpp |
index b2b7f927ac262913d86fcfd6c89af7cf430723cb..44277614c650a075cdcb298e8fdfba8021ae660e 100644 |
--- a/src/codec/SkSwizzler.cpp |
+++ b/src/codec/SkSwizzler.cpp |
@@ -7,6 +7,7 @@ |
#include "SkCodecPriv.h" |
#include "SkColorPriv.h" |
+#include "SkScaledCodec.h" |
#include "SkSwizzler.h" |
#include "SkTemplates.h" |
#include "SkUtils.h" |
@@ -19,114 +20,116 @@ SkSwizzler::ResultAlpha SkSwizzler::GetResult(uint8_t zeroAlpha, |
return (((uint16_t) maxAlpha) << 8) | zeroAlpha; |
} |
+// samples the row. Does not do anything else but sampling |
+static SkSwizzler::ResultAlpha sample565(void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, |
+ int width, int deltaSrc, int offset, const SkPMColor ctable[]){ |
+ |
+ src += offset; |
+ uint16_t* SK_RESTRICT dst = (uint16_t*) dstRow; |
+ for (int x = 0; x < width; x++) { |
+ dst[x] = src[1] << 8 | src[0]; |
+ src += deltaSrc; |
+ } |
+ // 565 is always opaque |
+ return SkSwizzler::kOpaque_ResultAlpha; |
+} |
+ |
// kBit |
// These routines exclusively choose between white and black |
#define GRAYSCALE_BLACK 0 |
#define GRAYSCALE_WHITE 0xFF |
+ |
+// same as swizzle_bit_to_index and swizzle_bit_to_n32 except for value assigned to dst[x] |
static SkSwizzler::ResultAlpha swizzle_bit_to_grayscale( |
- void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width, |
- int /*bitsPerPixel*/, const SkPMColor* /*ctable*/) { |
+ void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth, |
+ int deltaSrc, int offset, const SkPMColor* /*ctable*/) { |
+ |
uint8_t* SK_RESTRICT dst = (uint8_t*) dstRow; |
- // Determine how many full bytes are in the row |
- int bytesInRow = width >> 3; |
- int i; |
- for (i = 0; i < bytesInRow; i++) { |
- U8CPU currByte = src[i]; |
- for (int j = 0; j < 8; j++) { |
- dst[j] = ((currByte >> (7 - j)) & 1) ? GRAYSCALE_WHITE : GRAYSCALE_BLACK; |
- } |
- dst += 8; |
- } |
+ // increment src by byte offset and bitIndex by bit offset |
+ src += offset / 8; |
+ int bitIndex = offset % 8; |
+ uint8_t currByte = *src; |
- // Finish the remaining bits |
- width &= 7; |
- if (width > 0) { |
- U8CPU currByte = src[i]; |
- for (int j = 0; j < width; j++) { |
- dst[j] = ((currByte >> 7) & 1) ? GRAYSCALE_WHITE : GRAYSCALE_BLACK; |
- currByte <<= 1; |
- } |
+ dst[0] = ((currByte >> (7-bitIndex)) & 1) ? GRAYSCALE_WHITE : GRAYSCALE_BLACK; |
+ |
+ for (int x = 1; x < dstWidth; x++) { |
+ int bitOffset = bitIndex + deltaSrc; |
+ bitIndex = bitOffset % 8; |
+ currByte = *(src += bitOffset / 8); |
+ dst[x] = ((currByte >> (7-bitIndex)) & 1) ? GRAYSCALE_WHITE : GRAYSCALE_BLACK; |
} |
+ |
return SkSwizzler::kOpaque_ResultAlpha; |
} |
#undef GRAYSCALE_BLACK |
#undef GRAYSCALE_WHITE |
+// same as swizzle_bit_to_grayscale and swizzle_bit_to_n32 except for value assigned to dst[x] |
static SkSwizzler::ResultAlpha swizzle_bit_to_index( |
- void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width, |
- int /*bitsPerPixel*/, const SkPMColor* /*ctable*/) { |
+ void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth, |
+ int deltaSrc, int offset, const SkPMColor* /*ctable*/) { |
uint8_t* SK_RESTRICT dst = (uint8_t*) dstRow; |
- // Determine how many full bytes are in the row |
- int bytesInRow = width >> 3; |
- int i; |
- for (i = 0; i < bytesInRow; i++) { |
- U8CPU currByte = src[i]; |
- for (int j = 0; j < 8; j++) { |
- dst[j] = (currByte >> (7 - j)) & 1; |
- } |
- dst += 8; |
- } |
+ // increment src by byte offset and bitIndex by bit offset |
+ src += offset / 8; |
+ int bitIndex = offset % 8; |
+ uint8_t currByte = *src; |
- // Finish the remaining bits |
- width &= 7; |
- if (width > 0) { |
- U8CPU currByte = src[i]; |
- for (int j = 0; j < width; j++) { |
- dst[j] = ((currByte >> 7) & 1); |
- currByte <<= 1; |
- } |
+ dst[0] = ((currByte >> (7-bitIndex)) & 1); |
+ |
+ for (int x = 1; x < dstWidth; x++) { |
+ int bitOffset = bitIndex + deltaSrc; |
+ bitIndex = bitOffset % 8; |
+ currByte = *(src += bitOffset / 8); |
+ dst[x] = ((currByte >> (7-bitIndex)) & 1); |
} |
+ |
return SkSwizzler::kOpaque_ResultAlpha; |
} |
+// same as swizzle_bit_to_grayscale and swizzle_bit_to_index except for value assigned to dst[x] |
static SkSwizzler::ResultAlpha swizzle_bit_to_n32( |
- void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width, |
- int /*bitsPerPixel*/, const SkPMColor* /*ctable*/) { |
+ void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth, |
+ int deltaSrc, int offset, const SkPMColor* /*ctable*/) { |
SkPMColor* SK_RESTRICT dst = (SkPMColor*) dstRow; |
- // Determine how many full bytes are in the row |
- int bytesInRow = width >> 3; |
- int i; |
- for (i = 0; i < bytesInRow; i++) { |
- U8CPU currByte = src[i]; |
- for (int j = 0; j < 8; j++) { |
- dst[j] = ((currByte >> (7 - j)) & 1) ? SK_ColorWHITE : SK_ColorBLACK; |
- } |
- dst += 8; |
- } |
+ // increment src by byte offset and bitIndex by bit offset |
+ src += offset / 8; |
+ int bitIndex = offset % 8; |
+ uint8_t currByte = *src; |
- // Finish the remaining bits |
- width &= 7; |
- if (width > 0) { |
- U8CPU currByte = src[i]; |
- for (int j = 0; j < width; j++) { |
- dst[j] = ((currByte >> 7) & 1) ? SK_ColorWHITE : SK_ColorBLACK; |
- currByte <<= 1; |
- } |
+ dst[0] = ((currByte >> (7 - bitIndex)) & 1) ? SK_ColorWHITE : SK_ColorBLACK; |
+ |
+ for (int x = 1; x < dstWidth; x++) { |
+ int bitOffset = bitIndex + deltaSrc; |
+ bitIndex = bitOffset % 8; |
+ currByte = *(src += bitOffset / 8); |
+ dst[x] = ((currByte >> (7 - bitIndex)) & 1) ? SK_ColorWHITE : SK_ColorBLACK; |
} |
+ |
return SkSwizzler::kOpaque_ResultAlpha; |
} |
// kIndex1, kIndex2, kIndex4 |
static SkSwizzler::ResultAlpha swizzle_small_index_to_index( |
- void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width, |
- int bitsPerPixel, const SkPMColor ctable[]) { |
+ void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth, |
+ int bitsPerPixel, int offset, const SkPMColor ctable[]) { |
+ src += offset; |
uint8_t* SK_RESTRICT dst = (uint8_t*) dstRow; |
INIT_RESULT_ALPHA; |
const uint32_t pixelsPerByte = 8 / bitsPerPixel; |
- const size_t rowBytes = compute_row_bytes_ppb(width, pixelsPerByte); |
+ const size_t rowBytes = compute_row_bytes_ppb(dstWidth, pixelsPerByte); |
const uint8_t mask = (1 << bitsPerPixel) - 1; |
int x = 0; |
for (uint32_t byte = 0; byte < rowBytes; byte++) { |
uint8_t pixelData = src[byte]; |
- for (uint32_t p = 0; p < pixelsPerByte && x < width; p++) { |
+ for (uint32_t p = 0; p < pixelsPerByte && x < dstWidth; p++) { |
uint8_t index = (pixelData >> (8 - bitsPerPixel)) & mask; |
UPDATE_RESULT_ALPHA(ctable[index] >> SK_A32_SHIFT); |
dst[x] = index; |
@@ -138,18 +141,19 @@ static SkSwizzler::ResultAlpha swizzle_small_index_to_index( |
} |
static SkSwizzler::ResultAlpha swizzle_small_index_to_n32( |
- void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width, |
- int bitsPerPixel, const SkPMColor ctable[]) { |
+ void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth, |
+ int bitsPerPixel, int offset, const SkPMColor ctable[]) { |
+ src += offset; |
SkPMColor* SK_RESTRICT dst = (SkPMColor*) dstRow; |
INIT_RESULT_ALPHA; |
const uint32_t pixelsPerByte = 8 / bitsPerPixel; |
- const size_t rowBytes = compute_row_bytes_ppb(width, pixelsPerByte); |
+ const size_t rowBytes = compute_row_bytes_ppb(dstWidth, pixelsPerByte); |
const uint8_t mask = (1 << bitsPerPixel) - 1; |
int x = 0; |
for (uint32_t byte = 0; byte < rowBytes; byte++) { |
uint8_t pixelData = src[byte]; |
- for (uint32_t p = 0; p < pixelsPerByte && x < width; p++) { |
+ for (uint32_t p = 0; p < pixelsPerByte && x < dstWidth; p++) { |
uint8_t index = (pixelData >> (8 - bitsPerPixel)) & mask; |
SkPMColor c = ctable[index]; |
UPDATE_RESULT_ALPHA(c >> SK_A32_SHIFT); |
@@ -164,58 +168,75 @@ static SkSwizzler::ResultAlpha swizzle_small_index_to_n32( |
// kIndex |
static SkSwizzler::ResultAlpha swizzle_index_to_index( |
- void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width, |
- int bytesPerPixel, const SkPMColor ctable[]) { |
+ void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth, |
+ int deltaSrc, int offset, const SkPMColor ctable[]) { |
+ src += offset; |
uint8_t* SK_RESTRICT dst = (uint8_t*) dstRow; |
- memcpy(dst, src, width); |
+ INIT_RESULT_ALPHA; |
// TODO (msarett): Should we skip the loop here and guess that the row is opaque/not opaque? |
// SkScaledBitmap sampler just guesses that it is opaque. This is dangerous |
// and probably wrong since gif and bmp (rarely) may have alpha. |
- INIT_RESULT_ALPHA; |
- for (int x = 0; x < width; x++) { |
- UPDATE_RESULT_ALPHA(ctable[src[x]] >> SK_A32_SHIFT); |
+ if (1 == deltaSrc) { |
+ // A non-zero offset is only used when sampling, meaning that deltaSrc will be |
+ // greater than 1. The below loop relies on the fact that src remains unchanged. |
+ SkASSERT(0 == offset); |
+ memcpy(dst, src, dstWidth); |
+ for (int x = 0; x < dstWidth; x++) { |
+ UPDATE_RESULT_ALPHA(ctable[src[x]] >> SK_A32_SHIFT); |
+ } |
+ } else { |
+ for (int x = 0; x < dstWidth; x++) { |
+ dst[x] = *src; |
+ UPDATE_RESULT_ALPHA(ctable[*src] >> SK_A32_SHIFT); |
+ src += deltaSrc; |
+ } |
} |
return COMPUTE_RESULT_ALPHA; |
} |
static SkSwizzler::ResultAlpha swizzle_index_to_n32( |
- void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width, |
- int bytesPerPixel, const SkPMColor ctable[]) { |
+ void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth, |
+ int deltaSrc, int offset, const SkPMColor ctable[]) { |
+ src += offset; |
SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; |
INIT_RESULT_ALPHA; |
- for (int x = 0; x < width; x++) { |
- SkPMColor c = ctable[src[x]]; |
+ for (int x = 0; x < dstWidth; x++) { |
+ SkPMColor c = ctable[*src]; |
UPDATE_RESULT_ALPHA(c >> SK_A32_SHIFT); |
dst[x] = c; |
+ src += deltaSrc; |
} |
return COMPUTE_RESULT_ALPHA; |
} |
static SkSwizzler::ResultAlpha swizzle_index_to_n32_skipZ( |
- void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width, |
- int bytesPerPixel, const SkPMColor ctable[]) { |
+ void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth, |
+ int deltaSrc, int offset, const SkPMColor ctable[]) { |
+ src += offset; |
SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; |
INIT_RESULT_ALPHA; |
- for (int x = 0; x < width; x++) { |
- SkPMColor c = ctable[src[x]]; |
+ for (int x = 0; x < dstWidth; x++) { |
+ SkPMColor c = ctable[*src]; |
UPDATE_RESULT_ALPHA(c >> SK_A32_SHIFT); |
if (c != 0) { |
dst[x] = c; |
} |
+ src += deltaSrc; |
} |
return COMPUTE_RESULT_ALPHA; |
} |
static SkSwizzler::ResultAlpha swizzle_index_to_565( |
- void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width, |
- int bytesPerPixel, const SkPMColor ctable[]) { |
+ void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth, |
+ int bytesPerPixel, int offset, const SkPMColor ctable[]) { |
// FIXME: Support dithering? Requires knowing y, which I think is a bigger |
// change. |
+ src += offset; |
uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow; |
- for (int x = 0; x < width; x++) { |
+ for (int x = 0; x < dstWidth; x++) { |
dst[x] = SkPixel32ToPixel16(ctable[*src]); |
src += bytesPerPixel; |
} |
@@ -228,29 +249,42 @@ static SkSwizzler::ResultAlpha swizzle_index_to_565( |
// kGray |
static SkSwizzler::ResultAlpha swizzle_gray_to_n32( |
- void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width, |
- int bytesPerPixel, const SkPMColor ctable[]) { |
+ void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth, |
+ int deltaSrc, int offset, const SkPMColor ctable[]) { |
+ src += offset; |
SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; |
- for (int x = 0; x < width; x++) { |
- dst[x] = SkPackARGB32NoCheck(0xFF, src[x], src[x], src[x]); |
+ for (int x = 0; x < dstWidth; x++) { |
+ dst[x] = SkPackARGB32NoCheck(0xFF, *src, *src, *src); |
+ src += deltaSrc; |
} |
return SkSwizzler::kOpaque_ResultAlpha; |
} |
static SkSwizzler::ResultAlpha swizzle_gray_to_gray( |
- void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width, |
- int bytesPerPixel, const SkPMColor ctable[]) { |
- memcpy(dstRow, src, width); |
+ void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth, |
+ int deltaSrc, int offset, const SkPMColor ctable[]) { |
+ |
+ src += offset; |
+ uint8_t* SK_RESTRICT dst = (uint8_t*) dstRow; |
+ if (1 == deltaSrc) { |
+ memcpy(dstRow, src, dstWidth); |
+ } else { |
+ for (int x = 0; x < dstWidth; x++) { |
+ dst[x] = src[0]; |
+ src += deltaSrc; |
+ } |
+ } |
return SkSwizzler::kOpaque_ResultAlpha; |
} |
static SkSwizzler::ResultAlpha swizzle_gray_to_565( |
- void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width, |
- int bytesPerPixel, const SkPMColor ctable[]) { |
+ void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth, |
+ int bytesPerPixel, int offset, const SkPMColor ctable[]) { |
// FIXME: Support dithering? |
+ src += offset; |
uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow; |
- for (int x = 0; x < width; x++) { |
+ for (int x = 0; x < dstWidth; x++) { |
dst[x] = SkPack888ToRGB16(src[0], src[0], src[0]); |
src += bytesPerPixel; |
} |
@@ -260,13 +294,14 @@ static SkSwizzler::ResultAlpha swizzle_gray_to_565( |
// kBGRX |
static SkSwizzler::ResultAlpha swizzle_bgrx_to_n32( |
- void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width, |
- int bytesPerPixel, const SkPMColor ctable[]) { |
+ void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth, |
+ int deltaSrc, int offset, const SkPMColor ctable[]) { |
+ src += offset; |
SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; |
- for (int x = 0; x < width; x++) { |
+ for (int x = 0; x < dstWidth; x++) { |
dst[x] = SkPackARGB32NoCheck(0xFF, src[2], src[1], src[0]); |
- src += bytesPerPixel; |
+ src += deltaSrc; |
} |
return SkSwizzler::kOpaque_ResultAlpha; |
} |
@@ -274,54 +309,58 @@ static SkSwizzler::ResultAlpha swizzle_bgrx_to_n32( |
// kBGRA |
static SkSwizzler::ResultAlpha swizzle_bgra_to_n32_unpremul( |
- void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width, |
- int bytesPerPixel, const SkPMColor ctable[]) { |
+ void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth, |
+ int deltaSrc, int offset, const SkPMColor ctable[]) { |
+ src += offset; |
SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; |
INIT_RESULT_ALPHA; |
- for (int x = 0; x < width; x++) { |
+ for (int x = 0; x < dstWidth; x++) { |
uint8_t alpha = src[3]; |
UPDATE_RESULT_ALPHA(alpha); |
dst[x] = SkPackARGB32NoCheck(alpha, src[2], src[1], src[0]); |
- src += bytesPerPixel; |
+ src += deltaSrc; |
} |
return COMPUTE_RESULT_ALPHA; |
} |
static SkSwizzler::ResultAlpha swizzle_bgra_to_n32_premul( |
- void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width, |
- int bytesPerPixel, const SkPMColor ctable[]) { |
+ void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth, |
+ int deltaSrc, int offset, const SkPMColor ctable[]) { |
+ src += offset; |
SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; |
INIT_RESULT_ALPHA; |
- for (int x = 0; x < width; x++) { |
+ for (int x = 0; x < dstWidth; x++) { |
uint8_t alpha = src[3]; |
UPDATE_RESULT_ALPHA(alpha); |
dst[x] = SkPreMultiplyARGB(alpha, src[2], src[1], src[0]); |
- src += bytesPerPixel; |
+ src += deltaSrc; |
} |
return COMPUTE_RESULT_ALPHA; |
} |
// kRGBX |
static SkSwizzler::ResultAlpha swizzle_rgbx_to_n32( |
- void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width, |
- int bytesPerPixel, const SkPMColor ctable[]) { |
+ void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth, |
+ int deltaSrc, int offset, const SkPMColor ctable[]) { |
+ src += offset; |
SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; |
- for (int x = 0; x < width; x++) { |
+ for (int x = 0; x < dstWidth; x++) { |
dst[x] = SkPackARGB32(0xFF, src[0], src[1], src[2]); |
- src += bytesPerPixel; |
+ src += deltaSrc; |
} |
return SkSwizzler::kOpaque_ResultAlpha; |
} |
static SkSwizzler::ResultAlpha swizzle_rgbx_to_565( |
- void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width, |
- int bytesPerPixel, const SkPMColor ctable[]) { |
+ void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth, |
+ int bytesPerPixel, int offset, const SkPMColor ctable[]) { |
// FIXME: Support dithering? |
+ src += offset; |
uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow; |
- for (int x = 0; x < width; x++) { |
+ for (int x = 0; x < dstWidth; x++) { |
dst[x] = SkPack888ToRGB16(src[0], src[1], src[2]); |
src += bytesPerPixel; |
} |
@@ -331,48 +370,51 @@ static SkSwizzler::ResultAlpha swizzle_rgbx_to_565( |
// kRGBA |
static SkSwizzler::ResultAlpha swizzle_rgba_to_n32_premul( |
- void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width, |
- int bytesPerPixel, const SkPMColor ctable[]) { |
+ void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth, |
+ int deltaSrc, int offset, const SkPMColor ctable[]) { |
+ src += offset; |
SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; |
INIT_RESULT_ALPHA; |
- for (int x = 0; x < width; x++) { |
+ for (int x = 0; x < dstWidth; x++) { |
unsigned alpha = src[3]; |
UPDATE_RESULT_ALPHA(alpha); |
dst[x] = SkPreMultiplyARGB(alpha, src[0], src[1], src[2]); |
- src += bytesPerPixel; |
+ src += deltaSrc; |
} |
return COMPUTE_RESULT_ALPHA; |
} |
static SkSwizzler::ResultAlpha swizzle_rgba_to_n32_unpremul( |
- void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width, |
- int bytesPerPixel, const SkPMColor ctable[]) { |
+ void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth, |
+ int deltaSrc, int offset, const SkPMColor ctable[]) { |
+ src += offset; |
uint32_t* SK_RESTRICT dst = reinterpret_cast<uint32_t*>(dstRow); |
INIT_RESULT_ALPHA; |
- for (int x = 0; x < width; x++) { |
+ for (int x = 0; x < dstWidth; x++) { |
unsigned alpha = src[3]; |
UPDATE_RESULT_ALPHA(alpha); |
dst[x] = SkPackARGB32NoCheck(alpha, src[0], src[1], src[2]); |
- src += bytesPerPixel; |
+ src += deltaSrc; |
} |
return COMPUTE_RESULT_ALPHA; |
} |
static SkSwizzler::ResultAlpha swizzle_rgba_to_n32_premul_skipZ( |
- void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width, |
- int bytesPerPixel, const SkPMColor ctable[]) { |
+ void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth, |
+ int deltaSrc, int offset, const SkPMColor ctable[]) { |
+ src += offset; |
SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; |
INIT_RESULT_ALPHA; |
- for (int x = 0; x < width; x++) { |
+ for (int x = 0; x < dstWidth; x++) { |
unsigned alpha = src[3]; |
UPDATE_RESULT_ALPHA(alpha); |
if (0 != alpha) { |
dst[x] = SkPreMultiplyARGB(alpha, src[0], src[1], src[2]); |
} |
- src += bytesPerPixel; |
+ src += deltaSrc; |
} |
return COMPUTE_RESULT_ALPHA; |
} |
@@ -385,11 +427,12 @@ static SkSwizzler::ResultAlpha swizzle_rgba_to_n32_premul_skipZ( |
decide whether to switch to unpremul default. |
static bool swizzle_rgba_to_n32_unpremul_skipZ(void* SK_RESTRICT dstRow, |
const uint8_t* SK_RESTRICT src, |
- int width, int bitsPerPixel, |
+ int dstWidth, int bitsPerPixel, int offset, |
const SkPMColor[]) { |
+ src += offset; |
SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; |
unsigned alphaMask = 0xFF; |
- for (int x = 0; x < width; x++) { |
+ for (int x = 0; x < dstWidth; x++) { |
unsigned alpha = src[3]; |
// NOTE: We cheat here. The caller requested unpremul and skip zeroes. It's possible |
// the color components are not zero, but we skip them anyway, meaning they'll remain |
@@ -406,9 +449,10 @@ static bool swizzle_rgba_to_n32_unpremul_skipZ(void* SK_RESTRICT dstRow, |
SkSwizzler* SkSwizzler::CreateSwizzler(SkSwizzler::SrcConfig sc, |
const SkPMColor* ctable, |
- const SkImageInfo& info, |
- SkCodec::ZeroInitialized zeroInit) { |
- if (info.colorType() == kUnknown_SkColorType || kUnknown == sc) { |
+ const SkImageInfo& dstInfo, |
+ SkCodec::ZeroInitialized zeroInit, |
+ const SkImageInfo& srcInfo) { |
+ if (dstInfo.colorType() == kUnknown_SkColorType || kUnknown == sc) { |
return NULL; |
} |
if ((kIndex == sc || kIndex4 == sc || kIndex2 == sc || kIndex1 == sc) |
@@ -416,9 +460,10 @@ SkSwizzler* SkSwizzler::CreateSwizzler(SkSwizzler::SrcConfig sc, |
return NULL; |
} |
RowProc proc = NULL; |
+ |
switch (sc) { |
case kBit: |
- switch (info.colorType()) { |
+ switch (dstInfo.colorType()) { |
case kN32_SkColorType: |
proc = &swizzle_bit_to_n32; |
break; |
@@ -435,7 +480,7 @@ SkSwizzler* SkSwizzler::CreateSwizzler(SkSwizzler::SrcConfig sc, |
case kIndex1: |
case kIndex2: |
case kIndex4: |
- switch (info.colorType()) { |
+ switch (dstInfo.colorType()) { |
case kN32_SkColorType: |
proc = &swizzle_small_index_to_n32; |
break; |
@@ -447,7 +492,7 @@ SkSwizzler* SkSwizzler::CreateSwizzler(SkSwizzler::SrcConfig sc, |
} |
break; |
case kIndex: |
- switch (info.colorType()) { |
+ switch (dstInfo.colorType()) { |
case kN32_SkColorType: |
// We assume the color premultiplied ctable (or not) as desired. |
if (SkCodec::kYes_ZeroInitialized == zeroInit) { |
@@ -469,7 +514,7 @@ SkSwizzler* SkSwizzler::CreateSwizzler(SkSwizzler::SrcConfig sc, |
} |
break; |
case kGray: |
- switch (info.colorType()) { |
+ switch (dstInfo.colorType()) { |
case kN32_SkColorType: |
proc = &swizzle_gray_to_n32; |
break; |
@@ -485,7 +530,7 @@ SkSwizzler* SkSwizzler::CreateSwizzler(SkSwizzler::SrcConfig sc, |
break; |
case kBGR: |
case kBGRX: |
- switch (info.colorType()) { |
+ switch (dstInfo.colorType()) { |
case kN32_SkColorType: |
proc = &swizzle_bgrx_to_n32; |
break; |
@@ -494,9 +539,9 @@ SkSwizzler* SkSwizzler::CreateSwizzler(SkSwizzler::SrcConfig sc, |
} |
break; |
case kBGRA: |
- switch (info.colorType()) { |
+ switch (dstInfo.colorType()) { |
case kN32_SkColorType: |
- switch (info.alphaType()) { |
+ switch (dstInfo.alphaType()) { |
case kUnpremul_SkAlphaType: |
proc = &swizzle_bgra_to_n32_unpremul; |
break; |
@@ -513,7 +558,7 @@ SkSwizzler* SkSwizzler::CreateSwizzler(SkSwizzler::SrcConfig sc, |
break; |
case kRGBX: |
// TODO: Support other swizzles. |
- switch (info.colorType()) { |
+ switch (dstInfo.colorType()) { |
case kN32_SkColorType: |
proc = &swizzle_rgbx_to_n32; |
break; |
@@ -524,9 +569,9 @@ SkSwizzler* SkSwizzler::CreateSwizzler(SkSwizzler::SrcConfig sc, |
} |
break; |
case kRGBA: |
- switch (info.colorType()) { |
+ switch (dstInfo.colorType()) { |
case kN32_SkColorType: |
- if (info.alphaType() == kUnpremul_SkAlphaType) { |
+ if (dstInfo.alphaType() == kUnpremul_SkAlphaType) { |
// Respect zeroInit? |
proc = &swizzle_rgba_to_n32_unpremul; |
} else { |
@@ -542,7 +587,7 @@ SkSwizzler* SkSwizzler::CreateSwizzler(SkSwizzler::SrcConfig sc, |
} |
break; |
case kRGB: |
- switch (info.colorType()) { |
+ switch (dstInfo.colorType()) { |
case kN32_SkColorType: |
proc = &swizzle_rgbx_to_n32; |
break; |
@@ -550,6 +595,14 @@ SkSwizzler* SkSwizzler::CreateSwizzler(SkSwizzler::SrcConfig sc, |
break; |
} |
break; |
+ case kRGB_565: |
+ switch (dstInfo.colorType()) { |
+ case kRGB_565_SkColorType: |
+ proc = &sample565; |
+ break; |
+ default: |
+ break; |
+ } |
default: |
break; |
} |
@@ -558,22 +611,31 @@ SkSwizzler* SkSwizzler::CreateSwizzler(SkSwizzler::SrcConfig sc, |
} |
// Store deltaSrc in bytes if it is an even multiple, otherwise use bits |
- int deltaSrc = SkIsAlign8(BitsPerPixel(sc)) ? BytesPerPixel(sc) : |
- BitsPerPixel(sc); |
- return SkNEW_ARGS(SkSwizzler, (proc, ctable, deltaSrc, info)); |
+ int deltaSrc = SkIsAlign8(BitsPerPixel(sc)) ? BytesPerPixel(sc) : BitsPerPixel(sc); |
+ |
+ // get sampleX based on srcInfo and dstInfo dimensions |
+ int sampleX; |
+ SkScaledCodec::ComputeSampleSize(dstInfo, srcInfo, &sampleX, NULL); |
+ |
+ return SkNEW_ARGS(SkSwizzler, (proc, ctable, deltaSrc, dstInfo, sampleX)); |
} |
SkSwizzler::SkSwizzler(RowProc proc, const SkPMColor* ctable, |
- int deltaSrc, const SkImageInfo& info) |
+ int deltaSrc, const SkImageInfo& info, int sampleX) |
: fRowProc(proc) |
, fColorTable(ctable) |
, fDeltaSrc(deltaSrc) |
, fDstInfo(info) |
-{} |
+ , fSampleX(sampleX) |
+ , fX0(sampleX == 1 ? 0 : sampleX >> 1) |
+{ |
+ // check that fX0 is less than original width |
+ SkASSERT(fX0 >= 0 && fX0 < fDstInfo.width() * fSampleX); |
+} |
SkSwizzler::ResultAlpha SkSwizzler::swizzle(void* dst, const uint8_t* SK_RESTRICT src) { |
SkASSERT(NULL != dst && NULL != src); |
- return fRowProc(dst, src, fDstInfo.width(), fDeltaSrc, fColorTable); |
+ return fRowProc(dst, src, fDstInfo.width(), fSampleX * fDeltaSrc, fX0 * fDeltaSrc, fColorTable); |
} |
void SkSwizzler::Fill(void* dstStartRow, const SkImageInfo& dstInfo, size_t dstRowBytes, |