| Index: src/codec/SkMaskSwizzler.cpp
|
| diff --git a/src/codec/SkMaskSwizzler.cpp b/src/codec/SkMaskSwizzler.cpp
|
| index 31fd2cf81e0d9caaf11bece4ce3fd9bb7eacb01e..1582681feb53297b494762cca8917ed2b6da5806 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 = NULL;
|
| 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 NULL;
|
| }
|
| - return SkNEW_ARGS(SkMaskSwizzler, (info, masks, proc));
|
| +
|
| + // Get the sample size
|
| + int sampleX;
|
| + SkScaledCodec::ComputeSampleSize(dstInfo, srcInfo, &sampleX, NULL);
|
| +
|
| + return SkNEW_ARGS(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(SkScaledCodec::GetStartCoord(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(NULL != dst && NULL != src);
|
| - return fRowProc(dst, src, fDstInfo.width(), fMasks);
|
| + return fRowProc(dst, src, fDstInfo.width(), fMasks, fStartX, fSampleX);
|
| }
|
|
|