diff options
author | reed <reed@chromium.org> | 2015-03-17 17:44:06 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-03-17 17:44:07 -0700 |
commit | 0c9b1a8d05ea6ec5dfae0ead854304673d94d2c2 (patch) | |
tree | c6df748125f1c6a992900fa98de135a1b17d30b1 | |
parent | 160f24ce0e8d6dd7ca80b78871e063d4f4609cfb (diff) |
add kGray_8_SkColorType
patch from issue 1014783003 at patchset 60001 (http://crrev.com/1014783003#ps60001)
BUG=skia:
TBR=
Review URL: https://codereview.chromium.org/1010343002
-rw-r--r-- | gm/filterbitmap.cpp | 49 | ||||
-rw-r--r-- | include/core/SkImageInfo.h | 4 | ||||
-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 | ||||
-rw-r--r-- | src/gpu/SkGr.cpp | 2 | ||||
-rw-r--r-- | src/pdf/SkPDFImage.cpp | 25 |
10 files changed, 217 insertions, 22 deletions
diff --git a/gm/filterbitmap.cpp b/gm/filterbitmap.cpp index 7028012f45..c76a70a8ea 100644 --- a/gm/filterbitmap.cpp +++ b/gm/filterbitmap.cpp @@ -138,12 +138,13 @@ class FilterBitmapTextGM: public FilterBitmapGM { }; class FilterBitmapCheckerboardGM: public FilterBitmapGM { - public: - FilterBitmapCheckerboardGM(int size, int num_checks) - : fSize(size), fNumChecks(num_checks) - { - fName.printf("filterbitmap_checkerboard_%d_%d", fSize, fNumChecks); - } +public: + FilterBitmapCheckerboardGM(int size, int num_checks, bool convertToG8 = false) + : fSize(size), fNumChecks(num_checks), fConvertToG8(convertToG8) + { + fName.printf("filterbitmap_checkerboard_%d_%d%s", + fSize, fNumChecks, convertToG8 ? "_g8" : ""); + } protected: int fSize; @@ -167,20 +168,26 @@ class FilterBitmapCheckerboardGM: public FilterBitmapGM { } } } + if (fConvertToG8) { + SkBitmap tmp; + fBM.copyTo(&tmp, kGray_8_SkColorType); + fBM = tmp; + } } - private: - typedef FilterBitmapGM INHERITED; +private: + const bool fConvertToG8; + typedef FilterBitmapGM INHERITED; }; class FilterBitmapImageGM: public FilterBitmapGM { - public: - FilterBitmapImageGM(const char filename[]) - : fFilename(filename) - { - fName.printf("filterbitmap_image_%s", filename); - } +public: + FilterBitmapImageGM(const char filename[], bool convertToG8 = false) + : fFilename(filename), fConvertToG8(convertToG8) + { + fName.printf("filterbitmap_image_%s%s", filename, convertToG8 ? "_g8" : ""); + } - protected: +protected: SkString fFilename; int fSize; @@ -204,9 +211,15 @@ class FilterBitmapImageGM: public FilterBitmapGM { *(fBM.getAddr32(0,0)) = 0xFF0000FF; // red == bad } fSize = fBM.height(); + if (fConvertToG8) { + SkBitmap tmp; + fBM.copyTo(&tmp, kGray_8_SkColorType); + fBM = tmp; + } } - private: - typedef FilterBitmapGM INHERITED; +private: + const bool fConvertToG8; + typedef FilterBitmapGM INHERITED; }; ////////////////////////////////////////////////////////////////////////////// @@ -216,12 +229,14 @@ DEF_GM( return new FilterBitmapTextGM(7); ) DEF_GM( return new FilterBitmapTextGM(10); ) DEF_GM( return new FilterBitmapCheckerboardGM(4,4); ) DEF_GM( return new FilterBitmapCheckerboardGM(32,32); ) +DEF_GM( return new FilterBitmapCheckerboardGM(32,32, true); ) DEF_GM( return new FilterBitmapCheckerboardGM(32,8); ) DEF_GM( return new FilterBitmapCheckerboardGM(32,2); ) DEF_GM( return new FilterBitmapCheckerboardGM(192,192); ) DEF_GM( return new FilterBitmapImageGM("mandrill_16.png"); ) DEF_GM( return new FilterBitmapImageGM("mandrill_32.png"); ) DEF_GM( return new FilterBitmapImageGM("mandrill_64.png"); ) +DEF_GM( return new FilterBitmapImageGM("mandrill_64.png", true); ) DEF_GM( return new FilterBitmapImageGM("mandrill_128.png"); ) DEF_GM( return new FilterBitmapImageGM("mandrill_256.png"); ) DEF_GM( return new FilterBitmapImageGM("mandrill_512.png"); ) diff --git a/include/core/SkImageInfo.h b/include/core/SkImageInfo.h index d915c09255..01318fd1aa 100644 --- a/include/core/SkImageInfo.h +++ b/include/core/SkImageInfo.h @@ -72,8 +72,9 @@ enum SkColorType { kRGBA_8888_SkColorType, kBGRA_8888_SkColorType, kIndex_8_SkColorType, + kGray_8_SkColorType, - kLastEnum_SkColorType = kIndex_8_SkColorType, + kLastEnum_SkColorType = kGray_8_SkColorType, #if SK_PMCOLOR_BYTE_ORDER(B,G,R,A) kN32_SkColorType = kBGRA_8888_SkColorType, @@ -93,6 +94,7 @@ static int SkColorTypeBytesPerPixel(SkColorType ct) { 4, // RGBA_8888 4, // BGRA_8888 1, // kIndex_8 + 1, // kGray_8 }; SK_COMPILE_ASSERT(SK_ARRAY_COUNT(gSize) == (size_t)(kLastEnum_SkColorType + 1), size_mismatch_with_SkColorType_enum); 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) } diff --git a/src/gpu/SkGr.cpp b/src/gpu/SkGr.cpp index d105418377..32c9158334 100644 --- a/src/gpu/SkGr.cpp +++ b/src/gpu/SkGr.cpp @@ -594,6 +594,8 @@ GrPixelConfig SkImageInfo2GrPixelConfig(SkColorType ct, SkAlphaType, SkColorProf return kBGRA_8888_GrPixelConfig; case kIndex_8_SkColorType: return kIndex_8_GrPixelConfig; + case kGray_8_SkColorType: + return kAlpha_8_GrPixelConfig; // TODO: gray8 support on gpu } SkASSERT(0); // shouldn't get here return kUnknown_GrPixelConfig; diff --git a/src/pdf/SkPDFImage.cpp b/src/pdf/SkPDFImage.cpp index 666a008292..e3971aa57a 100644 --- a/src/pdf/SkPDFImage.cpp +++ b/src/pdf/SkPDFImage.cpp @@ -31,6 +31,7 @@ static size_t get_uncompressed_size(const SkBitmap& bitmap, return srcRect.width() * 3 * srcRect.height(); case kRGBA_8888_SkColorType: case kBGRA_8888_SkColorType: + case kGray_8_SkColorType: return srcRect.width() * 3 * srcRect.height(); case kAlpha_8_SkColorType: return 1; @@ -113,7 +114,7 @@ static SkStream* extract_rgb565_image(const SkBitmap& bitmap, const SkIRect& srcRect) { SkStream* stream = SkNEW_ARGS(SkMemoryStream, (get_uncompressed_size(bitmap, - srcRect))); + srcRect))); uint8_t* dst = (uint8_t*)stream->getMemoryBase(); for (int y = srcRect.fTop; y < srcRect.fBottom; y++) { uint16_t* src = bitmap.getAddr16(0, y); @@ -127,6 +128,20 @@ static SkStream* extract_rgb565_image(const SkBitmap& bitmap, return stream; } +static SkStream* extract_gray8_image(const SkBitmap& bitmap, const SkIRect& srcRect) { + SkStream* stream = SkNEW_ARGS(SkMemoryStream, + (get_uncompressed_size(bitmap, srcRect))); + uint8_t* dst = (uint8_t*)stream->getMemoryBase(); + for (int y = srcRect.fTop; y < srcRect.fBottom; y++) { + uint8_t* src = bitmap.getAddr8(0, y); + for (int x = srcRect.fLeft; x < srcRect.fRight; x++) { + dst[0] = dst[1] = dst[2] = src[x]; + dst += 3; + } + } + return stream; +} + static uint32_t get_argb8888_neighbor_avg_color(const SkBitmap& bitmap, int xOrig, int yOrig); @@ -227,7 +242,8 @@ static SkStream* extract_image_data(const SkBitmap& bitmap, bool extractAlpha, bool* isTransparent) { SkColorType colorType = bitmap.colorType(); if (extractAlpha && (kIndex_8_SkColorType == colorType || - kRGB_565_SkColorType == colorType)) { + kRGB_565_SkColorType == colorType || + kGray_8_SkColorType == colorType)) { if (isTransparent != NULL) { *isTransparent = false; } @@ -258,6 +274,11 @@ static SkStream* extract_image_data(const SkBitmap& bitmap, stream.reset(extract_rgb565_image(bitmap, srcRect)); } break; + case kGray_8_SkColorType: + if (!extractAlpha) { + stream.reset(extract_gray8_image(bitmap, srcRect)); + } + break; case kN32_SkColorType: stream.reset(extract_argb8888_data(bitmap, srcRect, extractAlpha, &isOpaque, &transparent)); |