Index: src/codec/SkMaskSwizzler.cpp |
diff --git a/src/codec/SkMaskSwizzler.cpp b/src/codec/SkMaskSwizzler.cpp |
index 58be0c67af441660664b5e25466d6a205b04d92c..6ca9b58f4ed7e16e27490188aa6077412c1ed6dc 100644 |
--- a/src/codec/SkMaskSwizzler.cpp |
+++ b/src/codec/SkMaskSwizzler.cpp |
@@ -8,57 +8,64 @@ |
#include "SkCodecPriv.h" |
#include "SkColorPriv.h" |
#include "SkMaskSwizzler.h" |
+#include "SkScaledCodec.h" |
static SkSwizzler::ResultAlpha swizzle_mask16_to_n32_opaque( |
- void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks) { |
+ void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks, |
+ uint32_t startX, uint32_t sampleX) { |
// Use the masks to decode to the destination |
- uint16_t* srcPtr = (uint16_t*) srcRow; |
+ uint16_t* srcPtr = ((uint16_t*) srcRow) + startX; |
SkPMColor* dstPtr = (SkPMColor*) dstRow; |
for (int i = 0; i < width; i++) { |
- uint16_t p = srcPtr[i]; |
+ uint16_t p = srcPtr[0]; |
uint8_t red = masks->getRed(p); |
uint8_t green = masks->getGreen(p); |
uint8_t blue = masks->getBlue(p); |
dstPtr[i] = SkPackARGB32NoCheck(0xFF, red, green, blue); |
+ srcPtr += sampleX; |
} |
return SkSwizzler::kOpaque_ResultAlpha; |
} |
static SkSwizzler::ResultAlpha swizzle_mask16_to_n32_unpremul( |
- void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks) { |
+ void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks, |
+ uint32_t startX, uint32_t sampleX) { |
// Use the masks to decode to the destination |
- uint16_t* srcPtr = (uint16_t*) srcRow; |
+ uint16_t* srcPtr = ((uint16_t*) srcRow) + startX; |
SkPMColor* dstPtr = (SkPMColor*) dstRow; |
INIT_RESULT_ALPHA; |
for (int i = 0; i < width; i++) { |
- uint16_t p = srcPtr[i]; |
+ uint16_t p = srcPtr[0]; |
uint8_t red = masks->getRed(p); |
uint8_t green = masks->getGreen(p); |
uint8_t blue = masks->getBlue(p); |
uint8_t alpha = masks->getAlpha(p); |
UPDATE_RESULT_ALPHA(alpha); |
dstPtr[i] = SkPackARGB32NoCheck(alpha, red, green, blue); |
+ srcPtr += sampleX; |
} |
return COMPUTE_RESULT_ALPHA; |
} |
static SkSwizzler::ResultAlpha swizzle_mask16_to_n32_premul( |
- void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks) { |
+ void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks, |
+ uint32_t startX, uint32_t sampleX) { |
// Use the masks to decode to the destination |
- uint16_t* srcPtr = (uint16_t*) srcRow; |
+ uint16_t* srcPtr = ((uint16_t*) srcRow) + startX; |
SkPMColor* dstPtr = (SkPMColor*) dstRow; |
INIT_RESULT_ALPHA; |
for (int i = 0; i < width; i++) { |
- uint16_t p = srcPtr[i]; |
+ uint16_t p = srcPtr[0]; |
uint8_t red = masks->getRed(p); |
uint8_t green = masks->getGreen(p); |
uint8_t blue = masks->getBlue(p); |
uint8_t alpha = masks->getAlpha(p); |
UPDATE_RESULT_ALPHA(alpha); |
dstPtr[i] = SkPreMultiplyARGB(alpha, red, green, blue); |
+ srcPtr += sampleX; |
} |
return COMPUTE_RESULT_ALPHA; |
} |
@@ -66,152 +73,174 @@ static SkSwizzler::ResultAlpha swizzle_mask16_to_n32_premul( |
// TODO (msarett): We have promoted a two byte per pixel image to 8888, only to |
// convert it back to 565. Instead, we should swizzle to 565 directly. |
static SkSwizzler::ResultAlpha swizzle_mask16_to_565( |
- void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks) { |
+ void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks, |
+ uint32_t startX, uint32_t sampleX) { |
// Use the masks to decode to the destination |
- uint16_t* srcPtr = (uint16_t*) srcRow; |
+ uint16_t* srcPtr = ((uint16_t*) srcRow) + startX; |
uint16_t* dstPtr = (uint16_t*) dstRow; |
for (int i = 0; i < width; i++) { |
- uint16_t p = srcPtr[i]; |
+ uint16_t p = srcPtr[0]; |
uint8_t red = masks->getRed(p); |
uint8_t green = masks->getGreen(p); |
uint8_t blue = masks->getBlue(p); |
dstPtr[i] = SkPack888ToRGB16(red, green, blue); |
+ srcPtr += sampleX; |
} |
return SkSwizzler::kOpaque_ResultAlpha; |
} |
static SkSwizzler::ResultAlpha swizzle_mask24_to_n32_opaque( |
- void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks) { |
+ void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks, |
+ uint32_t startX, uint32_t sampleX) { |
// Use the masks to decode to the destination |
+ srcRow += 3 * startX; |
SkPMColor* dstPtr = (SkPMColor*) dstRow; |
- for (int i = 0; i < 3*width; i += 3) { |
- uint32_t p = srcRow[i] | (srcRow[i + 1] << 8) | srcRow[i + 2] << 16; |
+ for (int i = 0; i < width; i++) { |
+ uint32_t p = srcRow[0] | (srcRow[1] << 8) | srcRow[2] << 16; |
uint8_t red = masks->getRed(p); |
uint8_t green = masks->getGreen(p); |
uint8_t blue = masks->getBlue(p); |
- dstPtr[i/3] = SkPackARGB32NoCheck(0xFF, red, green, blue); |
+ dstPtr[i] = SkPackARGB32NoCheck(0xFF, red, green, blue); |
+ srcRow += 3 * sampleX; |
} |
return SkSwizzler::kOpaque_ResultAlpha; |
} |
static SkSwizzler::ResultAlpha swizzle_mask24_to_n32_unpremul( |
- void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks) { |
+ void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks, |
+ uint32_t startX, uint32_t sampleX) { |
// Use the masks to decode to the destination |
+ srcRow += 3 * startX; |
SkPMColor* dstPtr = (SkPMColor*) dstRow; |
INIT_RESULT_ALPHA; |
- for (int i = 0; i < 3*width; i += 3) { |
- uint32_t p = srcRow[i] | (srcRow[i + 1] << 8) | srcRow[i + 2] << 16; |
+ for (int i = 0; i < width; i++) { |
+ uint32_t p = srcRow[0] | (srcRow[1] << 8) | srcRow[2] << 16; |
uint8_t red = masks->getRed(p); |
uint8_t green = masks->getGreen(p); |
uint8_t blue = masks->getBlue(p); |
uint8_t alpha = masks->getAlpha(p); |
UPDATE_RESULT_ALPHA(alpha); |
- dstPtr[i/3] = SkPackARGB32NoCheck(alpha, red, green, blue); |
+ dstPtr[i] = SkPackARGB32NoCheck(alpha, red, green, blue); |
+ srcRow += 3 * sampleX; |
} |
return COMPUTE_RESULT_ALPHA; |
} |
static SkSwizzler::ResultAlpha swizzle_mask24_to_n32_premul( |
- void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks) { |
+ void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks, |
+ uint32_t startX, uint32_t sampleX) { |
// Use the masks to decode to the destination |
+ srcRow += 3 * startX; |
SkPMColor* dstPtr = (SkPMColor*) dstRow; |
INIT_RESULT_ALPHA; |
- for (int i = 0; i < 3*width; i += 3) { |
- uint32_t p = srcRow[i] | (srcRow[i + 1] << 8) | srcRow[i + 2] << 16; |
+ for (int i = 0; i < width; i++) { |
+ uint32_t p = srcRow[0] | (srcRow[1] << 8) | srcRow[2] << 16; |
uint8_t red = masks->getRed(p); |
uint8_t green = masks->getGreen(p); |
uint8_t blue = masks->getBlue(p); |
uint8_t alpha = masks->getAlpha(p); |
UPDATE_RESULT_ALPHA(alpha); |
- dstPtr[i/3] = SkPreMultiplyARGB(alpha, red, green, blue); |
+ dstPtr[i] = SkPreMultiplyARGB(alpha, red, green, blue); |
+ srcRow += 3 * sampleX; |
} |
return COMPUTE_RESULT_ALPHA; |
} |
static SkSwizzler::ResultAlpha swizzle_mask24_to_565( |
- void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks) { |
+ void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks, |
+ uint32_t startX, uint32_t sampleX) { |
// Use the masks to decode to the destination |
+ srcRow += 3 * startX; |
uint16_t* dstPtr = (uint16_t*) dstRow; |
- for (int i = 0; i < 3*width; i += 3) { |
- uint32_t p = srcRow[i] | (srcRow[i + 1] << 8) | srcRow[i + 2] << 16; |
+ for (int i = 0; i < width; i++) { |
+ uint32_t p = srcRow[0] | (srcRow[1] << 8) | srcRow[2] << 16; |
uint8_t red = masks->getRed(p); |
uint8_t green = masks->getGreen(p); |
uint8_t blue = masks->getBlue(p); |
- dstPtr[i/3] = SkPack888ToRGB16(red, green, blue); |
+ dstPtr[i] = SkPack888ToRGB16(red, green, blue); |
+ srcRow += 3 * sampleX; |
} |
return SkSwizzler::kOpaque_ResultAlpha; |
} |
static SkSwizzler::ResultAlpha swizzle_mask32_to_n32_opaque( |
- void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks) { |
+ void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks, |
+ uint32_t startX, uint32_t sampleX) { |
// Use the masks to decode to the destination |
- uint32_t* srcPtr = (uint32_t*) srcRow; |
+ uint32_t* srcPtr = ((uint32_t*) srcRow) + startX; |
SkPMColor* dstPtr = (SkPMColor*) dstRow; |
for (int i = 0; i < width; i++) { |
- uint32_t p = srcPtr[i]; |
+ uint32_t p = srcPtr[0]; |
uint8_t red = masks->getRed(p); |
uint8_t green = masks->getGreen(p); |
uint8_t blue = masks->getBlue(p); |
dstPtr[i] = SkPackARGB32NoCheck(0xFF, red, green, blue); |
+ srcPtr += sampleX; |
} |
return SkSwizzler::kOpaque_ResultAlpha; |
} |
static SkSwizzler::ResultAlpha swizzle_mask32_to_n32_unpremul( |
- void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks) { |
+ void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks, |
+ uint32_t startX, uint32_t sampleX) { |
// Use the masks to decode to the destination |
- uint32_t* srcPtr = (uint32_t*) srcRow; |
+ uint32_t* srcPtr = ((uint32_t*) srcRow) + startX; |
SkPMColor* dstPtr = (SkPMColor*) dstRow; |
INIT_RESULT_ALPHA; |
for (int i = 0; i < width; i++) { |
- uint32_t p = srcPtr[i]; |
+ uint32_t p = srcPtr[0]; |
uint8_t red = masks->getRed(p); |
uint8_t green = masks->getGreen(p); |
uint8_t blue = masks->getBlue(p); |
uint8_t alpha = masks->getAlpha(p); |
UPDATE_RESULT_ALPHA(alpha); |
dstPtr[i] = SkPackARGB32NoCheck(alpha, red, green, blue); |
+ srcPtr += sampleX; |
} |
return COMPUTE_RESULT_ALPHA; |
} |
static SkSwizzler::ResultAlpha swizzle_mask32_to_n32_premul( |
- void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks) { |
+ void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks, |
+ uint32_t startX, uint32_t sampleX) { |
// Use the masks to decode to the destination |
- uint32_t* srcPtr = (uint32_t*) srcRow; |
+ uint32_t* srcPtr = ((uint32_t*) srcRow) + startX; |
SkPMColor* dstPtr = (SkPMColor*) dstRow; |
INIT_RESULT_ALPHA; |
for (int i = 0; i < width; i++) { |
- uint32_t p = srcPtr[i]; |
+ uint32_t p = srcPtr[0]; |
uint8_t red = masks->getRed(p); |
uint8_t green = masks->getGreen(p); |
uint8_t blue = masks->getBlue(p); |
uint8_t alpha = masks->getAlpha(p); |
UPDATE_RESULT_ALPHA(alpha); |
dstPtr[i] = SkPreMultiplyARGB(alpha, red, green, blue); |
+ srcPtr += sampleX; |
} |
return COMPUTE_RESULT_ALPHA; |
} |
static SkSwizzler::ResultAlpha swizzle_mask32_to_565( |
- void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks) { |
+ void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks, |
+ uint32_t startX, uint32_t sampleX) { |
// Use the masks to decode to the destination |
- uint32_t* srcPtr = (uint32_t*) srcRow; |
+ uint32_t* srcPtr = ((uint32_t*) srcRow) + startX; |
uint16_t* dstPtr = (uint16_t*) dstRow; |
for (int i = 0; i < width; i++) { |
- uint32_t p = srcPtr[i]; |
+ uint32_t p = srcPtr[0]; |
uint8_t red = masks->getRed(p); |
uint8_t green = masks->getGreen(p); |
uint8_t blue = masks->getBlue(p); |
dstPtr[i] = SkPack888ToRGB16(red, green, blue); |
+ srcPtr += sampleX; |
} |
return SkSwizzler::kOpaque_ResultAlpha; |
} |
@@ -222,15 +251,16 @@ static SkSwizzler::ResultAlpha swizzle_mask32_to_565( |
* |
*/ |
SkMaskSwizzler* SkMaskSwizzler::CreateMaskSwizzler( |
- const SkImageInfo& info, SkMasks* masks, uint32_t bitsPerPixel) { |
+ const SkImageInfo& dstInfo, const SkImageInfo& srcInfo, SkMasks* masks, |
+ uint32_t bitsPerPixel) { |
// Choose the appropriate row procedure |
RowProc proc = nullptr; |
switch (bitsPerPixel) { |
case 16: |
- switch (info.colorType()) { |
+ switch (dstInfo.colorType()) { |
case kN32_SkColorType: |
- switch (info.alphaType()) { |
+ switch (dstInfo.alphaType()) { |
case kUnpremul_SkAlphaType: |
proc = &swizzle_mask16_to_n32_unpremul; |
break; |
@@ -245,7 +275,7 @@ SkMaskSwizzler* SkMaskSwizzler::CreateMaskSwizzler( |
} |
break; |
case kRGB_565_SkColorType: |
- switch (info.alphaType()) { |
+ switch (dstInfo.alphaType()) { |
case kOpaque_SkAlphaType: |
proc = &swizzle_mask16_to_565; |
break; |
@@ -258,9 +288,9 @@ SkMaskSwizzler* SkMaskSwizzler::CreateMaskSwizzler( |
} |
break; |
case 24: |
- switch (info.colorType()) { |
+ switch (dstInfo.colorType()) { |
case kN32_SkColorType: |
- switch (info.alphaType()) { |
+ switch (dstInfo.alphaType()) { |
case kUnpremul_SkAlphaType: |
proc = &swizzle_mask24_to_n32_unpremul; |
break; |
@@ -275,7 +305,7 @@ SkMaskSwizzler* SkMaskSwizzler::CreateMaskSwizzler( |
} |
break; |
case kRGB_565_SkColorType: |
- switch (info.alphaType()) { |
+ switch (dstInfo.alphaType()) { |
case kOpaque_SkAlphaType: |
proc = &swizzle_mask24_to_565; |
break; |
@@ -288,9 +318,9 @@ SkMaskSwizzler* SkMaskSwizzler::CreateMaskSwizzler( |
} |
break; |
case 32: |
- switch (info.colorType()) { |
+ switch (dstInfo.colorType()) { |
case kN32_SkColorType: |
- switch (info.alphaType()) { |
+ switch (dstInfo.alphaType()) { |
case kUnpremul_SkAlphaType: |
proc = &swizzle_mask32_to_n32_unpremul; |
break; |
@@ -305,7 +335,7 @@ SkMaskSwizzler* SkMaskSwizzler::CreateMaskSwizzler( |
} |
break; |
case kRGB_565_SkColorType: |
- switch (info.alphaType()) { |
+ switch (dstInfo.alphaType()) { |
case kOpaque_SkAlphaType: |
proc = &swizzle_mask32_to_565; |
break; |
@@ -321,7 +351,12 @@ SkMaskSwizzler* SkMaskSwizzler::CreateMaskSwizzler( |
SkASSERT(false); |
return nullptr; |
} |
- return new SkMaskSwizzler(info, masks, proc); |
+ |
+ // Get the sample size |
+ int sampleX; |
+ SkScaledCodec::ComputeSampleSize(dstInfo, srcInfo, &sampleX, NULL); |
+ |
+ return new SkMaskSwizzler(dstInfo, masks, proc, sampleX); |
} |
/* |
@@ -330,10 +365,12 @@ SkMaskSwizzler* SkMaskSwizzler::CreateMaskSwizzler( |
* |
*/ |
SkMaskSwizzler::SkMaskSwizzler(const SkImageInfo& dstInfo, SkMasks* masks, |
- RowProc proc) |
+ RowProc proc, uint32_t sampleX) |
: fDstInfo(dstInfo) |
, fMasks(masks) |
, fRowProc(proc) |
+ , fSampleX(sampleX) |
+ , fStartX(get_start_coord(sampleX)) |
{} |
/* |
@@ -343,5 +380,5 @@ SkMaskSwizzler::SkMaskSwizzler(const SkImageInfo& dstInfo, SkMasks* masks, |
*/ |
SkSwizzler::ResultAlpha SkMaskSwizzler::swizzle(void* dst, const uint8_t* SK_RESTRICT src) { |
SkASSERT(nullptr != dst && nullptr != src); |
- return fRowProc(dst, src, fDstInfo.width(), fMasks); |
+ return fRowProc(dst, src, fDstInfo.width(), fMasks, fStartX, fSampleX); |
} |