static unsigned color_dist16(uint16_t a, uint16_t b) { unsigned dr = SkAbs32(SkPacked16ToR32(a) - SkPacked16ToR32(b)); unsigned dg = SkAbs32(SkPacked16ToG32(a) - SkPacked16ToG32(b)); unsigned db = SkAbs32(SkPacked16ToB32(a) - SkPacked16ToB32(b)); return SkMax32(dr, SkMax32(dg, db)); }
void SkTransparentShader::TransparentShaderContext::shadeSpan(int x, int y, SkPMColor span[], int count) { unsigned scale = SkAlpha255To256(this->getPaintAlpha()); switch (fDevice->colorType()) { case kN32_SkColorType: if (scale == 256) { SkPMColor* src = fDevice->getAddr32(x, y); if (src != span) { memcpy(span, src, count * sizeof(SkPMColor)); } } else { const SkPMColor* src = fDevice->getAddr32(x, y); for (int i = count - 1; i >= 0; --i) { span[i] = SkAlphaMulQ(src[i], scale); } } break; case kRGB_565_SkColorType: { const uint16_t* src = fDevice->getAddr16(x, y); if (scale == 256) { for (int i = count - 1; i >= 0; --i) { span[i] = SkPixel16ToPixel32(src[i]); } } else { unsigned alpha = this->getPaintAlpha(); for (int i = count - 1; i >= 0; --i) { uint16_t c = src[i]; unsigned r = SkPacked16ToR32(c); unsigned g = SkPacked16ToG32(c); unsigned b = SkPacked16ToB32(c); span[i] = SkPackARGB32( alpha, SkAlphaMul(r, scale), SkAlphaMul(g, scale), SkAlphaMul(b, scale)); } } break; } case kAlpha_8_SkColorType: { const uint8_t* src = fDevice->getAddr8(x, y); if (scale == 256) { for (int i = count - 1; i >= 0; --i) { span[i] = SkPackARGB32(src[i], 0, 0, 0); } } else { for (int i = count - 1; i >= 0; --i) { span[i] = SkPackARGB32(SkAlphaMul(src[i], scale), 0, 0, 0); } } break; } default: SkDEBUGFAIL("colorType not supported as a destination device"); break; } }
static void ToColor_S565(SkColor dst[], const void* src, int width, SkColorTable*) { SkASSERT(width > 0); const uint16_t* s = (const uint16_t*)src; do { uint16_t c = *s++; *dst++ = SkColorSetRGB(SkPacked16ToR32(c), SkPacked16ToG32(c), SkPacked16ToB32(c)); } while (--width != 0); }
static void RGB_565_To_RGB(const uint8_t* in, uint8_t* rgb, int width, const SkPMColor*) { const uint16_t* SK_RESTRICT src = (const uint16_t*)in; for (int i = 0; i < width; ++i) { const uint16_t c = *src++; rgb[0] = SkPacked16ToR32(c); rgb[1] = SkPacked16ToG32(c); rgb[2] = SkPacked16ToB32(c); rgb += 3; } }
void SkTransparentShader::shadeSpan(int x, int y, SkPMColor span[], int count) { unsigned scale = SkAlpha255To256(fAlpha); switch (fDevice->getConfig()) { case SkBitmap::kARGB_8888_Config: if (scale == 256) { SkPMColor* src = fDevice->getAddr32(x, y); if (src != span) { memcpy(span, src, count * sizeof(SkPMColor)); } } else { const SkPMColor* src = fDevice->getAddr32(x, y); for (int i = count - 1; i >= 0; --i) { span[i] = SkAlphaMulQ(src[i], scale); } } break; case SkBitmap::kRGB_565_Config: { const uint16_t* src = fDevice->getAddr16(x, y); if (scale == 256) { for (int i = count - 1; i >= 0; --i) { span[i] = SkPixel16ToPixel32(src[i]); } } else { unsigned alpha = fAlpha; for (int i = count - 1; i >= 0; --i) { uint16_t c = src[i]; unsigned r = SkPacked16ToR32(c); unsigned g = SkPacked16ToG32(c); unsigned b = SkPacked16ToB32(c); span[i] = SkPackARGB32( alpha, SkAlphaMul(r, scale), SkAlphaMul(g, scale), SkAlphaMul(b, scale)); } } break; } case SkBitmap::kARGB_4444_Config: { const uint16_t* src = fDevice->getAddr16(x, y); if (scale == 256) { for (int i = count - 1; i >= 0; --i) { span[i] = SkPixel4444ToPixel32(src[i]); } } else { unsigned scale16 = scale >> 4; for (int i = count - 1; i >= 0; --i) { uint32_t c = SkExpand_4444(src[i]) * scale16; span[i] = SkCompact_8888(c); } } break; } case SkBitmap::kIndex8_Config: SkDEBUGFAIL("index8 not supported as a destination device"); break; case SkBitmap::kA8_Config: { const uint8_t* src = fDevice->getAddr8(x, y); if (scale == 256) { for (int i = count - 1; i >= 0; --i) { span[i] = SkPackARGB32(src[i], 0, 0, 0); } } else { for (int i = count - 1; i >= 0; --i) { span[i] = SkPackARGB32(SkAlphaMul(src[i], scale), 0, 0, 0); } } break; } case SkBitmap::kA1_Config: SkDEBUGFAIL("kA1_Config umimplemented at this time"); break; default: // to avoid warnings break; } }
static void bitmap_to_pdf_pixels(const SkBitmap& bitmap, SkWStream* out) { if (!bitmap.getPixels()) { size_t size = pixel_count(bitmap) * pdf_color_component_count(bitmap.colorType()); fill_stream(out, '\x00', size); return; } SkBitmap copy; const SkBitmap& bm = not4444(bitmap, ©); SkAutoLockPixels autoLockPixels(bm); SkColorType colorType = bm.colorType(); switch (colorType) { case kRGBA_8888_SkColorType: case kBGRA_8888_SkColorType: { SkASSERT(3 == pdf_color_component_count(colorType)); SkAutoTMalloc<uint8_t> scanline(3 * bm.width()); for (int y = 0; y < bm.height(); ++y) { const uint32_t* src = bm.getAddr32(0, y); uint8_t* dst = scanline.get(); for (int x = 0; x < bm.width(); ++x) { uint32_t color = *src++; U8CPU alpha = SkGetA32Component(color, colorType); if (alpha != SK_AlphaTRANSPARENT) { pmcolor_to_rgb24(color, dst, colorType); } else { get_neighbor_avg_color(bm, x, y, dst, colorType); } dst += 3; } out->write(scanline.get(), 3 * bm.width()); } return; } case kRGB_565_SkColorType: { SkASSERT(3 == pdf_color_component_count(colorType)); SkAutoTMalloc<uint8_t> scanline(3 * bm.width()); for (int y = 0; y < bm.height(); ++y) { const uint16_t* src = bm.getAddr16(0, y); uint8_t* dst = scanline.get(); for (int x = 0; x < bm.width(); ++x) { U16CPU color565 = *src++; *dst++ = SkPacked16ToR32(color565); *dst++ = SkPacked16ToG32(color565); *dst++ = SkPacked16ToB32(color565); } out->write(scanline.get(), 3 * bm.width()); } return; } case kAlpha_8_SkColorType: SkASSERT(1 == pdf_color_component_count(colorType)); fill_stream(out, '\x00', pixel_count(bm)); return; case kGray_8_SkColorType: case kIndex_8_SkColorType: SkASSERT(1 == pdf_color_component_count(colorType)); // these two formats need no transformation to serialize. for (int y = 0; y < bm.height(); ++y) { out->write(bm.getAddr8(0, y), bm.width()); } return; case kUnknown_SkColorType: case kARGB_4444_SkColorType: default: SkDEBUGFAIL("unexpected color type"); } }