| Index: src/images/SkScaledBitmapSampler.cpp
|
| diff --git a/src/images/SkScaledBitmapSampler.cpp b/src/images/SkScaledBitmapSampler.cpp
|
| deleted file mode 100644
|
| index 5ffd64889396b57ac8b5bf893f7f106212be00f1..0000000000000000000000000000000000000000
|
| --- a/src/images/SkScaledBitmapSampler.cpp
|
| +++ /dev/null
|
| @@ -1,877 +0,0 @@
|
| -/*
|
| - * Copyright 2007 The Android Open Source Project
|
| - *
|
| - * Use of this source code is governed by a BSD-style license that can be
|
| - * found in the LICENSE file.
|
| - */
|
| -
|
| -
|
| -#include "SkScaledBitmapSampler.h"
|
| -#include "SkBitmap.h"
|
| -#include "SkColorPriv.h"
|
| -#include "SkDither.h"
|
| -#include "SkTypes.h"
|
| -
|
| -// 8888
|
| -
|
| -static bool Sample_Gray_D8888(void* SK_RESTRICT dstRow,
|
| - const uint8_t* SK_RESTRICT src,
|
| - int width, int deltaSrc, int, const SkPMColor[]) {
|
| - SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
|
| - for (int x = 0; x < width; x++) {
|
| - dst[x] = SkPackARGB32(0xFF, src[0], src[0], src[0]);
|
| - src += deltaSrc;
|
| - }
|
| - return false;
|
| -}
|
| -
|
| -static SkScaledBitmapSampler::RowProc
|
| -get_gray_to_8888_proc(const SkScaledBitmapSampler::Options& opts) {
|
| - // 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[]) {
|
| - SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
|
| - for (int x = 0; x < width; x++) {
|
| - dst[x] = SkPackARGB32(0xFF, src[0], src[1], src[2]);
|
| - src += deltaSrc;
|
| - }
|
| - return false;
|
| -}
|
| -
|
| -static SkScaledBitmapSampler::RowProc
|
| -get_RGBx_to_8888_proc(const SkScaledBitmapSampler::Options& opts) {
|
| - // 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[]) {
|
| - SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
|
| - unsigned alphaMask = 0xFF;
|
| - for (int x = 0; x < width; x++) {
|
| - unsigned alpha = src[3];
|
| - dst[x] = SkPreMultiplyARGB(alpha, src[0], src[1], src[2]);
|
| - src += deltaSrc;
|
| - alphaMask &= alpha;
|
| - }
|
| - 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 SkScaledBitmapSampler::Options& opts) {
|
| - // Dither has no effect.
|
| - if (!opts.fPremultiplyAlpha) {
|
| - // 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 (opts.fSkipZeros) {
|
| - return Sample_RGBA_D8888_SkipZ;
|
| - }
|
| - return Sample_RGBA_D8888;
|
| -}
|
| -
|
| -// 565
|
| -
|
| -static bool Sample_Gray_D565(void* SK_RESTRICT dstRow,
|
| - const uint8_t* SK_RESTRICT src,
|
| - int width, int deltaSrc, int, const SkPMColor[]) {
|
| - uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow;
|
| - for (int x = 0; x < width; x++) {
|
| - dst[x] = SkPack888ToRGB16(src[0], src[0], src[0]);
|
| - src += deltaSrc;
|
| - }
|
| - return false;
|
| -}
|
| -
|
| -static bool Sample_Gray_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[0], src[0], DITHER_VALUE(x));
|
| - src += deltaSrc;
|
| - }
|
| - return false;
|
| -}
|
| -
|
| -static SkScaledBitmapSampler::RowProc
|
| -get_gray_to_565_proc(const SkScaledBitmapSampler::Options& opts) {
|
| - // Unpremul and skip zeroes make no difference
|
| - if (opts.fDither) {
|
| - 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[]) {
|
| - uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow;
|
| - for (int x = 0; x < width; x++) {
|
| - dst[x] = SkPack888ToRGB16(src[0], src[1], src[2]);
|
| - src += deltaSrc;
|
| - }
|
| - 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 SkScaledBitmapSampler::Options& opts) {
|
| - // Unpremul and skip zeroes make no difference
|
| - if (opts.fDither) {
|
| - 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[]) {
|
| - uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow;
|
| - uint16_t* SK_RESTRICT castedSrc = (uint16_t*) src;
|
| - for (int x = 0; x < width; x++) {
|
| - dst[x] = castedSrc[0];
|
| - castedSrc += deltaSrc >> 1;
|
| - }
|
| - return false;
|
| -}
|
| -
|
| -static SkScaledBitmapSampler::RowProc
|
| -get_565_to_565_proc(const SkScaledBitmapSampler::Options& opts) {
|
| - // Unpremul, dither, and skip zeroes have no effect
|
| - return Sample_D565_D565;
|
| -}
|
| -
|
| -// 4444
|
| -
|
| -static bool Sample_Gray_D4444(void* SK_RESTRICT dstRow,
|
| - const uint8_t* SK_RESTRICT src,
|
| - int width, int deltaSrc, int, const SkPMColor[]) {
|
| - SkPMColor16* SK_RESTRICT dst = (SkPMColor16*)dstRow;
|
| - for (int x = 0; x < width; x++) {
|
| - unsigned gray = src[0] >> 4;
|
| - dst[x] = SkPackARGB4444(0xF, gray, gray, gray);
|
| - src += deltaSrc;
|
| - }
|
| - return false;
|
| -}
|
| -
|
| -static bool Sample_Gray_D4444_D(void* SK_RESTRICT dstRow,
|
| - const uint8_t* SK_RESTRICT src,
|
| - int width, int deltaSrc, int y, const SkPMColor[]) {
|
| - SkPMColor16* SK_RESTRICT dst = (SkPMColor16*)dstRow;
|
| - DITHER_4444_SCAN(y);
|
| - for (int x = 0; x < width; x++) {
|
| - dst[x] = SkDitherARGB32To4444(0xFF, src[0], src[0], src[0],
|
| - DITHER_VALUE(x));
|
| - src += deltaSrc;
|
| - }
|
| - return false;
|
| -}
|
| -
|
| -static SkScaledBitmapSampler::RowProc
|
| -get_gray_to_4444_proc(const SkScaledBitmapSampler::Options& opts) {
|
| - // Skip zeroes and unpremul make no difference
|
| - if (opts.fDither) {
|
| - 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[]) {
|
| - SkPMColor16* SK_RESTRICT dst = (SkPMColor16*)dstRow;
|
| - for (int x = 0; x < width; x++) {
|
| - dst[x] = SkPackARGB4444(0xF, src[0] >> 4, src[1] >> 4, src[2] >> 4);
|
| - src += deltaSrc;
|
| - }
|
| - return false;
|
| -}
|
| -
|
| -static bool Sample_RGBx_D4444_D(void* SK_RESTRICT dstRow,
|
| - const uint8_t* SK_RESTRICT src,
|
| - int width, int deltaSrc, int y, const SkPMColor[]) {
|
| - SkPMColor16* dst = (SkPMColor16*)dstRow;
|
| - DITHER_4444_SCAN(y);
|
| -
|
| - for (int x = 0; x < width; x++) {
|
| - dst[x] = SkDitherARGB32To4444(0xFF, src[0], src[1], src[2],
|
| - DITHER_VALUE(x));
|
| - src += deltaSrc;
|
| - }
|
| - return false;
|
| -}
|
| -
|
| -static SkScaledBitmapSampler::RowProc
|
| -get_RGBx_to_4444_proc(const SkScaledBitmapSampler::Options& opts) {
|
| - // Skip zeroes and unpremul make no difference
|
| - if (opts.fDither) {
|
| - 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[]) {
|
| - SkPMColor16* SK_RESTRICT dst = (SkPMColor16*)dstRow;
|
| - unsigned alphaMask = 0xFF;
|
| -
|
| - for (int x = 0; x < width; x++) {
|
| - unsigned alpha = src[3];
|
| - 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_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[]) {
|
| - SkPMColor16* SK_RESTRICT dst = (SkPMColor16*)dstRow;
|
| - unsigned alphaMask = 0xFF;
|
| - DITHER_4444_SCAN(y);
|
| -
|
| - for (int x = 0; x < width; x++) {
|
| - unsigned alpha = src[3];
|
| - 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 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 SkScaledBitmapSampler::Options& opts) {
|
| - if (!opts.fPremultiplyAlpha) {
|
| - // Unpremultiplied is not supported for 4444
|
| - return nullptr;
|
| - }
|
| - if (opts.fSkipZeros) {
|
| - if (opts.fDither) {
|
| - return Sample_RGBA_D4444_D_SkipZ;
|
| - }
|
| - return Sample_RGBA_D4444_SkipZ;
|
| - }
|
| - if (opts.fDither) {
|
| - return Sample_RGBA_D4444_D;
|
| - }
|
| - return Sample_RGBA_D4444;
|
| -}
|
| -
|
| -// Index
|
| -
|
| -#define A32_MASK_IN_PLACE (SkPMColor)(SK_A32_MASK << SK_A32_SHIFT)
|
| -
|
| -static bool Sample_Index_D8888(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;
|
| - dst[x] = c;
|
| - src += deltaSrc;
|
| - }
|
| - 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 SkScaledBitmapSampler::Options& opts) {
|
| - // The caller is expected to have created the source colortable
|
| - // properly with respect to opts.fPremultiplyAlpha, so premul makes
|
| - // no difference here.
|
| - // Dither makes no difference
|
| - if (opts.fSkipZeros) {
|
| - 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[]) {
|
| -
|
| - uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow;
|
| - for (int x = 0; x < width; x++) {
|
| - dst[x] = SkPixel32ToPixel16(ctable[*src]);
|
| - src += deltaSrc;
|
| - }
|
| - return false;
|
| -}
|
| -
|
| -static bool Sample_Index_D565_D(void* SK_RESTRICT dstRow,
|
| - const uint8_t* SK_RESTRICT src, int width,
|
| - int deltaSrc, int y, const SkPMColor ctable[]) {
|
| -
|
| - uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow;
|
| - DITHER_565_SCAN(y);
|
| -
|
| - for (int x = 0; x < width; x++) {
|
| - SkPMColor c = ctable[*src];
|
| - dst[x] = SkDitherRGBTo565(SkGetPackedR32(c), SkGetPackedG32(c),
|
| - SkGetPackedB32(c), DITHER_VALUE(x));
|
| - src += deltaSrc;
|
| - }
|
| - return false;
|
| -}
|
| -
|
| -static SkScaledBitmapSampler::RowProc
|
| -get_index_to_565_proc(const SkScaledBitmapSampler::Options& opts) {
|
| - // Unpremultiplied and skip zeroes make no difference
|
| - if (opts.fDither) {
|
| - 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[]) {
|
| -
|
| - 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;
|
| - dst[x] = SkPixel32ToPixel4444(c);
|
| - src += deltaSrc;
|
| - }
|
| - return cc != A32_MASK_IN_PLACE;
|
| -}
|
| -
|
| -static bool Sample_Index_D4444_D(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;
|
| - dst[x] = SkDitherARGB32To4444(c, DITHER_VALUE(x));
|
| - src += deltaSrc;
|
| - }
|
| - 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 SkScaledBitmapSampler::Options& opts) {
|
| - // Unpremul not allowed
|
| - if (!opts.fPremultiplyAlpha) {
|
| - return nullptr;
|
| - }
|
| - if (opts.fSkipZeros) {
|
| - if (opts.fDither) {
|
| - return Sample_Index_D4444_D_SkipZ;
|
| - }
|
| - return Sample_Index_D4444_SkipZ;
|
| - }
|
| - if (opts.fDither) {
|
| - 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[]) {
|
| - if (1 == deltaSrc) {
|
| - memcpy(dstRow, src, width);
|
| - } else {
|
| - uint8_t* SK_RESTRICT dst = (uint8_t*)dstRow;
|
| - for (int x = 0; x < width; x++) {
|
| - dst[x] = src[0];
|
| - src += deltaSrc;
|
| - }
|
| - }
|
| - return false;
|
| -}
|
| -
|
| -static SkScaledBitmapSampler::RowProc
|
| -get_index_to_index_proc(const SkScaledBitmapSampler::Options& opts) {
|
| - // Unpremul not allowed
|
| - if (!opts.fPremultiplyAlpha) {
|
| - return nullptr;
|
| - }
|
| - // 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,
|
| - int width, int deltaSrc, int,
|
| - const SkPMColor[]) {
|
| - // Sampling Gray to A8 uses the same function as Index to Index8,
|
| - // except we assume that there is alpha for speed, since an A8
|
| - // bitmap with no alpha is not interesting.
|
| - (void) Sample_Index_DI(dstRow, src, width, deltaSrc, /* y unused */ 0,
|
| - /* ctable unused */ nullptr);
|
| - return true;
|
| -}
|
| -
|
| -static SkScaledBitmapSampler::RowProc
|
| -get_gray_to_A8_proc(const SkScaledBitmapSampler::Options& opts) {
|
| - if (!opts.fPremultiplyAlpha) {
|
| - return nullptr;
|
| - }
|
| - // Ignore skip and dither.
|
| - return Sample_Gray_DA8;
|
| -}
|
| -
|
| -typedef SkScaledBitmapSampler::RowProc (*RowProcChooser)(const SkScaledBitmapSampler::Options&);
|
| -///////////////////////////////////////////////////////////////////////////////
|
| -
|
| -#include "SkScaledBitmapSampler.h"
|
| -
|
| -SkScaledBitmapSampler::SkScaledBitmapSampler(int width, int height,
|
| - int sampleSize) {
|
| - fCTable = nullptr;
|
| - fDstRow = nullptr;
|
| - fRowProc = nullptr;
|
| -
|
| - if (width <= 0 || height <= 0) {
|
| - sk_throw();
|
| - }
|
| -
|
| - SkDEBUGCODE(fSampleMode = kUninitialized_SampleMode);
|
| -
|
| - if (sampleSize <= 1) {
|
| - fScaledWidth = width;
|
| - fScaledHeight = height;
|
| - fX0 = fY0 = 0;
|
| - fDX = fDY = 1;
|
| - return;
|
| - }
|
| -
|
| - int dx = SkMin32(sampleSize, width);
|
| - int dy = SkMin32(sampleSize, height);
|
| -
|
| - fScaledWidth = width / dx;
|
| - fScaledHeight = height / dy;
|
| -
|
| - SkASSERT(fScaledWidth > 0);
|
| - SkASSERT(fScaledHeight > 0);
|
| -
|
| - fX0 = dx >> 1;
|
| - fY0 = dy >> 1;
|
| -
|
| - SkASSERT(fX0 >= 0 && fX0 < width);
|
| - SkASSERT(fY0 >= 0 && fY0 < height);
|
| -
|
| - fDX = dx;
|
| - fDY = dy;
|
| -
|
| - SkASSERT(fDX > 0 && (fX0 + fDX * (fScaledWidth - 1)) < width);
|
| - SkASSERT(fDY > 0 && (fY0 + fDY * (fScaledHeight - 1)) < height);
|
| -}
|
| -
|
| -bool SkScaledBitmapSampler::begin(SkBitmap* dst, SrcConfig sc,
|
| - const Options& opts,
|
| - 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,
|
| - nullptr, // 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,
|
| - nullptr, // 565 to 4444
|
| -
|
| - nullptr, // gray to index
|
| - nullptr, // rgbx to index
|
| - nullptr, // rgba to index
|
| - get_index_to_index_proc,
|
| - nullptr, // 565 to index
|
| -
|
| - get_gray_to_A8_proc,
|
| - nullptr, // rgbx to a8
|
| - nullptr, // rgba to a8
|
| - nullptr, // index to a8
|
| - nullptr, // 565 to a8
|
| - };
|
| -
|
| - // The jump between dst configs in the table
|
| - static const int gProcDstConfigSpan = 5;
|
| - static_assert(SK_ARRAY_COUNT(gProcChoosers) == 5 * gProcDstConfigSpan,
|
| - "gProcs_has_the_wrong_number_of_entries");
|
| -
|
| - fCTable = ctable;
|
| -
|
| - int index = 0;
|
| - switch (sc) {
|
| - case SkScaledBitmapSampler::kGray:
|
| - fSrcPixelSize = 1;
|
| - index += 0;
|
| - break;
|
| - case SkScaledBitmapSampler::kRGB:
|
| - fSrcPixelSize = 3;
|
| - index += 1;
|
| - break;
|
| - case SkScaledBitmapSampler::kRGBX:
|
| - fSrcPixelSize = 4;
|
| - index += 1;
|
| - break;
|
| - case SkScaledBitmapSampler::kRGBA:
|
| - fSrcPixelSize = 4;
|
| - index += 2;
|
| - break;
|
| - case SkScaledBitmapSampler::kIndex:
|
| - fSrcPixelSize = 1;
|
| - index += 3;
|
| - break;
|
| - case SkScaledBitmapSampler::kRGB_565:
|
| - fSrcPixelSize = 2;
|
| - index += 4;
|
| - break;
|
| - default:
|
| - return false;
|
| - }
|
| -
|
| - switch (dst->colorType()) {
|
| - case kN32_SkColorType:
|
| - index += 0 * gProcDstConfigSpan;
|
| - break;
|
| - case kRGB_565_SkColorType:
|
| - index += 1 * gProcDstConfigSpan;
|
| - break;
|
| - case kARGB_4444_SkColorType:
|
| - index += 2 * gProcDstConfigSpan;
|
| - break;
|
| - case kIndex_8_SkColorType:
|
| - index += 3 * gProcDstConfigSpan;
|
| - break;
|
| - case kAlpha_8_SkColorType:
|
| - index += 4 * gProcDstConfigSpan;
|
| - break;
|
| - default:
|
| - return false;
|
| - }
|
| -
|
| - RowProcChooser chooser = gProcChoosers[index];
|
| - if (nullptr == chooser) {
|
| - fRowProc = nullptr;
|
| - } else {
|
| - fRowProc = chooser(opts);
|
| - }
|
| - fDstRow = (char*)dst->getPixels();
|
| - fDstRowBytes = dst->rowBytes();
|
| - fCurrY = 0;
|
| - return fRowProc != nullptr;
|
| -}
|
| -
|
| -bool SkScaledBitmapSampler::begin(SkBitmap* dst, SrcConfig sc,
|
| - const SkImageDecoder& decoder,
|
| - const SkPMColor ctable[]) {
|
| - return this->begin(dst, sc, Options(decoder), ctable);
|
| -}
|
| -
|
| -bool SkScaledBitmapSampler::next(const uint8_t* SK_RESTRICT src) {
|
| - SkASSERT(kInterlaced_SampleMode != fSampleMode);
|
| - SkDEBUGCODE(fSampleMode = kConsecutive_SampleMode);
|
| - SkASSERT((unsigned)fCurrY < (unsigned)fScaledHeight);
|
| -
|
| - bool hadAlpha = fRowProc(fDstRow, src + fX0 * fSrcPixelSize, fScaledWidth,
|
| - fDX * fSrcPixelSize, fCurrY, fCTable);
|
| - fDstRow += fDstRowBytes;
|
| - fCurrY += 1;
|
| - return hadAlpha;
|
| -}
|
| -
|
| -bool SkScaledBitmapSampler::sampleInterlaced(const uint8_t* SK_RESTRICT src, int srcY) {
|
| - SkASSERT(kConsecutive_SampleMode != fSampleMode);
|
| - SkDEBUGCODE(fSampleMode = kInterlaced_SampleMode);
|
| - // Any line that should be a part of the destination can be created by the formula:
|
| - // fY0 + (some multiplier) * fDY
|
| - // so if srcY - fY0 is not an integer multiple of fDY that srcY will be skipped.
|
| - const int srcYMinusY0 = srcY - fY0;
|
| - if (srcYMinusY0 % fDY != 0) {
|
| - // This line is not part of the output, so return false for alpha, since we have
|
| - // not added an alpha to the output.
|
| - return false;
|
| - }
|
| - // Unlike in next(), where the data is used sequentially, this function skips around,
|
| - // so fDstRow and fCurrY are never updated. fDstRow must always be the starting point
|
| - // of the destination bitmap's pixels, which is used to calculate the destination row
|
| - // each time this function is called.
|
| - const int dstY = srcYMinusY0 / fDY;
|
| - if (dstY >= fScaledHeight) {
|
| - return false;
|
| - }
|
| - char* dstRow = fDstRow + dstY * fDstRowBytes;
|
| - return fRowProc(dstRow, src + fX0 * fSrcPixelSize, fScaledWidth,
|
| - fDX * fSrcPixelSize, dstY, fCTable);
|
| -}
|
| -
|
| -#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, nullptr, nullptr, // to A8
|
| - nullptr, nullptr, nullptr, nullptr, // 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
|
| - nullptr, nullptr, nullptr, nullptr, // to A8
|
| - Sample_Index_DI, Sample_Index_DI, nullptr, nullptr, // 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, nullptr, nullptr, // to 4444
|
| - Sample_Index_D8888, Sample_Index_D8888, Sample_Index_D8888, Sample_Index_D8888, // to 8888
|
| - // RGB
|
| - nullptr, nullptr, nullptr, nullptr, // to A8
|
| - nullptr, nullptr, nullptr, nullptr, // 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
|
| - nullptr, nullptr, nullptr, nullptr, // to A8
|
| - nullptr, nullptr, nullptr, nullptr, // 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
|
| - nullptr, nullptr, nullptr, nullptr, // to A8
|
| - nullptr, nullptr, nullptr, nullptr, // 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, nullptr, nullptr, // to 4444
|
| - Sample_RGBA_D8888, Sample_RGBA_D8888, Sample_RGBA_D8888_Unpremul, Sample_RGBA_D8888_Unpremul, // to 8888
|
| - // RGB_565
|
| - nullptr, nullptr, nullptr, nullptr, // to A8
|
| - nullptr, nullptr, nullptr, nullptr, // to Index8
|
| - Sample_D565_D565, Sample_D565_D565, Sample_D565_D565, Sample_D565_D565, // to 565
|
| - nullptr, nullptr, nullptr, nullptr, // to 4444
|
| - nullptr, nullptr, nullptr, nullptr, // to 8888
|
| -};
|
| -
|
| -// Dummy class that allows instantiation of an ImageDecoder, so begin can query its fields.
|
| -class DummyDecoder : public SkImageDecoder {
|
| -public:
|
| - DummyDecoder() {}
|
| -protected:
|
| - Result onDecode(SkStream*, SkBitmap*, SkImageDecoder::Mode) override {
|
| - return kFailure;
|
| - }
|
| -};
|
| -
|
| -void test_row_proc_choice();
|
| -void test_row_proc_choice() {
|
| - const SkColorType colorTypes[] = {
|
| - kAlpha_8_SkColorType, kIndex_8_SkColorType, kRGB_565_SkColorType, kARGB_4444_SkColorType,
|
| - kN32_SkColorType
|
| - };
|
| -
|
| - SkBitmap dummyBitmap;
|
| - DummyDecoder dummyDecoder;
|
| - size_t procCounter = 0;
|
| - for (int sc = SkScaledBitmapSampler::kGray; sc <= SkScaledBitmapSampler::kRGB_565; ++sc) {
|
| - for (size_t c = 0; c < SK_ARRAY_COUNT(colorTypes); ++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.setInfo(SkImageInfo::Make(10, 10,
|
| - colorTypes[c], kPremul_SkAlphaType));
|
| - 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
|
|
|