static SkStream* extract_argb4444_data(const SkBitmap& bitmap, const SkIRect& srcRect, bool extractAlpha, bool* isOpaque, bool* isTransparent) { SkStream* stream; uint8_t* dst = NULL; if (extractAlpha) { const int alphaRowBytes = (srcRect.width() + 1) / 2; stream = SkNEW_ARGS(SkMemoryStream, (alphaRowBytes * srcRect.height())); } else { stream = SkNEW_ARGS(SkMemoryStream, (get_uncompressed_size(bitmap, srcRect))); } dst = (uint8_t*)stream->getMemoryBase(); for (int y = srcRect.fTop; y < srcRect.fBottom; y++) { uint16_t* src = bitmap.getAddr16(0, y); int x; for (x = srcRect.fLeft; x + 1 < srcRect.fRight; x += 2) { if (extractAlpha) { dst[0] = (SkGetPackedA4444(src[x]) << 4) | SkGetPackedA4444(src[x + 1]); *isOpaque &= dst[0] == SK_AlphaOPAQUE; *isTransparent &= dst[0] == SK_AlphaTRANSPARENT; dst++; } else { dst[0] = (SkGetPackedR4444(src[x]) << 4) | SkGetPackedG4444(src[x]); dst[1] = (SkGetPackedB4444(src[x]) << 4) | SkGetPackedR4444(src[x + 1]); dst[2] = (SkGetPackedG4444(src[x + 1]) << 4) | SkGetPackedB4444(src[x + 1]); dst += 3; } } if (srcRect.width() & 1) { if (extractAlpha) { dst[0] = (SkGetPackedA4444(src[x]) << 4); *isOpaque &= dst[0] == (SK_AlphaOPAQUE & 0xF0); *isTransparent &= dst[0] == (SK_AlphaTRANSPARENT & 0xF0); dst++; } else { dst[0] = (SkGetPackedR4444(src[x]) << 4) | SkGetPackedG4444(src[x]); dst[1] = (SkGetPackedB4444(src[x]) << 4); dst += 2; } } } return stream; }
static uint16_t get_argb4444_neighbor_avg_color(const SkBitmap& bitmap, int xOrig, int yOrig) { uint8_t count = 0; uint8_t r = 0; uint8_t g = 0; uint8_t b = 0; for (int y = yOrig - 1; y <= yOrig + 1; y++) { if (y < 0 || y >= bitmap.height()) { continue; } uint16_t* src = bitmap.getAddr16(0, y); for (int x = xOrig - 1; x <= xOrig + 1; x++) { if (x < 0 || x >= bitmap.width()) { continue; } if ((SkGetPackedA4444(src[x]) & 0x0F) != SK_AlphaTRANSPARENT) { uint16_t color = remove_alpha_argb4444(src[x]); r += SkGetPackedR4444(color); g += SkGetPackedG4444(color); b += SkGetPackedB4444(color); count++; } } } if (count == 0) { return SkPackARGB4444(SK_AlphaOPAQUE & 0x0F, 0, 0, 0); } else { return SkPackARGB4444(SK_AlphaOPAQUE & 0x0F, r / count, g / count, b / count); } }
// returns 0..15 static unsigned color_dist4444(uint16_t c, unsigned r, unsigned g, unsigned b) { SkASSERT(r <= 0xF); SkASSERT(g <= 0xF); SkASSERT(b <= 0xF); unsigned dr = SkAbs32(SkGetPackedR4444(c) - r); unsigned dg = SkAbs32(SkGetPackedG4444(c) - g); unsigned db = SkAbs32(SkGetPackedB4444(c) - b); return SkMax32(dr, SkMax32(dg, db)); }
static void rgb2yuv_4444(uint8_t dst[], U16CPU c) { int r = SkGetPackedR4444(c); int g = SkGetPackedG4444(c); int b = SkGetPackedB4444(c); int y = ( CYR*r + CYG*g + CYB*b ) >> (CSHIFT - 4); int u = ( CUR*r + CUG*g + CUB*b ) >> (CSHIFT - 4); int v = ( CVR*r + CVG*g + CVB*b ) >> (CSHIFT - 4); dst[0] = SkToU8(y); dst[1] = SkToU8(u + 128); dst[2] = SkToU8(v + 128); }