diff options
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/SkBitmap.cpp | 30 | ||||
-rw-r--r-- | src/core/SkBitmapProcState.cpp | 20 | ||||
-rw-r--r-- | src/core/SkBitmapProcState_procs.h | 19 | ||||
-rw-r--r-- | src/core/SkConfig8888.cpp | 51 | ||||
-rw-r--r-- | src/core/SkImageInfo.cpp | 1 | ||||
-rw-r--r-- | src/core/SkMipMap.cpp | 38 |
6 files changed, 157 insertions, 2 deletions
diff --git a/src/core/SkBitmap.cpp b/src/core/SkBitmap.cpp index 0b586cb081..877cfaa6e1 100644 --- a/src/core/SkBitmap.cpp +++ b/src/core/SkBitmap.cpp @@ -516,6 +516,7 @@ void* SkBitmap::getAddr(int x, int y) const { break; case kAlpha_8_SkColorType: case kIndex_8_SkColorType: + case kGray_8_SkColorType: base += x; break; default: @@ -532,6 +533,10 @@ SkColor SkBitmap::getColor(int x, int y) const { SkASSERT((unsigned)y < (unsigned)this->height()); switch (this->colorType()) { + case kGray_8_SkColorType: { + uint8_t* addr = this->getAddr8(x, y); + return SkColorSetRGB(*addr, *addr, *addr); + } case kAlpha_8_SkColorType: { uint8_t* addr = this->getAddr8(x, y); return SkColorSetA(0, addr[0]); @@ -597,6 +602,7 @@ bool SkBitmap::ComputeIsOpaque(const SkBitmap& bm) { return 0xFF == SkGetPackedA32(c); } break; case kRGB_565_SkColorType: + case kGray_8_SkColorType: return true; break; case kARGB_4444_SkColorType: { @@ -674,6 +680,20 @@ void SkBitmap::internalErase(const SkIRect& area, const int rowBytes = fRowBytes; switch (this->colorType()) { + case kGray_8_SkColorType: { + if (255 != a) { + r = SkMulDiv255Round(r, a); + g = SkMulDiv255Round(g, a); + b = SkMulDiv255Round(b, a); + } + int gray = SkComputeLuminance(r, g, b); + uint8_t* p = this->getAddr8(area.fLeft, area.fTop); + while (--height >= 0) { + memset(p, gray, width); + p += rowBytes; + } + break; + } case kAlpha_8_SkColorType: { uint8_t* p = this->getAddr8(area.fLeft, area.fTop); while (--height >= 0) { @@ -828,6 +848,16 @@ bool SkBitmap::canCopyTo(SkColorType dstColorType) const { break; case kARGB_4444_SkColorType: return sameConfigs || kN32_SkColorType == srcCT || kIndex_8_SkColorType == srcCT; + case kGray_8_SkColorType: + switch (srcCT) { + case kGray_8_SkColorType: + case kRGBA_8888_SkColorType: + case kBGRA_8888_SkColorType: + return true; + default: + break; + } + return false; default: return false; } diff --git a/src/core/SkBitmapProcState.cpp b/src/core/SkBitmapProcState.cpp index 42d9c1003e..69c2ea19be 100644 --- a/src/core/SkBitmapProcState.cpp +++ b/src/core/SkBitmapProcState.cpp @@ -431,6 +431,10 @@ bool SkBitmapProcState::chooseScanlineProcs(bool trivialMatrix, bool clampClamp, index |= 32; fPaintPMColor = SkPreMultiplyColor(paint.getColor()); break; + case kGray_8_SkColorType: + index |= 40; + fPaintPMColor = SkPreMultiplyColor(paint.getColor()); + break; default: // TODO(dominikg): Should we ever get here? SkASSERT(false) instead? return false; @@ -473,7 +477,7 @@ bool SkBitmapProcState::chooseScanlineProcs(bool trivialMatrix, bool clampClamp, S4444_alpha_D32_filter_DXDY, S4444_opaque_D32_filter_DX, S4444_alpha_D32_filter_DX, - + // A8 treats alpha/opaque the same (equally efficient) SA8_alpha_D32_nofilter_DXDY, SA8_alpha_D32_nofilter_DXDY, @@ -482,7 +486,17 @@ bool SkBitmapProcState::chooseScanlineProcs(bool trivialMatrix, bool clampClamp, SA8_alpha_D32_filter_DXDY, SA8_alpha_D32_filter_DXDY, SA8_alpha_D32_filter_DX, - SA8_alpha_D32_filter_DX + SA8_alpha_D32_filter_DX, + + // todo: possibly specialize on opaqueness + SG8_alpha_D32_nofilter_DXDY, + SG8_alpha_D32_nofilter_DXDY, + SG8_alpha_D32_nofilter_DX, + SG8_alpha_D32_nofilter_DX, + SG8_alpha_D32_filter_DXDY, + SG8_alpha_D32_filter_DXDY, + SG8_alpha_D32_filter_DX, + SG8_alpha_D32_filter_DX }; static const SampleProc16 gSkBitmapProcStateSample16[] = { @@ -504,6 +518,8 @@ bool SkBitmapProcState::chooseScanlineProcs(bool trivialMatrix, bool clampClamp, // Don't support 4444 -> 565 NULL, NULL, NULL, NULL, // Don't support A8 -> 565 + NULL, NULL, NULL, NULL, + // Don't support G8 -> 565 (but we could) NULL, NULL, NULL, NULL }; #endif diff --git a/src/core/SkBitmapProcState_procs.h b/src/core/SkBitmapProcState_procs.h index 3b4cef3955..a9b87501b4 100644 --- a/src/core/SkBitmapProcState_procs.h +++ b/src/core/SkBitmapProcState_procs.h @@ -224,6 +224,25 @@ static inline U8CPU Filter_8(unsigned x, unsigned y, #define SRC_TO_FILTER(src) src #include "SkBitmapProcState_sample.h" +// SRC == Gray8 + +#undef FILTER_PROC +#define FILTER_PROC(x, y, a, b, c, d, dst) \ + do { \ + unsigned tmp = Filter_8(x, y, a, b, c, d); \ + SkPMColor color = SkPackARGB32(0xFF, tmp, tmp, tmp); \ + *(dst) = SkAlphaMulQ(color, alphaScale); \ + } while (0) + +#define MAKENAME(suffix) NAME_WRAP(SG8_alpha_D32 ## suffix) +#define DSTSIZE 32 +#define SRCTYPE uint8_t +#define CHECKSTATE(state) SkASSERT(kGray_8_SkColorType == state.fBitmap->colorType()); +#define PREAMBLE(state) unsigned alphaScale = state.fAlphaScale +#define RETURNDST(src) SkAlphaMulQ(SkPackARGB32(0xFF, src, src, src), alphaScale) +#define SRC_TO_FILTER(src) src +#include "SkBitmapProcState_sample.h" + /***************************************************************************** * * D16 functions diff --git a/src/core/SkConfig8888.cpp b/src/core/SkConfig8888.cpp index 85e208f287..d28941c27c 100644 --- a/src/core/SkConfig8888.cpp +++ b/src/core/SkConfig8888.cpp @@ -137,6 +137,47 @@ static void rect_memcpy(void* dst, size_t dstRB, const void* src, size_t srcRB, } } +static void copy_g8_to_32(void* dst, size_t dstRB, const void* src, size_t srcRB, int w, int h) { + uint32_t* dst32 = (uint32_t*)dst; + const uint8_t* src8 = (const uint8_t*)src; + + for (int y = 0; y < h; ++y) { + for (int x = 0; x < w; ++x) { + dst32[x] = SkPackARGB32(0xFF, src8[x], src8[x], src8[x]); + } + dst32 = (uint32_t*)((char*)dst32 + dstRB); + src8 += srcRB; + } +} + +static void copy_32_to_g8(void* dst, size_t dstRB, const void* src, size_t srcRB, + const SkImageInfo& srcInfo) { + uint8_t* dst8 = (uint8_t*)dst; + const uint32_t* src32 = (const uint32_t*)src; + + const int w = srcInfo.width(); + const int h = srcInfo.height(); + const bool isBGRA = (kBGRA_8888_SkColorType == srcInfo.colorType()); + + for (int y = 0; y < h; ++y) { + if (isBGRA) { + // BGRA + for (int x = 0; x < w; ++x) { + uint32_t s = src32[x]; + dst8[x] = SkComputeLuminance((s >> 16) & 0xFF, (s >> 8) & 0xFF, s & 0xFF); + } + } else { + // RGBA + for (int x = 0; x < w; ++x) { + uint32_t s = src32[x]; + dst8[x] = SkComputeLuminance(s & 0xFF, (s >> 8) & 0xFF, (s >> 16) & 0xFF); + } + } + src32 = (const uint32_t*)((const char*)src32 + srcRB); + dst8 += dstRB; + } +} + bool SkPixelInfo::CopyPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRB, const SkImageInfo& srcInfo, const void* srcPixels, size_t srcRB, SkColorTable* ctable) { @@ -170,6 +211,7 @@ bool SkPixelInfo::CopyPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t switch (srcInfo.colorType()) { case kRGB_565_SkColorType: case kAlpha_8_SkColorType: + case kGray_8_SkColorType: break; case kIndex_8_SkColorType: case kARGB_4444_SkColorType: @@ -189,6 +231,15 @@ bool SkPixelInfo::CopyPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t * are supported. */ + if (kGray_8_SkColorType == srcInfo.colorType() && 4 == dstInfo.bytesPerPixel()) { + copy_g8_to_32(dstPixels, dstRB, srcPixels, srcRB, width, height); + return true; + } + if (kGray_8_SkColorType == dstInfo.colorType() && 4 == srcInfo.bytesPerPixel()) { + copy_32_to_g8(dstPixels, dstRB, srcPixels, srcRB, srcInfo); + return true; + } + // Can no longer draw directly into 4444, but we can manually whack it for a few combinations if (kARGB_4444_SkColorType == dstInfo.colorType() && (kN32_SkColorType == srcInfo.colorType() || kIndex_8_SkColorType == srcInfo.colorType())) { diff --git a/src/core/SkImageInfo.cpp b/src/core/SkImageInfo.cpp index 0e8b0b1292..8429ef28c3 100644 --- a/src/core/SkImageInfo.cpp +++ b/src/core/SkImageInfo.cpp @@ -66,6 +66,7 @@ bool SkColorTypeValidateAlphaType(SkColorType colorType, SkAlphaType alphaType, } break; case kRGB_565_SkColorType: + case kGray_8_SkColorType: alphaType = kOpaque_SkAlphaType; break; default: diff --git a/src/core/SkMipMap.cpp b/src/core/SkMipMap.cpp index 9e0e5e1f52..1b410856e4 100644 --- a/src/core/SkMipMap.cpp +++ b/src/core/SkMipMap.cpp @@ -135,6 +135,39 @@ static void downsample4444(void* dst, int x, int y, const void* srcPtr, const Sk *((uint16_t*)dst) = (uint16_t)collaps4444(c >> 2); } +static void downsample8_nocheck(void* dst, int, int, const void* srcPtr, const SkBitmap& srcBM) { + const size_t rb = srcBM.rowBytes(); + const uint8_t* p = static_cast<const uint8_t*>(srcPtr); + *(uint8_t*)dst = (p[0] + p[1] + p[rb] + p[rb + 1]) >> 2; +} + +static void downsample8_check(void* dst, int x, int y, const void* srcPtr, const SkBitmap& srcBM) { + const uint8_t* p = static_cast<const uint8_t*>(srcPtr); + const uint8_t* baseP = p; + + x <<= 1; + y <<= 1; + SkASSERT(srcBM.getAddr8(x, y) == p); + + unsigned c = *p; + if (x < srcBM.width() - 1) { + p += 1; + } + c += *p; + + p = baseP; + if (y < srcBM.height() - 1) { + p += srcBM.rowBytes(); + } + c += *p; + if (x < srcBM.width() - 1) { + p += 1; + } + c += *p; + + *(uint8_t*)dst = c >> 2; +} + size_t SkMipMap::AllocLevelsSize(int levelCount, size_t pixelSize) { if (levelCount < 0) { return 0; @@ -167,6 +200,11 @@ SkMipMap* SkMipMap::Build(const SkBitmap& src, SkDiscardableFactoryProc fact) { proc_check = downsample4444; proc_nocheck = proc_check; break; + case kAlpha_8_SkColorType: + case kGray_8_SkColorType: + proc_check = downsample8_check; + proc_nocheck = downsample8_nocheck; + break; default: return NULL; // don't build mipmaps for any other colortypes (yet) } |