1b184f7f52b2a94e95aee326a3ca37110d2e43336reed/* 2b184f7f52b2a94e95aee326a3ca37110d2e43336reed * Copyright 2014 Google Inc. 3b184f7f52b2a94e95aee326a3ca37110d2e43336reed * 4b184f7f52b2a94e95aee326a3ca37110d2e43336reed * Use of this source code is governed by a BSD-style license that can be 5b184f7f52b2a94e95aee326a3ca37110d2e43336reed * found in the LICENSE file. 6b184f7f52b2a94e95aee326a3ca37110d2e43336reed */ 7b184f7f52b2a94e95aee326a3ca37110d2e43336reed 8b184f7f52b2a94e95aee326a3ca37110d2e43336reed#include "SkBitmap.h" 9b184f7f52b2a94e95aee326a3ca37110d2e43336reed#include "SkCanvas.h" 10fb0d741d69a30d93b623e14ec34b737ee1673884bsalomon@google.com#include "SkConfig8888.h" 117111d463cee893a479280c7af41757e709e33ef5reed@google.com#include "SkColorPriv.h" 12b184f7f52b2a94e95aee326a3ca37110d2e43336reed#include "SkDither.h" 134b163ed2c22facbe8891616874ae07ba7827d9c9reed@google.com#include "SkMathPriv.h" 1461c49f357a03f68c12c2650ac9915657298352a4commit-bot@chromium.org#include "SkUnPreMultiply.h" 15fb0d741d69a30d93b623e14ec34b737ee1673884bsalomon@google.com 167111d463cee893a479280c7af41757e709e33ef5reed@google.comenum AlphaVerb { 177111d463cee893a479280c7af41757e709e33ef5reed@google.com kNothing_AlphaVerb, 187111d463cee893a479280c7af41757e709e33ef5reed@google.com kPremul_AlphaVerb, 197111d463cee893a479280c7af41757e709e33ef5reed@google.com kUnpremul_AlphaVerb, 207111d463cee893a479280c7af41757e709e33ef5reed@google.com}; 21fb0d741d69a30d93b623e14ec34b737ee1673884bsalomon@google.com 227111d463cee893a479280c7af41757e709e33ef5reed@google.comtemplate <bool doSwapRB, AlphaVerb doAlpha> uint32_t convert32(uint32_t c) { 237111d463cee893a479280c7af41757e709e33ef5reed@google.com if (doSwapRB) { 247111d463cee893a479280c7af41757e709e33ef5reed@google.com c = SkSwizzle_RB(c); 25fb0d741d69a30d93b623e14ec34b737ee1673884bsalomon@google.com } 26be41d38f1c076c9e4dc595a6e1a4eb5ccdbd307bskia.committer@gmail.com 277111d463cee893a479280c7af41757e709e33ef5reed@google.com // Lucky for us, in both RGBA and BGRA, the alpha component is always in the same place, so 287111d463cee893a479280c7af41757e709e33ef5reed@google.com // we can perform premul or unpremul the same way without knowing the swizzles for RGB. 297111d463cee893a479280c7af41757e709e33ef5reed@google.com switch (doAlpha) { 307111d463cee893a479280c7af41757e709e33ef5reed@google.com case kNothing_AlphaVerb: 317111d463cee893a479280c7af41757e709e33ef5reed@google.com // no change 32fb0d741d69a30d93b623e14ec34b737ee1673884bsalomon@google.com break; 337111d463cee893a479280c7af41757e709e33ef5reed@google.com case kPremul_AlphaVerb: 347111d463cee893a479280c7af41757e709e33ef5reed@google.com c = SkPreMultiplyARGB(SkGetPackedA32(c), SkGetPackedR32(c), 357111d463cee893a479280c7af41757e709e33ef5reed@google.com SkGetPackedG32(c), SkGetPackedB32(c)); 36fb0d741d69a30d93b623e14ec34b737ee1673884bsalomon@google.com break; 377111d463cee893a479280c7af41757e709e33ef5reed@google.com case kUnpremul_AlphaVerb: 387111d463cee893a479280c7af41757e709e33ef5reed@google.com c = SkUnPreMultiply::UnPreMultiplyPreservingByteOrder(c); 39fb0d741d69a30d93b623e14ec34b737ee1673884bsalomon@google.com break; 40fb0d741d69a30d93b623e14ec34b737ee1673884bsalomon@google.com } 417111d463cee893a479280c7af41757e709e33ef5reed@google.com return c; 42fb0d741d69a30d93b623e14ec34b737ee1673884bsalomon@google.com} 43fb0d741d69a30d93b623e14ec34b737ee1673884bsalomon@google.com 447111d463cee893a479280c7af41757e709e33ef5reed@google.comtemplate <bool doSwapRB, AlphaVerb doAlpha> 457111d463cee893a479280c7af41757e709e33ef5reed@google.comvoid convert32_row(uint32_t* dst, const uint32_t* src, int count) { 467111d463cee893a479280c7af41757e709e33ef5reed@google.com // This has to be correct if src == dst (but not partial overlap) 477111d463cee893a479280c7af41757e709e33ef5reed@google.com for (int i = 0; i < count; ++i) { 487111d463cee893a479280c7af41757e709e33ef5reed@google.com dst[i] = convert32<doSwapRB, doAlpha>(src[i]); 49fb0d741d69a30d93b623e14ec34b737ee1673884bsalomon@google.com } 50fb0d741d69a30d93b623e14ec34b737ee1673884bsalomon@google.com} 51fb0d741d69a30d93b623e14ec34b737ee1673884bsalomon@google.com 527111d463cee893a479280c7af41757e709e33ef5reed@google.comstatic bool is_32bit_colortype(SkColorType ct) { 537111d463cee893a479280c7af41757e709e33ef5reed@google.com return kRGBA_8888_SkColorType == ct || kBGRA_8888_SkColorType == ct; 547111d463cee893a479280c7af41757e709e33ef5reed@google.com} 55fb0d741d69a30d93b623e14ec34b737ee1673884bsalomon@google.com 567111d463cee893a479280c7af41757e709e33ef5reed@google.comstatic AlphaVerb compute_AlphaVerb(SkAlphaType src, SkAlphaType dst) { 5744977485bdac75c055c3fa638f118874ccd2d22freed SkASSERT(kUnknown_SkAlphaType != src); 5844977485bdac75c055c3fa638f118874ccd2d22freed SkASSERT(kUnknown_SkAlphaType != dst); 59fb0d741d69a30d93b623e14ec34b737ee1673884bsalomon@google.com 607111d463cee893a479280c7af41757e709e33ef5reed@google.com if (kOpaque_SkAlphaType == src || kOpaque_SkAlphaType == dst || src == dst) { 617111d463cee893a479280c7af41757e709e33ef5reed@google.com return kNothing_AlphaVerb; 62e14792d99fc7a1a314ef5e2ca5b269239468355acommit-bot@chromium.org } 637111d463cee893a479280c7af41757e709e33ef5reed@google.com if (kPremul_SkAlphaType == dst) { 647111d463cee893a479280c7af41757e709e33ef5reed@google.com SkASSERT(kUnpremul_SkAlphaType == src); 657111d463cee893a479280c7af41757e709e33ef5reed@google.com return kPremul_AlphaVerb; 667111d463cee893a479280c7af41757e709e33ef5reed@google.com } else { 677111d463cee893a479280c7af41757e709e33ef5reed@google.com SkASSERT(kPremul_SkAlphaType == src); 687111d463cee893a479280c7af41757e709e33ef5reed@google.com SkASSERT(kUnpremul_SkAlphaType == dst); 697111d463cee893a479280c7af41757e709e33ef5reed@google.com return kUnpremul_AlphaVerb; 701121170477302e25ef2a020cf2092aa6b399b3efreed@google.com } 71231f6b81c22001cac4ea87ea412c4d6fd10ffb8acommit-bot@chromium.org} 721121170477302e25ef2a020cf2092aa6b399b3efreed@google.com 737111d463cee893a479280c7af41757e709e33ef5reed@google.comstatic void memcpy32_row(uint32_t* dst, const uint32_t* src, int count) { 747111d463cee893a479280c7af41757e709e33ef5reed@google.com memcpy(dst, src, count * 4); 75231f6b81c22001cac4ea87ea412c4d6fd10ffb8acommit-bot@chromium.org} 761121170477302e25ef2a020cf2092aa6b399b3efreed@google.com 777111d463cee893a479280c7af41757e709e33ef5reed@google.combool SkSrcPixelInfo::convertPixelsTo(SkDstPixelInfo* dst, int width, int height) const { 787111d463cee893a479280c7af41757e709e33ef5reed@google.com if (width <= 0 || height <= 0) { 797111d463cee893a479280c7af41757e709e33ef5reed@google.com return false; 80231f6b81c22001cac4ea87ea412c4d6fd10ffb8acommit-bot@chromium.org } 817111d463cee893a479280c7af41757e709e33ef5reed@google.com 827111d463cee893a479280c7af41757e709e33ef5reed@google.com if (!is_32bit_colortype(fColorType) || !is_32bit_colortype(dst->fColorType)) { 837111d463cee893a479280c7af41757e709e33ef5reed@google.com return false; 847111d463cee893a479280c7af41757e709e33ef5reed@google.com } 857111d463cee893a479280c7af41757e709e33ef5reed@google.com 867111d463cee893a479280c7af41757e709e33ef5reed@google.com void (*proc)(uint32_t* dst, const uint32_t* src, int count); 877111d463cee893a479280c7af41757e709e33ef5reed@google.com AlphaVerb doAlpha = compute_AlphaVerb(fAlphaType, dst->fAlphaType); 887111d463cee893a479280c7af41757e709e33ef5reed@google.com bool doSwapRB = fColorType != dst->fColorType; 897111d463cee893a479280c7af41757e709e33ef5reed@google.com 907111d463cee893a479280c7af41757e709e33ef5reed@google.com switch (doAlpha) { 917111d463cee893a479280c7af41757e709e33ef5reed@google.com case kNothing_AlphaVerb: 927111d463cee893a479280c7af41757e709e33ef5reed@google.com if (doSwapRB) { 937111d463cee893a479280c7af41757e709e33ef5reed@google.com proc = convert32_row<true, kNothing_AlphaVerb>; 947111d463cee893a479280c7af41757e709e33ef5reed@google.com } else { 957111d463cee893a479280c7af41757e709e33ef5reed@google.com if (fPixels == dst->fPixels) { 967111d463cee893a479280c7af41757e709e33ef5reed@google.com return true; 977111d463cee893a479280c7af41757e709e33ef5reed@google.com } 987111d463cee893a479280c7af41757e709e33ef5reed@google.com proc = memcpy32_row; 997111d463cee893a479280c7af41757e709e33ef5reed@google.com } 100231f6b81c22001cac4ea87ea412c4d6fd10ffb8acommit-bot@chromium.org break; 1017111d463cee893a479280c7af41757e709e33ef5reed@google.com case kPremul_AlphaVerb: 1027111d463cee893a479280c7af41757e709e33ef5reed@google.com if (doSwapRB) { 1037111d463cee893a479280c7af41757e709e33ef5reed@google.com proc = convert32_row<true, kPremul_AlphaVerb>; 1047111d463cee893a479280c7af41757e709e33ef5reed@google.com } else { 1057111d463cee893a479280c7af41757e709e33ef5reed@google.com proc = convert32_row<false, kPremul_AlphaVerb>; 1067111d463cee893a479280c7af41757e709e33ef5reed@google.com } 107231f6b81c22001cac4ea87ea412c4d6fd10ffb8acommit-bot@chromium.org break; 1087111d463cee893a479280c7af41757e709e33ef5reed@google.com case kUnpremul_AlphaVerb: 1097111d463cee893a479280c7af41757e709e33ef5reed@google.com if (doSwapRB) { 1107111d463cee893a479280c7af41757e709e33ef5reed@google.com proc = convert32_row<true, kUnpremul_AlphaVerb>; 1117111d463cee893a479280c7af41757e709e33ef5reed@google.com } else { 1127111d463cee893a479280c7af41757e709e33ef5reed@google.com proc = convert32_row<false, kUnpremul_AlphaVerb>; 1137111d463cee893a479280c7af41757e709e33ef5reed@google.com } 114fb0d741d69a30d93b623e14ec34b737ee1673884bsalomon@google.com break; 115fb0d741d69a30d93b623e14ec34b737ee1673884bsalomon@google.com } 116a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com 1177111d463cee893a479280c7af41757e709e33ef5reed@google.com uint32_t* dstP = static_cast<uint32_t*>(dst->fPixels); 1187111d463cee893a479280c7af41757e709e33ef5reed@google.com const uint32_t* srcP = static_cast<const uint32_t*>(fPixels); 1197111d463cee893a479280c7af41757e709e33ef5reed@google.com size_t srcInc = fRowBytes >> 2; 1207111d463cee893a479280c7af41757e709e33ef5reed@google.com size_t dstInc = dst->fRowBytes >> 2; 1217111d463cee893a479280c7af41757e709e33ef5reed@google.com for (int y = 0; y < height; ++y) { 1227111d463cee893a479280c7af41757e709e33ef5reed@google.com proc(dstP, srcP, width); 1237111d463cee893a479280c7af41757e709e33ef5reed@google.com dstP += dstInc; 1247111d463cee893a479280c7af41757e709e33ef5reed@google.com srcP += srcInc; 125a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com } 1267111d463cee893a479280c7af41757e709e33ef5reed@google.com return true; 127a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com} 128b184f7f52b2a94e95aee326a3ca37110d2e43336reed 129b184f7f52b2a94e95aee326a3ca37110d2e43336reedstatic void rect_memcpy(void* dst, size_t dstRB, const void* src, size_t srcRB, size_t bytesPerRow, 130b184f7f52b2a94e95aee326a3ca37110d2e43336reed int rowCount) { 131b184f7f52b2a94e95aee326a3ca37110d2e43336reed SkASSERT(bytesPerRow <= srcRB); 132b184f7f52b2a94e95aee326a3ca37110d2e43336reed SkASSERT(bytesPerRow <= dstRB); 133b184f7f52b2a94e95aee326a3ca37110d2e43336reed for (int i = 0; i < rowCount; ++i) { 134b184f7f52b2a94e95aee326a3ca37110d2e43336reed memcpy(dst, src, bytesPerRow); 135b184f7f52b2a94e95aee326a3ca37110d2e43336reed dst = (char*)dst + dstRB; 136b184f7f52b2a94e95aee326a3ca37110d2e43336reed src = (const char*)src + srcRB; 137b184f7f52b2a94e95aee326a3ca37110d2e43336reed } 138b184f7f52b2a94e95aee326a3ca37110d2e43336reed} 139b184f7f52b2a94e95aee326a3ca37110d2e43336reed 1400c9b1a8d05ea6ec5dfae0ead854304673d94d2c2reedstatic void copy_g8_to_32(void* dst, size_t dstRB, const void* src, size_t srcRB, int w, int h) { 1410c9b1a8d05ea6ec5dfae0ead854304673d94d2c2reed uint32_t* dst32 = (uint32_t*)dst; 1420c9b1a8d05ea6ec5dfae0ead854304673d94d2c2reed const uint8_t* src8 = (const uint8_t*)src; 1430c9b1a8d05ea6ec5dfae0ead854304673d94d2c2reed 1440c9b1a8d05ea6ec5dfae0ead854304673d94d2c2reed for (int y = 0; y < h; ++y) { 1450c9b1a8d05ea6ec5dfae0ead854304673d94d2c2reed for (int x = 0; x < w; ++x) { 1460c9b1a8d05ea6ec5dfae0ead854304673d94d2c2reed dst32[x] = SkPackARGB32(0xFF, src8[x], src8[x], src8[x]); 1470c9b1a8d05ea6ec5dfae0ead854304673d94d2c2reed } 1480c9b1a8d05ea6ec5dfae0ead854304673d94d2c2reed dst32 = (uint32_t*)((char*)dst32 + dstRB); 1490c9b1a8d05ea6ec5dfae0ead854304673d94d2c2reed src8 += srcRB; 1500c9b1a8d05ea6ec5dfae0ead854304673d94d2c2reed } 1510c9b1a8d05ea6ec5dfae0ead854304673d94d2c2reed} 1520c9b1a8d05ea6ec5dfae0ead854304673d94d2c2reed 1530c9b1a8d05ea6ec5dfae0ead854304673d94d2c2reedstatic void copy_32_to_g8(void* dst, size_t dstRB, const void* src, size_t srcRB, 1540c9b1a8d05ea6ec5dfae0ead854304673d94d2c2reed const SkImageInfo& srcInfo) { 1550c9b1a8d05ea6ec5dfae0ead854304673d94d2c2reed uint8_t* dst8 = (uint8_t*)dst; 1560c9b1a8d05ea6ec5dfae0ead854304673d94d2c2reed const uint32_t* src32 = (const uint32_t*)src; 1570c9b1a8d05ea6ec5dfae0ead854304673d94d2c2reed 1580c9b1a8d05ea6ec5dfae0ead854304673d94d2c2reed const int w = srcInfo.width(); 1590c9b1a8d05ea6ec5dfae0ead854304673d94d2c2reed const int h = srcInfo.height(); 1600c9b1a8d05ea6ec5dfae0ead854304673d94d2c2reed const bool isBGRA = (kBGRA_8888_SkColorType == srcInfo.colorType()); 1610c9b1a8d05ea6ec5dfae0ead854304673d94d2c2reed 1620c9b1a8d05ea6ec5dfae0ead854304673d94d2c2reed for (int y = 0; y < h; ++y) { 1630c9b1a8d05ea6ec5dfae0ead854304673d94d2c2reed if (isBGRA) { 1640c9b1a8d05ea6ec5dfae0ead854304673d94d2c2reed // BGRA 1650c9b1a8d05ea6ec5dfae0ead854304673d94d2c2reed for (int x = 0; x < w; ++x) { 1660c9b1a8d05ea6ec5dfae0ead854304673d94d2c2reed uint32_t s = src32[x]; 1670c9b1a8d05ea6ec5dfae0ead854304673d94d2c2reed dst8[x] = SkComputeLuminance((s >> 16) & 0xFF, (s >> 8) & 0xFF, s & 0xFF); 1680c9b1a8d05ea6ec5dfae0ead854304673d94d2c2reed } 1690c9b1a8d05ea6ec5dfae0ead854304673d94d2c2reed } else { 1700c9b1a8d05ea6ec5dfae0ead854304673d94d2c2reed // RGBA 1710c9b1a8d05ea6ec5dfae0ead854304673d94d2c2reed for (int x = 0; x < w; ++x) { 1720c9b1a8d05ea6ec5dfae0ead854304673d94d2c2reed uint32_t s = src32[x]; 1730c9b1a8d05ea6ec5dfae0ead854304673d94d2c2reed dst8[x] = SkComputeLuminance(s & 0xFF, (s >> 8) & 0xFF, (s >> 16) & 0xFF); 1740c9b1a8d05ea6ec5dfae0ead854304673d94d2c2reed } 1750c9b1a8d05ea6ec5dfae0ead854304673d94d2c2reed } 1760c9b1a8d05ea6ec5dfae0ead854304673d94d2c2reed src32 = (const uint32_t*)((const char*)src32 + srcRB); 1770c9b1a8d05ea6ec5dfae0ead854304673d94d2c2reed dst8 += dstRB; 1780c9b1a8d05ea6ec5dfae0ead854304673d94d2c2reed } 1790c9b1a8d05ea6ec5dfae0ead854304673d94d2c2reed} 1800c9b1a8d05ea6ec5dfae0ead854304673d94d2c2reed 181b184f7f52b2a94e95aee326a3ca37110d2e43336reedbool SkPixelInfo::CopyPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRB, 182b184f7f52b2a94e95aee326a3ca37110d2e43336reed const SkImageInfo& srcInfo, const void* srcPixels, size_t srcRB, 183b184f7f52b2a94e95aee326a3ca37110d2e43336reed SkColorTable* ctable) { 184b184f7f52b2a94e95aee326a3ca37110d2e43336reed if (srcInfo.dimensions() != dstInfo.dimensions()) { 185b184f7f52b2a94e95aee326a3ca37110d2e43336reed return false; 186b184f7f52b2a94e95aee326a3ca37110d2e43336reed } 187b184f7f52b2a94e95aee326a3ca37110d2e43336reed 188b184f7f52b2a94e95aee326a3ca37110d2e43336reed const int width = srcInfo.width(); 189b184f7f52b2a94e95aee326a3ca37110d2e43336reed const int height = srcInfo.height(); 190b184f7f52b2a94e95aee326a3ca37110d2e43336reed 191b184f7f52b2a94e95aee326a3ca37110d2e43336reed // Handle fancy alpha swizzling if both are ARGB32 192b184f7f52b2a94e95aee326a3ca37110d2e43336reed if (4 == srcInfo.bytesPerPixel() && 4 == dstInfo.bytesPerPixel()) { 193b184f7f52b2a94e95aee326a3ca37110d2e43336reed SkDstPixelInfo dstPI; 194b184f7f52b2a94e95aee326a3ca37110d2e43336reed dstPI.fColorType = dstInfo.colorType(); 195b184f7f52b2a94e95aee326a3ca37110d2e43336reed dstPI.fAlphaType = dstInfo.alphaType(); 196b184f7f52b2a94e95aee326a3ca37110d2e43336reed dstPI.fPixels = dstPixels; 197b184f7f52b2a94e95aee326a3ca37110d2e43336reed dstPI.fRowBytes = dstRB; 198775b8199a214af57c3ea7969e9d456f5f3eb137fmtklein 199b184f7f52b2a94e95aee326a3ca37110d2e43336reed SkSrcPixelInfo srcPI; 200b184f7f52b2a94e95aee326a3ca37110d2e43336reed srcPI.fColorType = srcInfo.colorType(); 201b184f7f52b2a94e95aee326a3ca37110d2e43336reed srcPI.fAlphaType = srcInfo.alphaType(); 202b184f7f52b2a94e95aee326a3ca37110d2e43336reed srcPI.fPixels = srcPixels; 203b184f7f52b2a94e95aee326a3ca37110d2e43336reed srcPI.fRowBytes = srcRB; 204775b8199a214af57c3ea7969e9d456f5f3eb137fmtklein 205b184f7f52b2a94e95aee326a3ca37110d2e43336reed return srcPI.convertPixelsTo(&dstPI, width, height); 206b184f7f52b2a94e95aee326a3ca37110d2e43336reed } 207b184f7f52b2a94e95aee326a3ca37110d2e43336reed 208b184f7f52b2a94e95aee326a3ca37110d2e43336reed // If they agree on colorType and the alphaTypes are compatible, then we just memcpy. 209b184f7f52b2a94e95aee326a3ca37110d2e43336reed // Note: we've already taken care of 32bit colortypes above. 210b184f7f52b2a94e95aee326a3ca37110d2e43336reed if (srcInfo.colorType() == dstInfo.colorType()) { 211b184f7f52b2a94e95aee326a3ca37110d2e43336reed switch (srcInfo.colorType()) { 212b184f7f52b2a94e95aee326a3ca37110d2e43336reed case kRGB_565_SkColorType: 213b184f7f52b2a94e95aee326a3ca37110d2e43336reed case kAlpha_8_SkColorType: 2140c9b1a8d05ea6ec5dfae0ead854304673d94d2c2reed case kGray_8_SkColorType: 215b184f7f52b2a94e95aee326a3ca37110d2e43336reed break; 216b184f7f52b2a94e95aee326a3ca37110d2e43336reed case kIndex_8_SkColorType: 217b184f7f52b2a94e95aee326a3ca37110d2e43336reed case kARGB_4444_SkColorType: 218b184f7f52b2a94e95aee326a3ca37110d2e43336reed if (srcInfo.alphaType() != dstInfo.alphaType()) { 219b184f7f52b2a94e95aee326a3ca37110d2e43336reed return false; 220b184f7f52b2a94e95aee326a3ca37110d2e43336reed } 221b184f7f52b2a94e95aee326a3ca37110d2e43336reed break; 222b184f7f52b2a94e95aee326a3ca37110d2e43336reed default: 223b184f7f52b2a94e95aee326a3ca37110d2e43336reed return false; 224b184f7f52b2a94e95aee326a3ca37110d2e43336reed } 225b184f7f52b2a94e95aee326a3ca37110d2e43336reed rect_memcpy(dstPixels, dstRB, srcPixels, srcRB, width * srcInfo.bytesPerPixel(), height); 226b184f7f52b2a94e95aee326a3ca37110d2e43336reed return true; 227b184f7f52b2a94e95aee326a3ca37110d2e43336reed } 228b184f7f52b2a94e95aee326a3ca37110d2e43336reed 229b184f7f52b2a94e95aee326a3ca37110d2e43336reed /* 230b184f7f52b2a94e95aee326a3ca37110d2e43336reed * Begin section where we try to change colorTypes along the way. Not all combinations 231b184f7f52b2a94e95aee326a3ca37110d2e43336reed * are supported. 232b184f7f52b2a94e95aee326a3ca37110d2e43336reed */ 233b184f7f52b2a94e95aee326a3ca37110d2e43336reed 2340c9b1a8d05ea6ec5dfae0ead854304673d94d2c2reed if (kGray_8_SkColorType == srcInfo.colorType() && 4 == dstInfo.bytesPerPixel()) { 2350c9b1a8d05ea6ec5dfae0ead854304673d94d2c2reed copy_g8_to_32(dstPixels, dstRB, srcPixels, srcRB, width, height); 2360c9b1a8d05ea6ec5dfae0ead854304673d94d2c2reed return true; 2370c9b1a8d05ea6ec5dfae0ead854304673d94d2c2reed } 2380c9b1a8d05ea6ec5dfae0ead854304673d94d2c2reed if (kGray_8_SkColorType == dstInfo.colorType() && 4 == srcInfo.bytesPerPixel()) { 2390c9b1a8d05ea6ec5dfae0ead854304673d94d2c2reed copy_32_to_g8(dstPixels, dstRB, srcPixels, srcRB, srcInfo); 2400c9b1a8d05ea6ec5dfae0ead854304673d94d2c2reed return true; 2410c9b1a8d05ea6ec5dfae0ead854304673d94d2c2reed } 2420c9b1a8d05ea6ec5dfae0ead854304673d94d2c2reed 243b184f7f52b2a94e95aee326a3ca37110d2e43336reed // Can no longer draw directly into 4444, but we can manually whack it for a few combinations 244b184f7f52b2a94e95aee326a3ca37110d2e43336reed if (kARGB_4444_SkColorType == dstInfo.colorType() && 245b184f7f52b2a94e95aee326a3ca37110d2e43336reed (kN32_SkColorType == srcInfo.colorType() || kIndex_8_SkColorType == srcInfo.colorType())) { 246b184f7f52b2a94e95aee326a3ca37110d2e43336reed if (srcInfo.alphaType() == kUnpremul_SkAlphaType) { 247b184f7f52b2a94e95aee326a3ca37110d2e43336reed // Our method for converting to 4444 assumes premultiplied. 248b184f7f52b2a94e95aee326a3ca37110d2e43336reed return false; 249b184f7f52b2a94e95aee326a3ca37110d2e43336reed } 250775b8199a214af57c3ea7969e9d456f5f3eb137fmtklein 251b184f7f52b2a94e95aee326a3ca37110d2e43336reed const SkPMColor* table = NULL; 252b184f7f52b2a94e95aee326a3ca37110d2e43336reed if (kIndex_8_SkColorType == srcInfo.colorType()) { 253b184f7f52b2a94e95aee326a3ca37110d2e43336reed if (NULL == ctable) { 254b184f7f52b2a94e95aee326a3ca37110d2e43336reed return false; 255b184f7f52b2a94e95aee326a3ca37110d2e43336reed } 256775b8199a214af57c3ea7969e9d456f5f3eb137fmtklein table = ctable->readColors(); 257b184f7f52b2a94e95aee326a3ca37110d2e43336reed } 258b184f7f52b2a94e95aee326a3ca37110d2e43336reed 259b184f7f52b2a94e95aee326a3ca37110d2e43336reed for (int y = 0; y < height; ++y) { 260b184f7f52b2a94e95aee326a3ca37110d2e43336reed DITHER_4444_SCAN(y); 261b184f7f52b2a94e95aee326a3ca37110d2e43336reed SkPMColor16* SK_RESTRICT dstRow = (SkPMColor16*)dstPixels; 262b184f7f52b2a94e95aee326a3ca37110d2e43336reed if (table) { 263b184f7f52b2a94e95aee326a3ca37110d2e43336reed const uint8_t* SK_RESTRICT srcRow = (const uint8_t*)srcPixels; 264b184f7f52b2a94e95aee326a3ca37110d2e43336reed for (int x = 0; x < width; ++x) { 265b184f7f52b2a94e95aee326a3ca37110d2e43336reed dstRow[x] = SkDitherARGB32To4444(table[srcRow[x]], DITHER_VALUE(x)); 266b184f7f52b2a94e95aee326a3ca37110d2e43336reed } 267b184f7f52b2a94e95aee326a3ca37110d2e43336reed } else { 268b184f7f52b2a94e95aee326a3ca37110d2e43336reed const SkPMColor* SK_RESTRICT srcRow = (const SkPMColor*)srcPixels; 269b184f7f52b2a94e95aee326a3ca37110d2e43336reed for (int x = 0; x < width; ++x) { 270b184f7f52b2a94e95aee326a3ca37110d2e43336reed dstRow[x] = SkDitherARGB32To4444(srcRow[x], DITHER_VALUE(x)); 271b184f7f52b2a94e95aee326a3ca37110d2e43336reed } 272b184f7f52b2a94e95aee326a3ca37110d2e43336reed } 273b184f7f52b2a94e95aee326a3ca37110d2e43336reed dstPixels = (char*)dstPixels + dstRB; 274b184f7f52b2a94e95aee326a3ca37110d2e43336reed srcPixels = (const char*)srcPixels + srcRB; 275b184f7f52b2a94e95aee326a3ca37110d2e43336reed } 276b184f7f52b2a94e95aee326a3ca37110d2e43336reed return true; 277b184f7f52b2a94e95aee326a3ca37110d2e43336reed } 278b184f7f52b2a94e95aee326a3ca37110d2e43336reed 279b184f7f52b2a94e95aee326a3ca37110d2e43336reed if (dstInfo.alphaType() == kUnpremul_SkAlphaType) { 280b184f7f52b2a94e95aee326a3ca37110d2e43336reed // We do not support drawing to unpremultiplied bitmaps. 281b184f7f52b2a94e95aee326a3ca37110d2e43336reed return false; 282b184f7f52b2a94e95aee326a3ca37110d2e43336reed } 283b184f7f52b2a94e95aee326a3ca37110d2e43336reed 284b184f7f52b2a94e95aee326a3ca37110d2e43336reed // Final fall-back, draw with a canvas 285b184f7f52b2a94e95aee326a3ca37110d2e43336reed // 286b184f7f52b2a94e95aee326a3ca37110d2e43336reed // Always clear the dest in case one of the blitters accesses it 287b184f7f52b2a94e95aee326a3ca37110d2e43336reed // TODO: switch the allocation of tmpDst to call sk_calloc_throw 288b184f7f52b2a94e95aee326a3ca37110d2e43336reed { 289b184f7f52b2a94e95aee326a3ca37110d2e43336reed SkBitmap bm; 290b184f7f52b2a94e95aee326a3ca37110d2e43336reed if (!bm.installPixels(srcInfo, const_cast<void*>(srcPixels), srcRB, ctable, NULL, NULL)) { 291b184f7f52b2a94e95aee326a3ca37110d2e43336reed return false; 292b184f7f52b2a94e95aee326a3ca37110d2e43336reed } 293b184f7f52b2a94e95aee326a3ca37110d2e43336reed SkAutoTUnref<SkCanvas> canvas(SkCanvas::NewRasterDirect(dstInfo, dstPixels, dstRB)); 294b184f7f52b2a94e95aee326a3ca37110d2e43336reed if (NULL == canvas.get()) { 295b184f7f52b2a94e95aee326a3ca37110d2e43336reed return false; 296b184f7f52b2a94e95aee326a3ca37110d2e43336reed } 297b184f7f52b2a94e95aee326a3ca37110d2e43336reed 298b184f7f52b2a94e95aee326a3ca37110d2e43336reed SkPaint paint; 299b184f7f52b2a94e95aee326a3ca37110d2e43336reed paint.setDither(true); 300b184f7f52b2a94e95aee326a3ca37110d2e43336reed 301b184f7f52b2a94e95aee326a3ca37110d2e43336reed canvas->clear(0); 302b184f7f52b2a94e95aee326a3ca37110d2e43336reed canvas->drawBitmap(bm, 0, 0, &paint); 303b184f7f52b2a94e95aee326a3ca37110d2e43336reed return true; 304b184f7f52b2a94e95aee326a3ca37110d2e43336reed } 305b184f7f52b2a94e95aee326a3ca37110d2e43336reed} 306b184f7f52b2a94e95aee326a3ca37110d2e43336reed 307