Android SetPixels
android/platform_frameworks_base/core/jni/android/graphics/Bitmap.cpp
SetPixels()
bool GraphicsJNI::SetPixels(JNIEnv* env, jintArray srcColors, int srcOffset, int srcStride, int x, int y, int width, int height, const SkBitmap& dstBitmap) { SkAutoLockPixels alp(dstBitmap); void* dst = dstBitmap.getPixels(); FromColorProc proc = ChooseFromColorProc(dstBitmap.config()); if (NULL == dst || NULL == proc) { return false; } const jint* array = env->GetIntArrayElements(srcColors, NULL); const SkColor* src = (const SkColor*)array + srcOffset; // reset to to actual choice from caller dst = dstBitmap.getAddr(x, y); // now copy/convert each scanline for (int y = 0; y < height; y++) { proc(dst, src, width, x, y); src += srcStride; dst = (char*)dst + dstBitmap.rowBytes(); } env->ReleaseIntArrayElements(srcColors, const_cast<jint*>(array), JNI_ABORT); return true; }
↓
FromColor_D32()
static void FromColor_D32(void* dst, const SkColor src[], int width, int, int) { SkPMColor* d = (SkPMColor*)dst; for (int i = 0; i < width; i++) { *d++ = SkPreMultiplyColor(*src++); } }
↓
android/platform_external_skia/src/core/SkColor.cpp
SkPreMultiplyARGB()
aが0x00の場合, r=0x00,g=0x00,b=0x00
aが0x01〜0xFEの場合, r=r*a, g=g*a, b=b*a
aが0xFFの場合, r=r, g=g, b=b
αブレンディングをしている。
SkPMColor SkPreMultiplyARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b) { if (a != 255) { r = SkMulDiv255Round(r, a); g = SkMulDiv255Round(g, a); b = SkMulDiv255Round(b, a); } return SkPackARGB32(a, r, g, b); }
↓
android/platform_external_skia/include/core/SkMath.h
/** Return a*b/255, rounding any fractional bits. Only valid if both a and b are 0..255 */ static inline U8CPU SkMulDiv255Round(U8CPU a, U8CPU b) { SkASSERT((uint8_t)a == a); SkASSERT((uint8_t)b == b); unsigned prod = SkMulS16(a, b) + 128; return (prod + (prod >> 8)) >> 8; }