1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com 28a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/* 3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2008 The Android Open Source Project 48a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com * 5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be 6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file. 78a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 88a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com 108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkBitmap.h" 118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkColorPriv.h" 128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkDither.h" 138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkFlattenable.h" 146e3e42296b0d7a93325146d9c9a7e23ef90760fecommit-bot@chromium.org#include "SkImagePriv.h" 158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkMallocPixelRef.h" 168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkMask.h" 178b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org#include "SkReadBuffer.h" 188b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org#include "SkWriteBuffer.h" 198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkPixelRef.h" 208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkThread.h" 21112706d4c566e283890322bb246b4b86d59837e1vandebo@chromium.org#include "SkUnPreMultiply.h" 228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkUtils.h" 23c0b7e10c6a68f59e1653e6c18e6bc954b3c3f0cfcommit-bot@chromium.org#include "SkValidationUtils.h" 248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkPackBits.h" 258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include <new> 268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2761e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.orgstatic bool reset_return_false(SkBitmap* bm) { 2861e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org bm->reset(); 2961e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org return false; 3061e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org} 3161e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org 328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkBitmap::SkBitmap() { 334516f4786f5dda1b86a8f825b9e8e910d9c2363creed@android.com sk_bzero(this, sizeof(*this)); 348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkBitmap::SkBitmap(const SkBitmap& src) { 378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDEBUGCODE(src.validate();) 384516f4786f5dda1b86a8f825b9e8e910d9c2363creed@android.com sk_bzero(this, sizeof(*this)); 398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *this = src; 408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDEBUGCODE(this->validate();) 418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkBitmap::~SkBitmap() { 448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDEBUGCODE(this->validate();) 458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->freePixels(); 468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkBitmap& SkBitmap::operator=(const SkBitmap& src) { 498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (this != &src) { 508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->freePixels(); 518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com memcpy(this, &src, sizeof(src)); 528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // inc src reference counts 5483f7bc30af2837c985934e14597caec332899a1creed@android.com SkSafeRef(src.fPixelRef); 558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // we reset our locks if we get blown away 578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fPixelLockCount = 0; 58f9ab99aaade8c451c0e9309b4c61a448373019e3weita@google.com 595f62ed74342e44cb1b9671ffdac47c6a81416136reed@google.com if (fPixelRef) { 608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // ignore the values from the memcpy 618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fPixels = NULL; 628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fColorTable = NULL; 63586f48cfa8b1fa7b29d8ee8d0a028489a33866debsalomon@google.com // Note that what to for genID is somewhat arbitrary. We have no 64586f48cfa8b1fa7b29d8ee8d0a028489a33866debsalomon@google.com // way to track changes to raw pixels across multiple SkBitmaps. 65586f48cfa8b1fa7b29d8ee8d0a028489a33866debsalomon@google.com // Would benefit from an SkRawPixelRef type created by 66586f48cfa8b1fa7b29d8ee8d0a028489a33866debsalomon@google.com // setPixels. 67586f48cfa8b1fa7b29d8ee8d0a028489a33866debsalomon@google.com // Just leave the memcpy'ed one but they'll get out of sync 68586f48cfa8b1fa7b29d8ee8d0a028489a33866debsalomon@google.com // as soon either is modified. 698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDEBUGCODE(this->validate();) 738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return *this; 748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkBitmap::swap(SkBitmap& other) { 77586f48cfa8b1fa7b29d8ee8d0a028489a33866debsalomon@google.com SkTSwap(fColorTable, other.fColorTable); 78586f48cfa8b1fa7b29d8ee8d0a028489a33866debsalomon@google.com SkTSwap(fPixelRef, other.fPixelRef); 79672588b684d484dce6ae251e9e163e4a46924322reed@google.com SkTSwap(fPixelRefOrigin, other.fPixelRefOrigin); 80586f48cfa8b1fa7b29d8ee8d0a028489a33866debsalomon@google.com SkTSwap(fPixelLockCount, other.fPixelLockCount); 81586f48cfa8b1fa7b29d8ee8d0a028489a33866debsalomon@google.com SkTSwap(fPixels, other.fPixels); 8261e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org SkTSwap(fInfo, other.fInfo); 83586f48cfa8b1fa7b29d8ee8d0a028489a33866debsalomon@google.com SkTSwap(fRowBytes, other.fRowBytes); 84586f48cfa8b1fa7b29d8ee8d0a028489a33866debsalomon@google.com SkTSwap(fFlags, other.fFlags); 858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDEBUGCODE(this->validate();) 878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkBitmap::reset() { 908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->freePixels(); 914516f4786f5dda1b86a8f825b9e8e910d9c2363creed@android.com sk_bzero(this, sizeof(*this)); 928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9486b2e43a33c486a0b150aa14fadf7af8323a11f5reed@google.comvoid SkBitmap::getBounds(SkRect* bounds) const { 9586b2e43a33c486a0b150aa14fadf7af8323a11f5reed@google.com SkASSERT(bounds); 9686b2e43a33c486a0b150aa14fadf7af8323a11f5reed@google.com bounds->set(0, 0, 97e5ea500d4714a7d84de2bf913e81be3b65d2de68reed SkIntToScalar(fInfo.width()), SkIntToScalar(fInfo.height())); 9886b2e43a33c486a0b150aa14fadf7af8323a11f5reed@google.com} 9986b2e43a33c486a0b150aa14fadf7af8323a11f5reed@google.com 10080e1459c32f5f3acbc688ae4f0e046aa283e8c3areed@google.comvoid SkBitmap::getBounds(SkIRect* bounds) const { 10180e1459c32f5f3acbc688ae4f0e046aa283e8c3areed@google.com SkASSERT(bounds); 102e5ea500d4714a7d84de2bf913e81be3b65d2de68reed bounds->set(0, 0, fInfo.width(), fInfo.height()); 10380e1459c32f5f3acbc688ae4f0e046aa283e8c3areed@google.com} 10480e1459c32f5f3acbc688ae4f0e046aa283e8c3areed@google.com 10586b2e43a33c486a0b150aa14fadf7af8323a11f5reed@google.com/////////////////////////////////////////////////////////////////////////////// 10686b2e43a33c486a0b150aa14fadf7af8323a11f5reed@google.com 107e5ea500d4714a7d84de2bf913e81be3b65d2de68reedbool SkBitmap::setInfo(const SkImageInfo& info, size_t rowBytes) { 108e5ea500d4714a7d84de2bf913e81be3b65d2de68reed SkAlphaType newAT = info.alphaType(); 109e5ea500d4714a7d84de2bf913e81be3b65d2de68reed if (!SkColorTypeValidateAlphaType(info.colorType(), info.alphaType(), &newAT)) { 110d5414e5efe0a6a0bce0b5499e2358e2be4cb9b61commit-bot@chromium.org return reset_return_false(this); 111d5414e5efe0a6a0bce0b5499e2358e2be4cb9b61commit-bot@chromium.org } 112e5ea500d4714a7d84de2bf913e81be3b65d2de68reed // don't look at info.alphaType(), since newAT is the real value... 11302d6f546161e2c98d69066373cec3f54f3c46252skia.committer@gmail.com 11461e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org // require that rowBytes fit in 31bits 11561e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org int64_t mrb = info.minRowBytes64(); 11661e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org if ((int32_t)mrb != mrb) { 11761e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org return reset_return_false(this); 1188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 11961e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org if ((int64_t)rowBytes != (int32_t)rowBytes) { 12061e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org return reset_return_false(this); 121383a697692cf46951fd451f6f4c3d03634a6a1cbreed@google.com } 122383a697692cf46951fd451f6f4c3d03634a6a1cbreed@google.com 12361e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org if (info.width() < 0 || info.height() < 0) { 12461e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org return reset_return_false(this); 125169a0ed50a5e451711c341795572e7177a540a24mike@reedtribe.org } 1268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 12761e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org if (kUnknown_SkColorType == info.colorType()) { 12861e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org rowBytes = 0; 12961e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org } else if (0 == rowBytes) { 13061e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org rowBytes = (size_t)mrb; 131f0aed97aec3fa1c7f6460d8d6327358f3dcbabe6reed } else if (!info.validRowBytes(rowBytes)) { 13261e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org return reset_return_false(this); 13361e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org } 1341195a28892d37ae9632e81e1bc2407cf644522d2mike@reedtribe.org 13561e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org this->freePixels(); 1361195a28892d37ae9632e81e1bc2407cf644522d2mike@reedtribe.org 137e5ea500d4714a7d84de2bf913e81be3b65d2de68reed fInfo = info.makeAlphaType(newAT); 13861e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org fRowBytes = SkToU32(rowBytes); 139383a697692cf46951fd451f6f4c3d03634a6a1cbreed@google.com return true; 140383a697692cf46951fd451f6f4c3d03634a6a1cbreed@google.com} 141383a697692cf46951fd451f6f4c3d03634a6a1cbreed@google.com 142e5ea500d4714a7d84de2bf913e81be3b65d2de68reedbool SkBitmap::setAlphaType(SkAlphaType newAlphaType) { 143e5ea500d4714a7d84de2bf913e81be3b65d2de68reed if (!SkColorTypeValidateAlphaType(fInfo.colorType(), newAlphaType, &newAlphaType)) { 144383a697692cf46951fd451f6f4c3d03634a6a1cbreed@google.com return false; 145383a697692cf46951fd451f6f4c3d03634a6a1cbreed@google.com } 146e5ea500d4714a7d84de2bf913e81be3b65d2de68reed if (fInfo.alphaType() != newAlphaType) { 147e5ea500d4714a7d84de2bf913e81be3b65d2de68reed fInfo = fInfo.makeAlphaType(newAlphaType); 1480e8d0d6cdc2e02946b099006d0a47e60764905e5commit-bot@chromium.org if (fPixelRef) { 149e5ea500d4714a7d84de2bf913e81be3b65d2de68reed fPixelRef->changeAlphaType(newAlphaType); 1500e8d0d6cdc2e02946b099006d0a47e60764905e5commit-bot@chromium.org } 1510e8d0d6cdc2e02946b099006d0a47e60764905e5commit-bot@chromium.org } 152383a697692cf46951fd451f6f4c3d03634a6a1cbreed@google.com return true; 1538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkBitmap::updatePixelsFromRef() const { 15649f085dddff10473b6ebf832a974288300224e60bsalomon if (fPixelRef) { 1578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (fPixelLockCount > 0) { 158ff0da4ff483ba7b4468b862949ffb3de505cba14reed@google.com SkASSERT(fPixelRef->isLocked()); 159f9ab99aaade8c451c0e9309b4c61a448373019e3weita@google.com 1608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void* p = fPixelRef->pixels(); 16149f085dddff10473b6ebf832a974288300224e60bsalomon if (p) { 162672588b684d484dce6ae251e9e163e4a46924322reed@google.com p = (char*)p 163303c4758ec7062daf1531c3642e9c7887423ef1breed@google.com + fPixelRefOrigin.fY * fRowBytes 16461e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org + fPixelRefOrigin.fX * fInfo.bytesPerPixel(); 1658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fPixels = p; 1675f62ed74342e44cb1b9671ffdac47c6a81416136reed@google.com fColorTable = fPixelRef->colorTable(); 1688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 1698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(0 == fPixelLockCount); 1708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fPixels = NULL; 1715f62ed74342e44cb1b9671ffdac47c6a81416136reed@google.com fColorTable = NULL; 1728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 176672588b684d484dce6ae251e9e163e4a46924322reed@google.comSkPixelRef* SkBitmap::setPixelRef(SkPixelRef* pr, int dx, int dy) { 177dcea5300dc028b5ea210d778b9e34a7504fee6d2reed@google.com#ifdef SK_DEBUG 178672588b684d484dce6ae251e9e163e4a46924322reed@google.com if (pr) { 179466f5f3e44e703ca58b43ac1c4ac3bfa0e1ff024commit-bot@chromium.org if (kUnknown_SkColorType != fInfo.colorType()) { 180dcea5300dc028b5ea210d778b9e34a7504fee6d2reed@google.com const SkImageInfo& prInfo = pr->info(); 181e5ea500d4714a7d84de2bf913e81be3b65d2de68reed SkASSERT(fInfo.width() <= prInfo.width()); 182e5ea500d4714a7d84de2bf913e81be3b65d2de68reed SkASSERT(fInfo.height() <= prInfo.height()); 183e5ea500d4714a7d84de2bf913e81be3b65d2de68reed SkASSERT(fInfo.colorType() == prInfo.colorType()); 184e5ea500d4714a7d84de2bf913e81be3b65d2de68reed switch (prInfo.alphaType()) { 185dcea5300dc028b5ea210d778b9e34a7504fee6d2reed@google.com case kIgnore_SkAlphaType: 186e5ea500d4714a7d84de2bf913e81be3b65d2de68reed SkASSERT(fInfo.alphaType() == kIgnore_SkAlphaType); 187dcea5300dc028b5ea210d778b9e34a7504fee6d2reed@google.com break; 188dcea5300dc028b5ea210d778b9e34a7504fee6d2reed@google.com case kOpaque_SkAlphaType: 189dcea5300dc028b5ea210d778b9e34a7504fee6d2reed@google.com case kPremul_SkAlphaType: 190e5ea500d4714a7d84de2bf913e81be3b65d2de68reed SkASSERT(fInfo.alphaType() == kOpaque_SkAlphaType || 191e5ea500d4714a7d84de2bf913e81be3b65d2de68reed fInfo.alphaType() == kPremul_SkAlphaType); 192dcea5300dc028b5ea210d778b9e34a7504fee6d2reed@google.com break; 193dcea5300dc028b5ea210d778b9e34a7504fee6d2reed@google.com case kUnpremul_SkAlphaType: 194e5ea500d4714a7d84de2bf913e81be3b65d2de68reed SkASSERT(fInfo.alphaType() == kOpaque_SkAlphaType || 195e5ea500d4714a7d84de2bf913e81be3b65d2de68reed fInfo.alphaType() == kUnpremul_SkAlphaType); 196dcea5300dc028b5ea210d778b9e34a7504fee6d2reed@google.com break; 197dcea5300dc028b5ea210d778b9e34a7504fee6d2reed@google.com } 198dcea5300dc028b5ea210d778b9e34a7504fee6d2reed@google.com } 199dcea5300dc028b5ea210d778b9e34a7504fee6d2reed@google.com } 200dcea5300dc028b5ea210d778b9e34a7504fee6d2reed@google.com#endif 2018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 202672588b684d484dce6ae251e9e163e4a46924322reed@google.com if (pr) { 203672588b684d484dce6ae251e9e163e4a46924322reed@google.com const SkImageInfo& info = pr->info(); 204e5ea500d4714a7d84de2bf913e81be3b65d2de68reed fPixelRefOrigin.set(SkPin32(dx, 0, info.width()), SkPin32(dy, 0, info.height())); 205672588b684d484dce6ae251e9e163e4a46924322reed@google.com } else { 206672588b684d484dce6ae251e9e163e4a46924322reed@google.com // ignore dx,dy if there is no pixelref 207672588b684d484dce6ae251e9e163e4a46924322reed@google.com fPixelRefOrigin.setZero(); 208672588b684d484dce6ae251e9e163e4a46924322reed@google.com } 209672588b684d484dce6ae251e9e163e4a46924322reed@google.com 210672588b684d484dce6ae251e9e163e4a46924322reed@google.com if (fPixelRef != pr) { 2110eb02a6abbe2964e4955863b0f82aff6a8661801piotaixr this->freePixels(); 2120eb02a6abbe2964e4955863b0f82aff6a8661801piotaixr SkASSERT(NULL == fPixelRef); 213f9ab99aaade8c451c0e9309b4c61a448373019e3weita@google.com 2140eb02a6abbe2964e4955863b0f82aff6a8661801piotaixr SkSafeRef(pr); 2150eb02a6abbe2964e4955863b0f82aff6a8661801piotaixr fPixelRef = pr; 2168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->updatePixelsFromRef(); 2178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDEBUGCODE(this->validate();) 2208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return pr; 2218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkBitmap::lockPixels() const { 22449f085dddff10473b6ebf832a974288300224e60bsalomon if (fPixelRef && 0 == sk_atomic_inc(&fPixelLockCount)) { 2258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fPixelRef->lockPixels(); 2268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->updatePixelsFromRef(); 2278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDEBUGCODE(this->validate();) 2298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkBitmap::unlockPixels() const { 2328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(NULL == fPixelRef || fPixelLockCount > 0); 2338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 23449f085dddff10473b6ebf832a974288300224e60bsalomon if (fPixelRef && 1 == sk_atomic_dec(&fPixelLockCount)) { 2358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fPixelRef->unlockPixels(); 2368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->updatePixelsFromRef(); 2378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDEBUGCODE(this->validate();) 2398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2419c49bc3e643c435677727c1c0904c4a7cb7a6907reed@google.combool SkBitmap::lockPixelsAreWritable() const { 242c84b8335ee4fd864c30a4703afc643cf4b5010d9djsollen@google.com return (fPixelRef) ? fPixelRef->lockPixelsAreWritable() : false; 2439c49bc3e643c435677727c1c0904c4a7cb7a6907reed@google.com} 2449c49bc3e643c435677727c1c0904c4a7cb7a6907reed@google.com 2458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkBitmap::setPixels(void* p, SkColorTable* ctable) { 2468e1034e9ca0e3009f65125239e21b06ec51a55a6reed@google.com if (NULL == p) { 247672588b684d484dce6ae251e9e163e4a46924322reed@google.com this->setPixelRef(NULL); 2488e1034e9ca0e3009f65125239e21b06ec51a55a6reed@google.com return; 2498e1034e9ca0e3009f65125239e21b06ec51a55a6reed@google.com } 2508e1034e9ca0e3009f65125239e21b06ec51a55a6reed@google.com 251466f5f3e44e703ca58b43ac1c4ac3bfa0e1ff024commit-bot@chromium.org if (kUnknown_SkColorType == fInfo.colorType()) { 252672588b684d484dce6ae251e9e163e4a46924322reed@google.com this->setPixelRef(NULL); 253bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com return; 254bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com } 255bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com 256466f5f3e44e703ca58b43ac1c4ac3bfa0e1ff024commit-bot@chromium.org SkPixelRef* pr = SkMallocPixelRef::NewDirect(fInfo, p, fRowBytes, ctable); 257bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com if (NULL == pr) { 258672588b684d484dce6ae251e9e163e4a46924322reed@google.com this->setPixelRef(NULL); 259bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com return; 260bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com } 261bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com 262bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com this->setPixelRef(pr)->unref(); 2638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 264c84b8335ee4fd864c30a4703afc643cf4b5010d9djsollen@google.com // since we're already allocated, we lockPixels right away 265c84b8335ee4fd864c30a4703afc643cf4b5010d9djsollen@google.com this->lockPixels(); 2668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDEBUGCODE(this->validate();) 2678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 269848250415eddc54075f7eb8795e8db79e749c6abreedbool SkBitmap::tryAllocPixels(Allocator* allocator, SkColorTable* ctable) { 2708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com HeapAllocator stdalloc; 271d2ac07b64b7d46e81d00d389781f9f83810f0095skia.committer@gmail.com 2728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (NULL == allocator) { 2738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com allocator = &stdalloc; 2748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return allocator->allocPixelRef(this, ctable); 2768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2789ebcac54635cde63110d73ad7c43d70772e7872freed@google.com/////////////////////////////////////////////////////////////////////////////// 2799ebcac54635cde63110d73ad7c43d70772e7872freed@google.com 280848250415eddc54075f7eb8795e8db79e749c6abreedbool SkBitmap::tryAllocPixels(const SkImageInfo& requestedInfo, size_t rowBytes) { 281bae704b050491a8a98c67cb23eaccb10852d2bd5reed if (kIndex_8_SkColorType == requestedInfo.colorType()) { 282bae704b050491a8a98c67cb23eaccb10852d2bd5reed return reset_return_false(this); 283bae704b050491a8a98c67cb23eaccb10852d2bd5reed } 284f0aed97aec3fa1c7f6460d8d6327358f3dcbabe6reed if (!this->setInfo(requestedInfo, rowBytes)) { 285bae704b050491a8a98c67cb23eaccb10852d2bd5reed return reset_return_false(this); 286bae704b050491a8a98c67cb23eaccb10852d2bd5reed } 287bae704b050491a8a98c67cb23eaccb10852d2bd5reed 288bae704b050491a8a98c67cb23eaccb10852d2bd5reed // setInfo may have corrected info (e.g. 565 is always opaque). 289bae704b050491a8a98c67cb23eaccb10852d2bd5reed const SkImageInfo& correctedInfo = this->info(); 290f0aed97aec3fa1c7f6460d8d6327358f3dcbabe6reed // setInfo may have computed a valid rowbytes if 0 were passed in 291f0aed97aec3fa1c7f6460d8d6327358f3dcbabe6reed rowBytes = this->rowBytes(); 292f0aed97aec3fa1c7f6460d8d6327358f3dcbabe6reed 293bae704b050491a8a98c67cb23eaccb10852d2bd5reed SkMallocPixelRef::PRFactory defaultFactory; 294bae704b050491a8a98c67cb23eaccb10852d2bd5reed 295f0aed97aec3fa1c7f6460d8d6327358f3dcbabe6reed SkPixelRef* pr = defaultFactory.create(correctedInfo, rowBytes, NULL); 296bae704b050491a8a98c67cb23eaccb10852d2bd5reed if (NULL == pr) { 297bae704b050491a8a98c67cb23eaccb10852d2bd5reed return reset_return_false(this); 298bae704b050491a8a98c67cb23eaccb10852d2bd5reed } 299bae704b050491a8a98c67cb23eaccb10852d2bd5reed this->setPixelRef(pr)->unref(); 300bae704b050491a8a98c67cb23eaccb10852d2bd5reed 301bae704b050491a8a98c67cb23eaccb10852d2bd5reed // TODO: lockPixels could/should return bool or void*/NULL 302bae704b050491a8a98c67cb23eaccb10852d2bd5reed this->lockPixels(); 303bae704b050491a8a98c67cb23eaccb10852d2bd5reed if (NULL == this->getPixels()) { 304bae704b050491a8a98c67cb23eaccb10852d2bd5reed return reset_return_false(this); 305bae704b050491a8a98c67cb23eaccb10852d2bd5reed } 306bae704b050491a8a98c67cb23eaccb10852d2bd5reed return true; 307bae704b050491a8a98c67cb23eaccb10852d2bd5reed} 308bae704b050491a8a98c67cb23eaccb10852d2bd5reed 309848250415eddc54075f7eb8795e8db79e749c6abreedbool SkBitmap::tryAllocPixels(const SkImageInfo& requestedInfo, SkPixelRefFactory* factory, 310848250415eddc54075f7eb8795e8db79e749c6abreed SkColorTable* ctable) { 311e5ea500d4714a7d84de2bf913e81be3b65d2de68reed if (kIndex_8_SkColorType == requestedInfo.colorType() && NULL == ctable) { 3129ebcac54635cde63110d73ad7c43d70772e7872freed@google.com return reset_return_false(this); 3139ebcac54635cde63110d73ad7c43d70772e7872freed@google.com } 3140187dc2155830c1ae3390d97463d5dd3971eca41scroggo if (!this->setInfo(requestedInfo)) { 3159ebcac54635cde63110d73ad7c43d70772e7872freed@google.com return reset_return_false(this); 3169ebcac54635cde63110d73ad7c43d70772e7872freed@google.com } 3179ebcac54635cde63110d73ad7c43d70772e7872freed@google.com 3180187dc2155830c1ae3390d97463d5dd3971eca41scroggo // setInfo may have corrected info (e.g. 565 is always opaque). 3190187dc2155830c1ae3390d97463d5dd3971eca41scroggo const SkImageInfo& correctedInfo = this->info(); 3200187dc2155830c1ae3390d97463d5dd3971eca41scroggo 3219ebcac54635cde63110d73ad7c43d70772e7872freed@google.com SkMallocPixelRef::PRFactory defaultFactory; 3229ebcac54635cde63110d73ad7c43d70772e7872freed@google.com if (NULL == factory) { 3239ebcac54635cde63110d73ad7c43d70772e7872freed@google.com factory = &defaultFactory; 3249ebcac54635cde63110d73ad7c43d70772e7872freed@google.com } 325d2ac07b64b7d46e81d00d389781f9f83810f0095skia.committer@gmail.com 326f0aed97aec3fa1c7f6460d8d6327358f3dcbabe6reed SkPixelRef* pr = factory->create(correctedInfo, correctedInfo.minRowBytes(), ctable); 3279ebcac54635cde63110d73ad7c43d70772e7872freed@google.com if (NULL == pr) { 3289ebcac54635cde63110d73ad7c43d70772e7872freed@google.com return reset_return_false(this); 3299ebcac54635cde63110d73ad7c43d70772e7872freed@google.com } 3309ebcac54635cde63110d73ad7c43d70772e7872freed@google.com this->setPixelRef(pr)->unref(); 3319ebcac54635cde63110d73ad7c43d70772e7872freed@google.com 3329ebcac54635cde63110d73ad7c43d70772e7872freed@google.com // TODO: lockPixels could/should return bool or void*/NULL 3339ebcac54635cde63110d73ad7c43d70772e7872freed@google.com this->lockPixels(); 3349ebcac54635cde63110d73ad7c43d70772e7872freed@google.com if (NULL == this->getPixels()) { 3359ebcac54635cde63110d73ad7c43d70772e7872freed@google.com return reset_return_false(this); 3369ebcac54635cde63110d73ad7c43d70772e7872freed@google.com } 3379ebcac54635cde63110d73ad7c43d70772e7872freed@google.com return true; 3389ebcac54635cde63110d73ad7c43d70772e7872freed@google.com} 3399ebcac54635cde63110d73ad7c43d70772e7872freed@google.com 3400187dc2155830c1ae3390d97463d5dd3971eca41scroggobool SkBitmap::installPixels(const SkImageInfo& requestedInfo, void* pixels, size_t rb, 3410187dc2155830c1ae3390d97463d5dd3971eca41scroggo SkColorTable* ct, void (*releaseProc)(void* addr, void* context), 3420187dc2155830c1ae3390d97463d5dd3971eca41scroggo void* context) { 3430187dc2155830c1ae3390d97463d5dd3971eca41scroggo if (!this->setInfo(requestedInfo, rb)) { 3449ebcac54635cde63110d73ad7c43d70772e7872freed@google.com this->reset(); 3459ebcac54635cde63110d73ad7c43d70772e7872freed@google.com return false; 3469ebcac54635cde63110d73ad7c43d70772e7872freed@google.com } 3479ebcac54635cde63110d73ad7c43d70772e7872freed@google.com 3480187dc2155830c1ae3390d97463d5dd3971eca41scroggo // setInfo may have corrected info (e.g. 565 is always opaque). 3490187dc2155830c1ae3390d97463d5dd3971eca41scroggo const SkImageInfo& correctedInfo = this->info(); 3500187dc2155830c1ae3390d97463d5dd3971eca41scroggo 3510187dc2155830c1ae3390d97463d5dd3971eca41scroggo SkPixelRef* pr = SkMallocPixelRef::NewWithProc(correctedInfo, rb, ct, pixels, releaseProc, 3520187dc2155830c1ae3390d97463d5dd3971eca41scroggo context); 3539ebcac54635cde63110d73ad7c43d70772e7872freed@google.com if (!pr) { 3549ebcac54635cde63110d73ad7c43d70772e7872freed@google.com this->reset(); 3559ebcac54635cde63110d73ad7c43d70772e7872freed@google.com return false; 3569ebcac54635cde63110d73ad7c43d70772e7872freed@google.com } 3579ebcac54635cde63110d73ad7c43d70772e7872freed@google.com 3589ebcac54635cde63110d73ad7c43d70772e7872freed@google.com this->setPixelRef(pr)->unref(); 3596e58cf36f0eba4b195726aa714d5487c91d06d04mike@reedtribe.org 3606e58cf36f0eba4b195726aa714d5487c91d06d04mike@reedtribe.org // since we're already allocated, we lockPixels right away 3616e58cf36f0eba4b195726aa714d5487c91d06d04mike@reedtribe.org this->lockPixels(); 3626e58cf36f0eba4b195726aa714d5487c91d06d04mike@reedtribe.org SkDEBUGCODE(this->validate();) 3639ebcac54635cde63110d73ad7c43d70772e7872freed@google.com return true; 3649ebcac54635cde63110d73ad7c43d70772e7872freed@google.com} 3659ebcac54635cde63110d73ad7c43d70772e7872freed@google.com 366dac522589e9395b4654a1a708f1bd971f37f95a5commit-bot@chromium.orgbool SkBitmap::installMaskPixels(const SkMask& mask) { 367dac522589e9395b4654a1a708f1bd971f37f95a5commit-bot@chromium.org if (SkMask::kA8_Format != mask.fFormat) { 368dac522589e9395b4654a1a708f1bd971f37f95a5commit-bot@chromium.org this->reset(); 369dac522589e9395b4654a1a708f1bd971f37f95a5commit-bot@chromium.org return false; 370dac522589e9395b4654a1a708f1bd971f37f95a5commit-bot@chromium.org } 371dac522589e9395b4654a1a708f1bd971f37f95a5commit-bot@chromium.org return this->installPixels(SkImageInfo::MakeA8(mask.fBounds.width(), 372dac522589e9395b4654a1a708f1bd971f37f95a5commit-bot@chromium.org mask.fBounds.height()), 373dac522589e9395b4654a1a708f1bd971f37f95a5commit-bot@chromium.org mask.fImage, mask.fRowBytes); 374dac522589e9395b4654a1a708f1bd971f37f95a5commit-bot@chromium.org} 375dac522589e9395b4654a1a708f1bd971f37f95a5commit-bot@chromium.org 376eb9a46cbbb475e862a084aa2224ec18d4ac5e95breed@google.com/////////////////////////////////////////////////////////////////////////////// 377eb9a46cbbb475e862a084aa2224ec18d4ac5e95breed@google.com 3788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkBitmap::freePixels() { 37949f085dddff10473b6ebf832a974288300224e60bsalomon if (fPixelRef) { 3808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (fPixelLockCount > 0) { 3818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fPixelRef->unlockPixels(); 3828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fPixelRef->unref(); 3848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fPixelRef = NULL; 385672588b684d484dce6ae251e9e163e4a46924322reed@google.com fPixelRefOrigin.setZero(); 3868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fPixelLockCount = 0; 3888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fPixels = NULL; 3895f62ed74342e44cb1b9671ffdac47c6a81416136reed@google.com fColorTable = NULL; 3908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 3918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comuint32_t SkBitmap::getGenerationID() const { 393c84b8335ee4fd864c30a4703afc643cf4b5010d9djsollen@google.com return (fPixelRef) ? fPixelRef->getGenerationID() : 0; 3948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 3958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkBitmap::notifyPixelsChanged() const { 397b052129a4121c1e3f051e374541a93d3d7a98064junov@chromium.org SkASSERT(!this->isImmutable()); 3988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (fPixelRef) { 3998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fPixelRef->notifyPixelsChanged(); 4008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 4018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 4028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 403b8d00db075b5ea09e353508a26ef5ced50722a6ccommit-bot@chromium.orgGrTexture* SkBitmap::getTexture() const { 404ce4e53a2347040a3c145768c193a7a7958c0d4ecreed@android.com return fPixelRef ? fPixelRef->getTexture() : NULL; 405ce4e53a2347040a3c145768c193a7a7958c0d4ecreed@android.com} 406ce4e53a2347040a3c145768c193a7a7958c0d4ecreed@android.com 4078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 4088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/** We explicitly use the same allocator for our pixels that SkMask does, 4108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com so that we can freely assign memory allocated by one class to the other. 4118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 4128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SkBitmap::HeapAllocator::allocPixelRef(SkBitmap* dst, 4138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkColorTable* ctable) { 414466f5f3e44e703ca58b43ac1c4ac3bfa0e1ff024commit-bot@chromium.org const SkImageInfo info = dst->info(); 415466f5f3e44e703ca58b43ac1c4ac3bfa0e1ff024commit-bot@chromium.org if (kUnknown_SkColorType == info.colorType()) { 416bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com// SkDebugf("unsupported config for info %d\n", dst->config()); 4178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return false; 4188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 41996f5fa02e996e39179f2eb88d57e8ed6114b06c5skia.committer@gmail.com 420466f5f3e44e703ca58b43ac1c4ac3bfa0e1ff024commit-bot@chromium.org SkPixelRef* pr = SkMallocPixelRef::NewAllocate(info, dst->rowBytes(), ctable); 421bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com if (NULL == pr) { 4228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return false; 4238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 424f9ab99aaade8c451c0e9309b4c61a448373019e3weita@google.com 425672588b684d484dce6ae251e9e163e4a46924322reed@google.com dst->setPixelRef(pr)->unref(); 4268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // since we're already allocated, we lockPixels right away 4278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com dst->lockPixels(); 4288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return true; 4298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 4308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 4328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 433fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.combool SkBitmap::copyPixelsTo(void* const dst, size_t dstSize, 4340ba4bf427acbd7707d04192a98c77ef194a0f25ascroggo@google.com size_t dstRowBytes, bool preserveDstPad) const { 43586bff1f008308267c4ff75456b202a9cf60c6193wjmaclean@chromium.org 4360ba4bf427acbd7707d04192a98c77ef194a0f25ascroggo@google.com if (0 == dstRowBytes) { 43786bff1f008308267c4ff75456b202a9cf60c6193wjmaclean@chromium.org dstRowBytes = fRowBytes; 4380ba4bf427acbd7707d04192a98c77ef194a0f25ascroggo@google.com } 43986bff1f008308267c4ff75456b202a9cf60c6193wjmaclean@chromium.org 44061e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org if (dstRowBytes < fInfo.minRowBytes() || 44161e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org dst == NULL || (getPixels() == NULL && pixelRef() == NULL)) { 44286bff1f008308267c4ff75456b202a9cf60c6193wjmaclean@chromium.org return false; 44361e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org } 44486bff1f008308267c4ff75456b202a9cf60c6193wjmaclean@chromium.org 445c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com if (!preserveDstPad && static_cast<uint32_t>(dstRowBytes) == fRowBytes) { 4464469938e92d779dff05e745559e67907bbf21e78reed@google.com size_t safeSize = this->getSafeSize(); 44786bff1f008308267c4ff75456b202a9cf60c6193wjmaclean@chromium.org if (safeSize > dstSize || safeSize == 0) 44886bff1f008308267c4ff75456b202a9cf60c6193wjmaclean@chromium.org return false; 44986bff1f008308267c4ff75456b202a9cf60c6193wjmaclean@chromium.org else { 45086bff1f008308267c4ff75456b202a9cf60c6193wjmaclean@chromium.org SkAutoLockPixels lock(*this); 45186bff1f008308267c4ff75456b202a9cf60c6193wjmaclean@chromium.org // This implementation will write bytes beyond the end of each row, 45286bff1f008308267c4ff75456b202a9cf60c6193wjmaclean@chromium.org // excluding the last row, if the bitmap's stride is greater than 45386bff1f008308267c4ff75456b202a9cf60c6193wjmaclean@chromium.org // strictly required by the current config. 45486bff1f008308267c4ff75456b202a9cf60c6193wjmaclean@chromium.org memcpy(dst, getPixels(), safeSize); 45586bff1f008308267c4ff75456b202a9cf60c6193wjmaclean@chromium.org 45686bff1f008308267c4ff75456b202a9cf60c6193wjmaclean@chromium.org return true; 45786bff1f008308267c4ff75456b202a9cf60c6193wjmaclean@chromium.org } 45886bff1f008308267c4ff75456b202a9cf60c6193wjmaclean@chromium.org } else { 45986bff1f008308267c4ff75456b202a9cf60c6193wjmaclean@chromium.org // If destination has different stride than us, then copy line by line. 46061e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org if (fInfo.getSafeSize(dstRowBytes) > dstSize) { 46186bff1f008308267c4ff75456b202a9cf60c6193wjmaclean@chromium.org return false; 46261e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org } else { 46386bff1f008308267c4ff75456b202a9cf60c6193wjmaclean@chromium.org // Just copy what we need on each line. 46461e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org size_t rowBytes = fInfo.minRowBytes(); 46586bff1f008308267c4ff75456b202a9cf60c6193wjmaclean@chromium.org SkAutoLockPixels lock(*this); 46686bff1f008308267c4ff75456b202a9cf60c6193wjmaclean@chromium.org const uint8_t* srcP = reinterpret_cast<const uint8_t*>(getPixels()); 46786bff1f008308267c4ff75456b202a9cf60c6193wjmaclean@chromium.org uint8_t* dstP = reinterpret_cast<uint8_t*>(dst); 468e5ea500d4714a7d84de2bf913e81be3b65d2de68reed for (int row = 0; row < fInfo.height(); row++, srcP += fRowBytes, dstP += dstRowBytes) { 46986bff1f008308267c4ff75456b202a9cf60c6193wjmaclean@chromium.org memcpy(dstP, srcP, rowBytes); 47086bff1f008308267c4ff75456b202a9cf60c6193wjmaclean@chromium.org } 47186bff1f008308267c4ff75456b202a9cf60c6193wjmaclean@chromium.org 47286bff1f008308267c4ff75456b202a9cf60c6193wjmaclean@chromium.org return true; 47386bff1f008308267c4ff75456b202a9cf60c6193wjmaclean@chromium.org } 47486bff1f008308267c4ff75456b202a9cf60c6193wjmaclean@chromium.org } 47586bff1f008308267c4ff75456b202a9cf60c6193wjmaclean@chromium.org} 47686bff1f008308267c4ff75456b202a9cf60c6193wjmaclean@chromium.org 47786bff1f008308267c4ff75456b202a9cf60c6193wjmaclean@chromium.org/////////////////////////////////////////////////////////////////////////////// 47886bff1f008308267c4ff75456b202a9cf60c6193wjmaclean@chromium.org 479fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.combool SkBitmap::isImmutable() const { 4800847059fcffe11d53d4ea803ba2d51c696eb6d07scroggo return fPixelRef ? fPixelRef->isImmutable() : false; 481b052129a4121c1e3f051e374541a93d3d7a98064junov@chromium.org} 482b052129a4121c1e3f051e374541a93d3d7a98064junov@chromium.org 483b052129a4121c1e3f051e374541a93d3d7a98064junov@chromium.orgvoid SkBitmap::setImmutable() { 484b052129a4121c1e3f051e374541a93d3d7a98064junov@chromium.org if (fPixelRef) { 485b052129a4121c1e3f051e374541a93d3d7a98064junov@chromium.org fPixelRef->setImmutable(); 486b052129a4121c1e3f051e374541a93d3d7a98064junov@chromium.org } 487b052129a4121c1e3f051e374541a93d3d7a98064junov@chromium.org} 488b052129a4121c1e3f051e374541a93d3d7a98064junov@chromium.org 4894ee7ae5dcfe2055cfcfc21bf2cec1d790330eb4ajunov@google.combool SkBitmap::isVolatile() const { 4904ee7ae5dcfe2055cfcfc21bf2cec1d790330eb4ajunov@google.com return (fFlags & kImageIsVolatile_Flag) != 0; 4914ee7ae5dcfe2055cfcfc21bf2cec1d790330eb4ajunov@google.com} 4924ee7ae5dcfe2055cfcfc21bf2cec1d790330eb4ajunov@google.com 4934ee7ae5dcfe2055cfcfc21bf2cec1d790330eb4ajunov@google.comvoid SkBitmap::setIsVolatile(bool isVolatile) { 4944ee7ae5dcfe2055cfcfc21bf2cec1d790330eb4ajunov@google.com if (isVolatile) { 4954ee7ae5dcfe2055cfcfc21bf2cec1d790330eb4ajunov@google.com fFlags |= kImageIsVolatile_Flag; 4964ee7ae5dcfe2055cfcfc21bf2cec1d790330eb4ajunov@google.com } else { 4974ee7ae5dcfe2055cfcfc21bf2cec1d790330eb4ajunov@google.com fFlags &= ~kImageIsVolatile_Flag; 4984ee7ae5dcfe2055cfcfc21bf2cec1d790330eb4ajunov@google.com } 4994ee7ae5dcfe2055cfcfc21bf2cec1d790330eb4ajunov@google.com} 5004ee7ae5dcfe2055cfcfc21bf2cec1d790330eb4ajunov@google.com 5018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid* SkBitmap::getAddr(int x, int y) const { 5028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT((unsigned)x < (unsigned)this->width()); 5038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT((unsigned)y < (unsigned)this->height()); 5048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com char* base = (char*)this->getPixels(); 5068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (base) { 5078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com base += y * this->rowBytes(); 50861e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org switch (this->colorType()) { 50961e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org case kRGBA_8888_SkColorType: 51061e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org case kBGRA_8888_SkColorType: 5118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com base += x << 2; 5128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com break; 51361e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org case kARGB_4444_SkColorType: 51461e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org case kRGB_565_SkColorType: 5158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com base += x << 1; 5168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com break; 51761e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org case kAlpha_8_SkColorType: 51861e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org case kIndex_8_SkColorType: 5198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com base += x; 5208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com break; 5218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com default: 5220c00f21fee3f5cfa3aa7e5d46ff94cb8cf340451tomhudson@google.com SkDEBUGFAIL("Can't return addr for config"); 5238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com base = NULL; 5248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com break; 5258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 5268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 5278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return base; 5288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 5298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 530112706d4c566e283890322bb246b4b86d59837e1vandebo@chromium.orgSkColor SkBitmap::getColor(int x, int y) const { 531112706d4c566e283890322bb246b4b86d59837e1vandebo@chromium.org SkASSERT((unsigned)x < (unsigned)this->width()); 532112706d4c566e283890322bb246b4b86d59837e1vandebo@chromium.org SkASSERT((unsigned)y < (unsigned)this->height()); 533112706d4c566e283890322bb246b4b86d59837e1vandebo@chromium.org 534cba73780bbd12fd254229517aec04fcbf0b64b52commit-bot@chromium.org switch (this->colorType()) { 535cba73780bbd12fd254229517aec04fcbf0b64b52commit-bot@chromium.org case kAlpha_8_SkColorType: { 5363b521d05335a1bf76be3456feb9dbfba0a51b339reed@google.com uint8_t* addr = this->getAddr8(x, y); 537112706d4c566e283890322bb246b4b86d59837e1vandebo@chromium.org return SkColorSetA(0, addr[0]); 538112706d4c566e283890322bb246b4b86d59837e1vandebo@chromium.org } 539cba73780bbd12fd254229517aec04fcbf0b64b52commit-bot@chromium.org case kIndex_8_SkColorType: { 5403b521d05335a1bf76be3456feb9dbfba0a51b339reed@google.com SkPMColor c = this->getIndex8Color(x, y); 541112706d4c566e283890322bb246b4b86d59837e1vandebo@chromium.org return SkUnPreMultiply::PMColorToColor(c); 542112706d4c566e283890322bb246b4b86d59837e1vandebo@chromium.org } 543cba73780bbd12fd254229517aec04fcbf0b64b52commit-bot@chromium.org case kRGB_565_SkColorType: { 5443b521d05335a1bf76be3456feb9dbfba0a51b339reed@google.com uint16_t* addr = this->getAddr16(x, y); 545112706d4c566e283890322bb246b4b86d59837e1vandebo@chromium.org return SkPixel16ToColor(addr[0]); 546112706d4c566e283890322bb246b4b86d59837e1vandebo@chromium.org } 547cba73780bbd12fd254229517aec04fcbf0b64b52commit-bot@chromium.org case kARGB_4444_SkColorType: { 5483b521d05335a1bf76be3456feb9dbfba0a51b339reed@google.com uint16_t* addr = this->getAddr16(x, y); 549112706d4c566e283890322bb246b4b86d59837e1vandebo@chromium.org SkPMColor c = SkPixel4444ToPixel32(addr[0]); 550112706d4c566e283890322bb246b4b86d59837e1vandebo@chromium.org return SkUnPreMultiply::PMColorToColor(c); 551112706d4c566e283890322bb246b4b86d59837e1vandebo@chromium.org } 552cba73780bbd12fd254229517aec04fcbf0b64b52commit-bot@chromium.org case kBGRA_8888_SkColorType: 553cba73780bbd12fd254229517aec04fcbf0b64b52commit-bot@chromium.org case kRGBA_8888_SkColorType: { 5543b521d05335a1bf76be3456feb9dbfba0a51b339reed@google.com uint32_t* addr = this->getAddr32(x, y); 555112706d4c566e283890322bb246b4b86d59837e1vandebo@chromium.org return SkUnPreMultiply::PMColorToColor(addr[0]); 556112706d4c566e283890322bb246b4b86d59837e1vandebo@chromium.org } 557d6bab0238655dbab24dfe92bd0b16b464310a8c7rmistry@google.com default: 558112706d4c566e283890322bb246b4b86d59837e1vandebo@chromium.org SkASSERT(false); 559112706d4c566e283890322bb246b4b86d59837e1vandebo@chromium.org return 0; 560112706d4c566e283890322bb246b4b86d59837e1vandebo@chromium.org } 561112706d4c566e283890322bb246b4b86d59837e1vandebo@chromium.org SkASSERT(false); // Not reached. 562112706d4c566e283890322bb246b4b86d59837e1vandebo@chromium.org return 0; 563112706d4c566e283890322bb246b4b86d59837e1vandebo@chromium.org} 564112706d4c566e283890322bb246b4b86d59837e1vandebo@chromium.org 5652a7579d11796866b0026755ab52597d09f4509ccreed@google.combool SkBitmap::ComputeIsOpaque(const SkBitmap& bm) { 5662a7579d11796866b0026755ab52597d09f4509ccreed@google.com SkAutoLockPixels alp(bm); 5672a7579d11796866b0026755ab52597d09f4509ccreed@google.com if (!bm.getPixels()) { 5682a7579d11796866b0026755ab52597d09f4509ccreed@google.com return false; 5692a7579d11796866b0026755ab52597d09f4509ccreed@google.com } 5702a7579d11796866b0026755ab52597d09f4509ccreed@google.com 5712a7579d11796866b0026755ab52597d09f4509ccreed@google.com const int height = bm.height(); 5722a7579d11796866b0026755ab52597d09f4509ccreed@google.com const int width = bm.width(); 5732a7579d11796866b0026755ab52597d09f4509ccreed@google.com 574cba73780bbd12fd254229517aec04fcbf0b64b52commit-bot@chromium.org switch (bm.colorType()) { 575cba73780bbd12fd254229517aec04fcbf0b64b52commit-bot@chromium.org case kAlpha_8_SkColorType: { 5762a7579d11796866b0026755ab52597d09f4509ccreed@google.com unsigned a = 0xFF; 5772a7579d11796866b0026755ab52597d09f4509ccreed@google.com for (int y = 0; y < height; ++y) { 5782a7579d11796866b0026755ab52597d09f4509ccreed@google.com const uint8_t* row = bm.getAddr8(0, y); 5792a7579d11796866b0026755ab52597d09f4509ccreed@google.com for (int x = 0; x < width; ++x) { 5802a7579d11796866b0026755ab52597d09f4509ccreed@google.com a &= row[x]; 5812a7579d11796866b0026755ab52597d09f4509ccreed@google.com } 5822a7579d11796866b0026755ab52597d09f4509ccreed@google.com if (0xFF != a) { 5832a7579d11796866b0026755ab52597d09f4509ccreed@google.com return false; 5842a7579d11796866b0026755ab52597d09f4509ccreed@google.com } 5852a7579d11796866b0026755ab52597d09f4509ccreed@google.com } 5862a7579d11796866b0026755ab52597d09f4509ccreed@google.com return true; 5872a7579d11796866b0026755ab52597d09f4509ccreed@google.com } break; 588cba73780bbd12fd254229517aec04fcbf0b64b52commit-bot@chromium.org case kIndex_8_SkColorType: { 5892a7579d11796866b0026755ab52597d09f4509ccreed@google.com SkAutoLockColors alc(bm); 5902a7579d11796866b0026755ab52597d09f4509ccreed@google.com const SkPMColor* table = alc.colors(); 5912a7579d11796866b0026755ab52597d09f4509ccreed@google.com if (!table) { 5922a7579d11796866b0026755ab52597d09f4509ccreed@google.com return false; 5932a7579d11796866b0026755ab52597d09f4509ccreed@google.com } 594140d7286c5a40058932696eaa28818c313bd2ddfreed@google.com SkPMColor c = (SkPMColor)~0; 5952a7579d11796866b0026755ab52597d09f4509ccreed@google.com for (int i = bm.getColorTable()->count() - 1; i >= 0; --i) { 5962a7579d11796866b0026755ab52597d09f4509ccreed@google.com c &= table[i]; 5972a7579d11796866b0026755ab52597d09f4509ccreed@google.com } 5982a7579d11796866b0026755ab52597d09f4509ccreed@google.com return 0xFF == SkGetPackedA32(c); 5992a7579d11796866b0026755ab52597d09f4509ccreed@google.com } break; 600cba73780bbd12fd254229517aec04fcbf0b64b52commit-bot@chromium.org case kRGB_565_SkColorType: 6012a7579d11796866b0026755ab52597d09f4509ccreed@google.com return true; 6022a7579d11796866b0026755ab52597d09f4509ccreed@google.com break; 603cba73780bbd12fd254229517aec04fcbf0b64b52commit-bot@chromium.org case kARGB_4444_SkColorType: { 6042a7579d11796866b0026755ab52597d09f4509ccreed@google.com unsigned c = 0xFFFF; 6052a7579d11796866b0026755ab52597d09f4509ccreed@google.com for (int y = 0; y < height; ++y) { 6062a7579d11796866b0026755ab52597d09f4509ccreed@google.com const SkPMColor16* row = bm.getAddr16(0, y); 6072a7579d11796866b0026755ab52597d09f4509ccreed@google.com for (int x = 0; x < width; ++x) { 6082a7579d11796866b0026755ab52597d09f4509ccreed@google.com c &= row[x]; 6092a7579d11796866b0026755ab52597d09f4509ccreed@google.com } 6102a7579d11796866b0026755ab52597d09f4509ccreed@google.com if (0xF != SkGetPackedA4444(c)) { 6112a7579d11796866b0026755ab52597d09f4509ccreed@google.com return false; 6122a7579d11796866b0026755ab52597d09f4509ccreed@google.com } 6132a7579d11796866b0026755ab52597d09f4509ccreed@google.com } 6142a7579d11796866b0026755ab52597d09f4509ccreed@google.com return true; 6152a7579d11796866b0026755ab52597d09f4509ccreed@google.com } break; 616cba73780bbd12fd254229517aec04fcbf0b64b52commit-bot@chromium.org case kBGRA_8888_SkColorType: 617cba73780bbd12fd254229517aec04fcbf0b64b52commit-bot@chromium.org case kRGBA_8888_SkColorType: { 618140d7286c5a40058932696eaa28818c313bd2ddfreed@google.com SkPMColor c = (SkPMColor)~0; 6192a7579d11796866b0026755ab52597d09f4509ccreed@google.com for (int y = 0; y < height; ++y) { 6202a7579d11796866b0026755ab52597d09f4509ccreed@google.com const SkPMColor* row = bm.getAddr32(0, y); 6212a7579d11796866b0026755ab52597d09f4509ccreed@google.com for (int x = 0; x < width; ++x) { 6222a7579d11796866b0026755ab52597d09f4509ccreed@google.com c &= row[x]; 6232a7579d11796866b0026755ab52597d09f4509ccreed@google.com } 6242a7579d11796866b0026755ab52597d09f4509ccreed@google.com if (0xFF != SkGetPackedA32(c)) { 6252a7579d11796866b0026755ab52597d09f4509ccreed@google.com return false; 6262a7579d11796866b0026755ab52597d09f4509ccreed@google.com } 6272a7579d11796866b0026755ab52597d09f4509ccreed@google.com } 6282a7579d11796866b0026755ab52597d09f4509ccreed@google.com return true; 6292a7579d11796866b0026755ab52597d09f4509ccreed@google.com } 6302a7579d11796866b0026755ab52597d09f4509ccreed@google.com default: 6312a7579d11796866b0026755ab52597d09f4509ccreed@google.com break; 6322a7579d11796866b0026755ab52597d09f4509ccreed@google.com } 6332a7579d11796866b0026755ab52597d09f4509ccreed@google.com return false; 6342a7579d11796866b0026755ab52597d09f4509ccreed@google.com} 6352a7579d11796866b0026755ab52597d09f4509ccreed@google.com 6362a7579d11796866b0026755ab52597d09f4509ccreed@google.com 6378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 6388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 6398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 64045f746f521d6925d22a304921f6e17196f4f8157reed@google.comstatic uint16_t pack_8888_to_4444(unsigned a, unsigned r, unsigned g, unsigned b) { 64145f746f521d6925d22a304921f6e17196f4f8157reed@google.com unsigned pixel = (SkA32To4444(a) << SK_A4444_SHIFT) | 64245f746f521d6925d22a304921f6e17196f4f8157reed@google.com (SkR32To4444(r) << SK_R4444_SHIFT) | 64345f746f521d6925d22a304921f6e17196f4f8157reed@google.com (SkG32To4444(g) << SK_G4444_SHIFT) | 64445f746f521d6925d22a304921f6e17196f4f8157reed@google.com (SkB32To4444(b) << SK_B4444_SHIFT); 64545f746f521d6925d22a304921f6e17196f4f8157reed@google.com return SkToU16(pixel); 64645f746f521d6925d22a304921f6e17196f4f8157reed@google.com} 64745f746f521d6925d22a304921f6e17196f4f8157reed@google.com 64860d3235ab42bd1d32a070695ee30d6e3ec2fa222reed@google.comvoid SkBitmap::internalErase(const SkIRect& area, 64960d3235ab42bd1d32a070695ee30d6e3ec2fa222reed@google.com U8CPU a, U8CPU r, U8CPU g, U8CPU b) const { 65060d3235ab42bd1d32a070695ee30d6e3ec2fa222reed@google.com#ifdef SK_DEBUG 6518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDEBUGCODE(this->validate();) 65260d3235ab42bd1d32a070695ee30d6e3ec2fa222reed@google.com SkASSERT(!area.isEmpty()); 65360d3235ab42bd1d32a070695ee30d6e3ec2fa222reed@google.com { 65492833f99b99f1f955c350f6f4f70acd3356a79a5reed@google.com SkIRect total = { 0, 0, this->width(), this->height() }; 65560d3235ab42bd1d32a070695ee30d6e3ec2fa222reed@google.com SkASSERT(total.contains(area)); 65660d3235ab42bd1d32a070695ee30d6e3ec2fa222reed@google.com } 65760d3235ab42bd1d32a070695ee30d6e3ec2fa222reed@google.com#endif 6588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 65961e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org switch (fInfo.colorType()) { 66061e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org case kUnknown_SkColorType: 66161e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org case kIndex_8_SkColorType: 6627669a77cd16fbab3618ca1f1a03bcfa05a93c447commit-bot@chromium.org return; // can't erase. Should we bzero so the memory is not uninitialized? 66361e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org default: 66461e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org break; 6658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 6668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 6678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkAutoLockPixels alp(*this); 6688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // perform this check after the lock call 6698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (!this->readyToDraw()) { 6708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 6718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 6728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 67360d3235ab42bd1d32a070695ee30d6e3ec2fa222reed@google.com int height = area.height(); 67460d3235ab42bd1d32a070695ee30d6e3ec2fa222reed@google.com const int width = area.width(); 6758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const int rowBytes = fRowBytes; 6768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 67761e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org switch (this->colorType()) { 67861e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org case kAlpha_8_SkColorType: { 67960d3235ab42bd1d32a070695ee30d6e3ec2fa222reed@google.com uint8_t* p = this->getAddr8(area.fLeft, area.fTop); 6808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (--height >= 0) { 6818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com memset(p, a, width); 6828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com p += rowBytes; 6838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 6848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com break; 6858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 68661e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org case kARGB_4444_SkColorType: 68761e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org case kRGB_565_SkColorType: { 68860d3235ab42bd1d32a070695ee30d6e3ec2fa222reed@google.com uint16_t* p = this->getAddr16(area.fLeft, area.fTop);; 68945f746f521d6925d22a304921f6e17196f4f8157reed@google.com uint16_t v; 690020b25becb4a99061e8643780c887ad472eb0648skia.committer@gmail.com 6917669a77cd16fbab3618ca1f1a03bcfa05a93c447commit-bot@chromium.org // make rgb premultiplied 6927669a77cd16fbab3618ca1f1a03bcfa05a93c447commit-bot@chromium.org if (255 != a) { 6937669a77cd16fbab3618ca1f1a03bcfa05a93c447commit-bot@chromium.org r = SkAlphaMul(r, a); 6947669a77cd16fbab3618ca1f1a03bcfa05a93c447commit-bot@chromium.org g = SkAlphaMul(g, a); 6957669a77cd16fbab3618ca1f1a03bcfa05a93c447commit-bot@chromium.org b = SkAlphaMul(b, a); 6967669a77cd16fbab3618ca1f1a03bcfa05a93c447commit-bot@chromium.org } 6977669a77cd16fbab3618ca1f1a03bcfa05a93c447commit-bot@chromium.org 69861e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org if (kARGB_4444_SkColorType == this->colorType()) { 69945f746f521d6925d22a304921f6e17196f4f8157reed@google.com v = pack_8888_to_4444(a, r, g, b); 70045f746f521d6925d22a304921f6e17196f4f8157reed@google.com } else { 70145f746f521d6925d22a304921f6e17196f4f8157reed@google.com v = SkPackRGB16(r >> (8 - SK_R16_BITS), 70245f746f521d6925d22a304921f6e17196f4f8157reed@google.com g >> (8 - SK_G16_BITS), 70345f746f521d6925d22a304921f6e17196f4f8157reed@google.com b >> (8 - SK_B16_BITS)); 70445f746f521d6925d22a304921f6e17196f4f8157reed@google.com } 7058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (--height >= 0) { 7068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com sk_memset16(p, v, width); 7078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com p = (uint16_t*)((char*)p + rowBytes); 7088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 7098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com break; 7108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 7117669a77cd16fbab3618ca1f1a03bcfa05a93c447commit-bot@chromium.org case kBGRA_8888_SkColorType: 7127669a77cd16fbab3618ca1f1a03bcfa05a93c447commit-bot@chromium.org case kRGBA_8888_SkColorType: { 71360d3235ab42bd1d32a070695ee30d6e3ec2fa222reed@google.com uint32_t* p = this->getAddr32(area.fLeft, area.fTop); 7147669a77cd16fbab3618ca1f1a03bcfa05a93c447commit-bot@chromium.org 7157669a77cd16fbab3618ca1f1a03bcfa05a93c447commit-bot@chromium.org if (255 != a && kPremul_SkAlphaType == this->alphaType()) { 7167669a77cd16fbab3618ca1f1a03bcfa05a93c447commit-bot@chromium.org r = SkAlphaMul(r, a); 7177669a77cd16fbab3618ca1f1a03bcfa05a93c447commit-bot@chromium.org g = SkAlphaMul(g, a); 7187669a77cd16fbab3618ca1f1a03bcfa05a93c447commit-bot@chromium.org b = SkAlphaMul(b, a); 7197669a77cd16fbab3618ca1f1a03bcfa05a93c447commit-bot@chromium.org } 7207669a77cd16fbab3618ca1f1a03bcfa05a93c447commit-bot@chromium.org uint32_t v = kRGBA_8888_SkColorType == this->colorType() ? 7217669a77cd16fbab3618ca1f1a03bcfa05a93c447commit-bot@chromium.org SkPackARGB_as_RGBA(a, r, g, b) : SkPackARGB_as_BGRA(a, r, g, b); 7228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 7238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (--height >= 0) { 7248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com sk_memset32(p, v, width); 7258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com p = (uint32_t*)((char*)p + rowBytes); 7268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 7278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com break; 7288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 72961e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org default: 73061e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org return; // no change, so don't call notifyPixelsChanged() 7318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 732f9ab99aaade8c451c0e9309b4c61a448373019e3weita@google.com 7338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->notifyPixelsChanged(); 7348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 7358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 73660d3235ab42bd1d32a070695ee30d6e3ec2fa222reed@google.comvoid SkBitmap::eraseARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b) const { 73792833f99b99f1f955c350f6f4f70acd3356a79a5reed@google.com SkIRect area = { 0, 0, this->width(), this->height() }; 73860d3235ab42bd1d32a070695ee30d6e3ec2fa222reed@google.com if (!area.isEmpty()) { 73960d3235ab42bd1d32a070695ee30d6e3ec2fa222reed@google.com this->internalErase(area, a, r, g, b); 74060d3235ab42bd1d32a070695ee30d6e3ec2fa222reed@google.com } 74160d3235ab42bd1d32a070695ee30d6e3ec2fa222reed@google.com} 74260d3235ab42bd1d32a070695ee30d6e3ec2fa222reed@google.com 74360d3235ab42bd1d32a070695ee30d6e3ec2fa222reed@google.comvoid SkBitmap::eraseArea(const SkIRect& rect, SkColor c) const { 74492833f99b99f1f955c350f6f4f70acd3356a79a5reed@google.com SkIRect area = { 0, 0, this->width(), this->height() }; 74560d3235ab42bd1d32a070695ee30d6e3ec2fa222reed@google.com if (area.intersect(rect)) { 74660d3235ab42bd1d32a070695ee30d6e3ec2fa222reed@google.com this->internalErase(area, SkColorGetA(c), SkColorGetR(c), 74760d3235ab42bd1d32a070695ee30d6e3ec2fa222reed@google.com SkColorGetG(c), SkColorGetB(c)); 74860d3235ab42bd1d32a070695ee30d6e3ec2fa222reed@google.com } 74960d3235ab42bd1d32a070695ee30d6e3ec2fa222reed@google.com} 75060d3235ab42bd1d32a070695ee30d6e3ec2fa222reed@google.com 7518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////////////// 7528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////////////// 7538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 7548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SkBitmap::extractSubset(SkBitmap* result, const SkIRect& subset) const { 7558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDEBUGCODE(this->validate();) 7568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 757c84b8335ee4fd864c30a4703afc643cf4b5010d9djsollen@google.com if (NULL == result || NULL == fPixelRef) { 7588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return false; // no src pixels 7598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 7608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 7618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkIRect srcRect, r; 7628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com srcRect.set(0, 0, this->width(), this->height()); 7638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (!r.intersect(srcRect, subset)) { 7648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return false; // r is empty (i.e. no intersection) 7658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 7668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 767a2a31928470dfb642880f6ab2e4d34b1c7f5d476scroggo@google.com if (fPixelRef->getTexture() != NULL) { 768a2a31928470dfb642880f6ab2e4d34b1c7f5d476scroggo@google.com // Do a deep copy 769e4538f5b46d70798e34eb078f5d5e76a59d02318reed SkPixelRef* pixelRef = fPixelRef->deepCopy(this->colorType(), &subset); 770a2a31928470dfb642880f6ab2e4d34b1c7f5d476scroggo@google.com if (pixelRef != NULL) { 771a2a31928470dfb642880f6ab2e4d34b1c7f5d476scroggo@google.com SkBitmap dst; 772a3264e53ee3f3c5d6a2c813df7e44b5b96d207f2commit-bot@chromium.org dst.setInfo(SkImageInfo::Make(subset.width(), subset.height(), 773a3264e53ee3f3c5d6a2c813df7e44b5b96d207f2commit-bot@chromium.org this->colorType(), this->alphaType())); 774a2a31928470dfb642880f6ab2e4d34b1c7f5d476scroggo@google.com dst.setIsVolatile(this->isVolatile()); 775a2a31928470dfb642880f6ab2e4d34b1c7f5d476scroggo@google.com dst.setPixelRef(pixelRef)->unref(); 776a2a31928470dfb642880f6ab2e4d34b1c7f5d476scroggo@google.com SkDEBUGCODE(dst.validate()); 777a2a31928470dfb642880f6ab2e4d34b1c7f5d476scroggo@google.com result->swap(dst); 778a2a31928470dfb642880f6ab2e4d34b1c7f5d476scroggo@google.com return true; 779a2a31928470dfb642880f6ab2e4d34b1c7f5d476scroggo@google.com } 780a2a31928470dfb642880f6ab2e4d34b1c7f5d476scroggo@google.com } 781a2a31928470dfb642880f6ab2e4d34b1c7f5d476scroggo@google.com 782a2a31928470dfb642880f6ab2e4d34b1c7f5d476scroggo@google.com // If the upper left of the rectangle was outside the bounds of this SkBitmap, we should have 783a2a31928470dfb642880f6ab2e4d34b1c7f5d476scroggo@google.com // exited above. 784a2a31928470dfb642880f6ab2e4d34b1c7f5d476scroggo@google.com SkASSERT(static_cast<unsigned>(r.fLeft) < static_cast<unsigned>(this->width())); 785a2a31928470dfb642880f6ab2e4d34b1c7f5d476scroggo@google.com SkASSERT(static_cast<unsigned>(r.fTop) < static_cast<unsigned>(this->height())); 786a2a31928470dfb642880f6ab2e4d34b1c7f5d476scroggo@google.com 7878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkBitmap dst; 788a3264e53ee3f3c5d6a2c813df7e44b5b96d207f2commit-bot@chromium.org dst.setInfo(SkImageInfo::Make(r.width(), r.height(), this->colorType(), this->alphaType()), 789a3264e53ee3f3c5d6a2c813df7e44b5b96d207f2commit-bot@chromium.org this->rowBytes()); 7900eb7576c659a165f1d73b6b7ddfd43dc3782f62bskyostil@google.com dst.setIsVolatile(this->isVolatile()); 7918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 7928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (fPixelRef) { 793672588b684d484dce6ae251e9e163e4a46924322reed@google.com SkIPoint origin = fPixelRefOrigin; 794672588b684d484dce6ae251e9e163e4a46924322reed@google.com origin.fX += r.fLeft; 795672588b684d484dce6ae251e9e163e4a46924322reed@google.com origin.fY += r.fTop; 7968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // share the pixelref with a custom offset 797672588b684d484dce6ae251e9e163e4a46924322reed@google.com dst.setPixelRef(fPixelRef, origin); 7988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 7998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDEBUGCODE(dst.validate();) 8008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // we know we're good, so commit to result 8028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com result->swap(dst); 8038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return true; 8048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 8058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 8078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkCanvas.h" 8098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkPaint.h" 8108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8118a2ad3cae710f05cca57e48dd1732d575dba2dc7commit-bot@chromium.orgbool SkBitmap::canCopyTo(SkColorType dstColorType) const { 812b184f7f52b2a94e95aee326a3ca37110d2e43336reed const SkColorType srcCT = this->colorType(); 813b184f7f52b2a94e95aee326a3ca37110d2e43336reed 814b184f7f52b2a94e95aee326a3ca37110d2e43336reed if (srcCT == kUnknown_SkColorType) { 8158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return false; 8168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 8178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 818b184f7f52b2a94e95aee326a3ca37110d2e43336reed bool sameConfigs = (srcCT == dstColorType); 8198a2ad3cae710f05cca57e48dd1732d575dba2dc7commit-bot@chromium.org switch (dstColorType) { 8208a2ad3cae710f05cca57e48dd1732d575dba2dc7commit-bot@chromium.org case kAlpha_8_SkColorType: 8218a2ad3cae710f05cca57e48dd1732d575dba2dc7commit-bot@chromium.org case kRGB_565_SkColorType: 82260b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org case kRGBA_8888_SkColorType: 82360b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org case kBGRA_8888_SkColorType: 8248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com break; 8258a2ad3cae710f05cca57e48dd1732d575dba2dc7commit-bot@chromium.org case kIndex_8_SkColorType: 826f9ab99aaade8c451c0e9309b4c61a448373019e3weita@google.com if (!sameConfigs) { 827f9ab99aaade8c451c0e9309b4c61a448373019e3weita@google.com return false; 828f9ab99aaade8c451c0e9309b4c61a448373019e3weita@google.com } 829f9ab99aaade8c451c0e9309b4c61a448373019e3weita@google.com break; 8308a2ad3cae710f05cca57e48dd1732d575dba2dc7commit-bot@chromium.org case kARGB_4444_SkColorType: 831b184f7f52b2a94e95aee326a3ca37110d2e43336reed return sameConfigs || kN32_SkColorType == srcCT || kIndex_8_SkColorType == srcCT; 8328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com default: 8338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return false; 8348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 835fbaa88d9695347299321cbce2bf803726999fb58reed@android.com return true; 836fbaa88d9695347299321cbce2bf803726999fb58reed@android.com} 837fbaa88d9695347299321cbce2bf803726999fb58reed@android.com 838b184f7f52b2a94e95aee326a3ca37110d2e43336reed#include "SkConfig8888.h" 839b184f7f52b2a94e95aee326a3ca37110d2e43336reed 840b184f7f52b2a94e95aee326a3ca37110d2e43336reedbool SkBitmap::readPixels(const SkImageInfo& requestedDstInfo, void* dstPixels, size_t dstRB, 841b184f7f52b2a94e95aee326a3ca37110d2e43336reed int x, int y) const { 842b184f7f52b2a94e95aee326a3ca37110d2e43336reed if (kUnknown_SkColorType == requestedDstInfo.colorType()) { 843b184f7f52b2a94e95aee326a3ca37110d2e43336reed return false; 844b184f7f52b2a94e95aee326a3ca37110d2e43336reed } 845b184f7f52b2a94e95aee326a3ca37110d2e43336reed if (NULL == dstPixels || dstRB < requestedDstInfo.minRowBytes()) { 846b184f7f52b2a94e95aee326a3ca37110d2e43336reed return false; 847b184f7f52b2a94e95aee326a3ca37110d2e43336reed } 848b184f7f52b2a94e95aee326a3ca37110d2e43336reed if (0 == requestedDstInfo.width() || 0 == requestedDstInfo.height()) { 849b184f7f52b2a94e95aee326a3ca37110d2e43336reed return false; 850b184f7f52b2a94e95aee326a3ca37110d2e43336reed } 851b184f7f52b2a94e95aee326a3ca37110d2e43336reed 852b184f7f52b2a94e95aee326a3ca37110d2e43336reed SkIRect srcR = SkIRect::MakeXYWH(x, y, requestedDstInfo.width(), requestedDstInfo.height()); 853b184f7f52b2a94e95aee326a3ca37110d2e43336reed if (!srcR.intersect(0, 0, this->width(), this->height())) { 854b184f7f52b2a94e95aee326a3ca37110d2e43336reed return false; 855b184f7f52b2a94e95aee326a3ca37110d2e43336reed } 856b184f7f52b2a94e95aee326a3ca37110d2e43336reed 857b184f7f52b2a94e95aee326a3ca37110d2e43336reed // the intersect may have shrunk info's logical size 858e5ea500d4714a7d84de2bf913e81be3b65d2de68reed const SkImageInfo dstInfo = requestedDstInfo.makeWH(srcR.width(), srcR.height()); 859b184f7f52b2a94e95aee326a3ca37110d2e43336reed 860b184f7f52b2a94e95aee326a3ca37110d2e43336reed // if x or y are negative, then we have to adjust pixels 861b184f7f52b2a94e95aee326a3ca37110d2e43336reed if (x > 0) { 862b184f7f52b2a94e95aee326a3ca37110d2e43336reed x = 0; 863b184f7f52b2a94e95aee326a3ca37110d2e43336reed } 864b184f7f52b2a94e95aee326a3ca37110d2e43336reed if (y > 0) { 865b184f7f52b2a94e95aee326a3ca37110d2e43336reed y = 0; 866b184f7f52b2a94e95aee326a3ca37110d2e43336reed } 867b184f7f52b2a94e95aee326a3ca37110d2e43336reed // here x,y are either 0 or negative 868b184f7f52b2a94e95aee326a3ca37110d2e43336reed dstPixels = ((char*)dstPixels - y * dstRB - x * dstInfo.bytesPerPixel()); 869b184f7f52b2a94e95aee326a3ca37110d2e43336reed 870b184f7f52b2a94e95aee326a3ca37110d2e43336reed ////////////// 871b184f7f52b2a94e95aee326a3ca37110d2e43336reed 872b184f7f52b2a94e95aee326a3ca37110d2e43336reed SkAutoLockPixels alp(*this); 873b184f7f52b2a94e95aee326a3ca37110d2e43336reed 874b184f7f52b2a94e95aee326a3ca37110d2e43336reed // since we don't stop creating un-pixeled devices yet, check for no pixels here 875b184f7f52b2a94e95aee326a3ca37110d2e43336reed if (NULL == this->getPixels()) { 876b184f7f52b2a94e95aee326a3ca37110d2e43336reed return false; 877b184f7f52b2a94e95aee326a3ca37110d2e43336reed } 878b184f7f52b2a94e95aee326a3ca37110d2e43336reed 879e5ea500d4714a7d84de2bf913e81be3b65d2de68reed const SkImageInfo srcInfo = this->info().makeWH(dstInfo.width(), dstInfo.height()); 880b184f7f52b2a94e95aee326a3ca37110d2e43336reed 881b184f7f52b2a94e95aee326a3ca37110d2e43336reed const void* srcPixels = this->getAddr(srcR.x(), srcR.y()); 882b184f7f52b2a94e95aee326a3ca37110d2e43336reed return SkPixelInfo::CopyPixels(dstInfo, dstPixels, dstRB, srcInfo, srcPixels, this->rowBytes(), 883b184f7f52b2a94e95aee326a3ca37110d2e43336reed this->getColorTable()); 884b184f7f52b2a94e95aee326a3ca37110d2e43336reed} 885b184f7f52b2a94e95aee326a3ca37110d2e43336reed 886b184f7f52b2a94e95aee326a3ca37110d2e43336reedbool SkBitmap::copyTo(SkBitmap* dst, SkColorType dstColorType, Allocator* alloc) const { 8878a2ad3cae710f05cca57e48dd1732d575dba2dc7commit-bot@chromium.org if (!this->canCopyTo(dstColorType)) { 888fbaa88d9695347299321cbce2bf803726999fb58reed@android.com return false; 889fbaa88d9695347299321cbce2bf803726999fb58reed@android.com } 890fbaa88d9695347299321cbce2bf803726999fb58reed@android.com 89150dfa0130b0705414df7ba7da9915139f6320b09reed@google.com // if we have a texture, first get those pixels 89250dfa0130b0705414df7ba7da9915139f6320b09reed@google.com SkBitmap tmpSrc; 89350dfa0130b0705414df7ba7da9915139f6320b09reed@google.com const SkBitmap* src = this; 89450dfa0130b0705414df7ba7da9915139f6320b09reed@google.com 895a2a31928470dfb642880f6ab2e4d34b1c7f5d476scroggo@google.com if (fPixelRef) { 896a2a31928470dfb642880f6ab2e4d34b1c7f5d476scroggo@google.com SkIRect subset; 89761e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org subset.setXYWH(fPixelRefOrigin.fX, fPixelRefOrigin.fY, 89861e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org fInfo.width(), fInfo.height()); 899672588b684d484dce6ae251e9e163e4a46924322reed@google.com if (fPixelRef->readPixels(&tmpSrc, &subset)) { 9000187dc2155830c1ae3390d97463d5dd3971eca41scroggo if (fPixelRef->info().alphaType() == kUnpremul_SkAlphaType) { 9010187dc2155830c1ae3390d97463d5dd3971eca41scroggo // FIXME: The only meaningful implementation of readPixels 9020187dc2155830c1ae3390d97463d5dd3971eca41scroggo // (GrPixelRef) assumes premultiplied pixels. 9030187dc2155830c1ae3390d97463d5dd3971eca41scroggo return false; 9040187dc2155830c1ae3390d97463d5dd3971eca41scroggo } 905672588b684d484dce6ae251e9e163e4a46924322reed@google.com SkASSERT(tmpSrc.width() == this->width()); 906672588b684d484dce6ae251e9e163e4a46924322reed@google.com SkASSERT(tmpSrc.height() == this->height()); 907672588b684d484dce6ae251e9e163e4a46924322reed@google.com 908672588b684d484dce6ae251e9e163e4a46924322reed@google.com // did we get lucky and we can just return tmpSrc? 9098a2ad3cae710f05cca57e48dd1732d575dba2dc7commit-bot@chromium.org if (tmpSrc.colorType() == dstColorType && NULL == alloc) { 910672588b684d484dce6ae251e9e163e4a46924322reed@google.com dst->swap(tmpSrc); 9115ccae2c5b134d1b971c188215433305e88491aecscroggo@google.com // If the result is an exact copy, clone the gen ID. 9125ccae2c5b134d1b971c188215433305e88491aecscroggo@google.com if (dst->pixelRef() && dst->pixelRef()->info() == fPixelRef->info()) { 913672588b684d484dce6ae251e9e163e4a46924322reed@google.com dst->pixelRef()->cloneGenID(*fPixelRef); 914a2a31928470dfb642880f6ab2e4d34b1c7f5d476scroggo@google.com } 915672588b684d484dce6ae251e9e163e4a46924322reed@google.com return true; 916d5764e8ab731dd12df9293e52ce644eaa45333bdscroggo@google.com } 917672588b684d484dce6ae251e9e163e4a46924322reed@google.com 918672588b684d484dce6ae251e9e163e4a46924322reed@google.com // fall through to the raster case 919672588b684d484dce6ae251e9e163e4a46924322reed@google.com src = &tmpSrc; 92050dfa0130b0705414df7ba7da9915139f6320b09reed@google.com } 92150dfa0130b0705414df7ba7da9915139f6320b09reed@google.com } 92250dfa0130b0705414df7ba7da9915139f6320b09reed@google.com 923311c82db3115fc6810855cbcc42a6bc6fbd48265reed@android.com // we lock this now, since we may need its colortable 92450dfa0130b0705414df7ba7da9915139f6320b09reed@google.com SkAutoLockPixels srclock(*src); 92550dfa0130b0705414df7ba7da9915139f6320b09reed@google.com if (!src->readyToDraw()) { 926fbaa88d9695347299321cbce2bf803726999fb58reed@android.com return false; 927fbaa88d9695347299321cbce2bf803726999fb58reed@android.com } 928fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 9295ccae2c5b134d1b971c188215433305e88491aecscroggo@google.com // The only way to be readyToDraw is if fPixelRef is non NULL. 9305ccae2c5b134d1b971c188215433305e88491aecscroggo@google.com SkASSERT(fPixelRef != NULL); 9315ccae2c5b134d1b971c188215433305e88491aecscroggo@google.com 932e5ea500d4714a7d84de2bf913e81be3b65d2de68reed const SkImageInfo dstInfo = src->info().makeColorType(dstColorType); 9338a2ad3cae710f05cca57e48dd1732d575dba2dc7commit-bot@chromium.org 93450dfa0130b0705414df7ba7da9915139f6320b09reed@google.com SkBitmap tmpDst; 935a3264e53ee3f3c5d6a2c813df7e44b5b96d207f2commit-bot@chromium.org if (!tmpDst.setInfo(dstInfo)) { 9368a2ad3cae710f05cca57e48dd1732d575dba2dc7commit-bot@chromium.org return false; 9378a2ad3cae710f05cca57e48dd1732d575dba2dc7commit-bot@chromium.org } 938fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 939f9ab99aaade8c451c0e9309b4c61a448373019e3weita@google.com // allocate colortable if srcConfig == kIndex8_Config 9408a2ad3cae710f05cca57e48dd1732d575dba2dc7commit-bot@chromium.org SkAutoTUnref<SkColorTable> ctable; 9418a2ad3cae710f05cca57e48dd1732d575dba2dc7commit-bot@chromium.org if (dstColorType == kIndex_8_SkColorType) { 9428a2ad3cae710f05cca57e48dd1732d575dba2dc7commit-bot@chromium.org // TODO: can we just ref() the src colortable? Is it reentrant-safe? 9438a2ad3cae710f05cca57e48dd1732d575dba2dc7commit-bot@chromium.org ctable.reset(SkNEW_ARGS(SkColorTable, (*src->getColorTable()))); 9448a2ad3cae710f05cca57e48dd1732d575dba2dc7commit-bot@chromium.org } 945848250415eddc54075f7eb8795e8db79e749c6abreed if (!tmpDst.tryAllocPixels(alloc, ctable)) { 9468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return false; 9478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 948fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 94950dfa0130b0705414df7ba7da9915139f6320b09reed@google.com if (!tmpDst.readyToDraw()) { 9508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // allocator/lock failed 9518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return false; 9528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 953fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 9545ccae2c5b134d1b971c188215433305e88491aecscroggo@google.com // pixelRef must be non NULL or tmpDst.readyToDraw() would have 9555ccae2c5b134d1b971c188215433305e88491aecscroggo@google.com // returned false. 9565ccae2c5b134d1b971c188215433305e88491aecscroggo@google.com SkASSERT(tmpDst.pixelRef() != NULL); 9575ccae2c5b134d1b971c188215433305e88491aecscroggo@google.com 958b184f7f52b2a94e95aee326a3ca37110d2e43336reed if (!src->readPixels(tmpDst.info(), tmpDst.getPixels(), tmpDst.rowBytes(), 0, 0)) { 959b184f7f52b2a94e95aee326a3ca37110d2e43336reed return false; 960b184f7f52b2a94e95aee326a3ca37110d2e43336reed } 9610187dc2155830c1ae3390d97463d5dd3971eca41scroggo 962b184f7f52b2a94e95aee326a3ca37110d2e43336reed // (for BitmapHeap) Clone the pixelref genID even though we have a new pixelref. 963b184f7f52b2a94e95aee326a3ca37110d2e43336reed // The old copyTo impl did this, so we continue it for now. 964b184f7f52b2a94e95aee326a3ca37110d2e43336reed // 965b184f7f52b2a94e95aee326a3ca37110d2e43336reed // TODO: should we ignore rowbytes (i.e. getSize)? Then it could just be 966b184f7f52b2a94e95aee326a3ca37110d2e43336reed // if (src_pixelref->info == dst_pixelref->info) 967b184f7f52b2a94e95aee326a3ca37110d2e43336reed // 968b184f7f52b2a94e95aee326a3ca37110d2e43336reed if (src->colorType() == dstColorType && tmpDst.getSize() == src->getSize()) { 969b184f7f52b2a94e95aee326a3ca37110d2e43336reed SkPixelRef* dstPixelRef = tmpDst.pixelRef(); 970b184f7f52b2a94e95aee326a3ca37110d2e43336reed if (dstPixelRef->info() == fPixelRef->info()) { 971b184f7f52b2a94e95aee326a3ca37110d2e43336reed dstPixelRef->cloneGenID(*fPixelRef); 972311c82db3115fc6810855cbcc42a6bc6fbd48265reed@android.com } 9738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 9748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 97550dfa0130b0705414df7ba7da9915139f6320b09reed@google.com dst->swap(tmpDst); 9768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return true; 9778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 9788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 979fab349c0bf3a305b7a7388b77bab13b0f7b37393commit-bot@chromium.orgbool SkBitmap::deepCopyTo(SkBitmap* dst) const { 980e4538f5b46d70798e34eb078f5d5e76a59d02318reed const SkColorType dstCT = this->colorType(); 98161e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org 9828a2ad3cae710f05cca57e48dd1732d575dba2dc7commit-bot@chromium.org if (!this->canCopyTo(dstCT)) { 983ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org return false; 984ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org } 985ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org 986ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org // If we have a PixelRef, and it supports deep copy, use it. 987ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org // Currently supported only by texture-backed bitmaps. 988ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org if (fPixelRef) { 989e4538f5b46d70798e34eb078f5d5e76a59d02318reed SkPixelRef* pixelRef = fPixelRef->deepCopy(dstCT, NULL); 990eeef0cc49bf71e8b5e044d6a73b79cfe2b2c87b3commit-bot@chromium.org if (pixelRef) { 991eeef0cc49bf71e8b5e044d6a73b79cfe2b2c87b3commit-bot@chromium.org uint32_t rowBytes; 992eeef0cc49bf71e8b5e044d6a73b79cfe2b2c87b3commit-bot@chromium.org if (this->colorType() == dstCT) { 993eeef0cc49bf71e8b5e044d6a73b79cfe2b2c87b3commit-bot@chromium.org // Since there is no subset to pass to deepCopy, and deepCopy 994eeef0cc49bf71e8b5e044d6a73b79cfe2b2c87b3commit-bot@chromium.org // succeeded, the new pixel ref must be identical. 995eeef0cc49bf71e8b5e044d6a73b79cfe2b2c87b3commit-bot@chromium.org SkASSERT(fPixelRef->info() == pixelRef->info()); 996eeef0cc49bf71e8b5e044d6a73b79cfe2b2c87b3commit-bot@chromium.org pixelRef->cloneGenID(*fPixelRef); 997eeef0cc49bf71e8b5e044d6a73b79cfe2b2c87b3commit-bot@chromium.org // Use the same rowBytes as the original. 998eeef0cc49bf71e8b5e044d6a73b79cfe2b2c87b3commit-bot@chromium.org rowBytes = fRowBytes; 999eeef0cc49bf71e8b5e044d6a73b79cfe2b2c87b3commit-bot@chromium.org } else { 1000a3264e53ee3f3c5d6a2c813df7e44b5b96d207f2commit-bot@chromium.org // With the new config, an appropriate fRowBytes will be computed by setInfo. 1001eeef0cc49bf71e8b5e044d6a73b79cfe2b2c87b3commit-bot@chromium.org rowBytes = 0; 1002eeef0cc49bf71e8b5e044d6a73b79cfe2b2c87b3commit-bot@chromium.org } 1003eeef0cc49bf71e8b5e044d6a73b79cfe2b2c87b3commit-bot@chromium.org 1004e5ea500d4714a7d84de2bf913e81be3b65d2de68reed const SkImageInfo info = fInfo.makeColorType(dstCT); 1005a3264e53ee3f3c5d6a2c813df7e44b5b96d207f2commit-bot@chromium.org if (!dst->setInfo(info, rowBytes)) { 100661e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org return false; 100761e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org } 1008eeef0cc49bf71e8b5e044d6a73b79cfe2b2c87b3commit-bot@chromium.org dst->setPixelRef(pixelRef, fPixelRefOrigin)->unref(); 1009ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org return true; 1010ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org } 1011ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org } 1012ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org 1013ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org if (this->getTexture()) { 1014ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org return false; 1015ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org } else { 10168a2ad3cae710f05cca57e48dd1732d575dba2dc7commit-bot@chromium.org return this->copyTo(dst, dstCT, NULL); 1017ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org } 1018ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org} 1019ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org 10208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 10218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1022a87cd2af4c7f46ba8437c2e500805c9deb9e3a40tomhudson@google.comstatic bool GetBitmapAlpha(const SkBitmap& src, uint8_t* SK_RESTRICT alpha, 10238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int alphaRowBytes) { 10248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(alpha != NULL); 10258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(alphaRowBytes >= src.width()); 10268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1027cba73780bbd12fd254229517aec04fcbf0b64b52commit-bot@chromium.org SkColorType colorType = src.colorType(); 1028cba73780bbd12fd254229517aec04fcbf0b64b52commit-bot@chromium.org int w = src.width(); 1029cba73780bbd12fd254229517aec04fcbf0b64b52commit-bot@chromium.org int h = src.height(); 1030cba73780bbd12fd254229517aec04fcbf0b64b52commit-bot@chromium.org size_t rb = src.rowBytes(); 10318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 10321cdcb5138f9b70aff547ea1c3af96f0c90b12f8freed@android.com SkAutoLockPixels alp(src); 10331cdcb5138f9b70aff547ea1c3af96f0c90b12f8freed@android.com if (!src.readyToDraw()) { 10341cdcb5138f9b70aff547ea1c3af96f0c90b12f8freed@android.com // zero out the alpha buffer and return 10351cdcb5138f9b70aff547ea1c3af96f0c90b12f8freed@android.com while (--h >= 0) { 10361cdcb5138f9b70aff547ea1c3af96f0c90b12f8freed@android.com memset(alpha, 0, w); 10371cdcb5138f9b70aff547ea1c3af96f0c90b12f8freed@android.com alpha += alphaRowBytes; 10381cdcb5138f9b70aff547ea1c3af96f0c90b12f8freed@android.com } 10391cdcb5138f9b70aff547ea1c3af96f0c90b12f8freed@android.com return false; 10401cdcb5138f9b70aff547ea1c3af96f0c90b12f8freed@android.com } 104182065d667f64e232bcde2ad849756a6096fcbe6freed@google.com 1042cba73780bbd12fd254229517aec04fcbf0b64b52commit-bot@chromium.org if (kAlpha_8_SkColorType == colorType && !src.isOpaque()) { 10438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const uint8_t* s = src.getAddr8(0, 0); 10448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (--h >= 0) { 10458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com memcpy(alpha, s, w); 10468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com s += rb; 10478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com alpha += alphaRowBytes; 10488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1049cba73780bbd12fd254229517aec04fcbf0b64b52commit-bot@chromium.org } else if (kN32_SkColorType == colorType && !src.isOpaque()) { 10508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPMColor* SK_RESTRICT s = src.getAddr32(0, 0); 10518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (--h >= 0) { 10528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com for (int x = 0; x < w; x++) { 10538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com alpha[x] = SkGetPackedA32(s[x]); 10548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 10558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com s = (const SkPMColor*)((const char*)s + rb); 10568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com alpha += alphaRowBytes; 10578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1058cba73780bbd12fd254229517aec04fcbf0b64b52commit-bot@chromium.org } else if (kARGB_4444_SkColorType == colorType && !src.isOpaque()) { 10598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPMColor16* SK_RESTRICT s = src.getAddr16(0, 0); 10608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (--h >= 0) { 10618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com for (int x = 0; x < w; x++) { 10628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com alpha[x] = SkPacked4444ToA32(s[x]); 10638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 10648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com s = (const SkPMColor16*)((const char*)s + rb); 10658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com alpha += alphaRowBytes; 10668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1067cba73780bbd12fd254229517aec04fcbf0b64b52commit-bot@chromium.org } else if (kIndex_8_SkColorType == colorType && !src.isOpaque()) { 10688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkColorTable* ct = src.getColorTable(); 10698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (ct) { 10708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPMColor* SK_RESTRICT table = ct->lockColors(); 10718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const uint8_t* SK_RESTRICT s = src.getAddr8(0, 0); 10728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (--h >= 0) { 10738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com for (int x = 0; x < w; x++) { 10748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com alpha[x] = SkGetPackedA32(table[s[x]]); 10758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 10768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com s += rb; 10778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com alpha += alphaRowBytes; 10788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 10790a6151d66cc32d91eca037c91e557158cf8a2be2reed@google.com ct->unlockColors(); 10808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 10818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { // src is opaque, so just fill alpha[] with 0xFF 10828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com memset(alpha, 0xFF, h * alphaRowBytes); 10838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 10841cdcb5138f9b70aff547ea1c3af96f0c90b12f8freed@android.com return true; 10858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 10868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 10878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkPaint.h" 10888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkMaskFilter.h" 10898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkMatrix.h" 10908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1091cd9d69b9ce7eb301a9fd8d91b9f95fd99b07bae5djsollen@google.combool SkBitmap::extractAlpha(SkBitmap* dst, const SkPaint* paint, 109257f4969724a1dd88c8d9ae35a863e6cf621181d5djsollen@google.com Allocator *allocator, SkIPoint* offset) const { 10938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDEBUGCODE(this->validate();) 10948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1095cd9d69b9ce7eb301a9fd8d91b9f95fd99b07bae5djsollen@google.com SkBitmap tmpBitmap; 10968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkMatrix identity; 10978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkMask srcM, dstM; 10988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 10998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com srcM.fBounds.set(0, 0, this->width(), this->height()); 11008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com srcM.fRowBytes = SkAlign4(this->width()); 11018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com srcM.fFormat = SkMask::kA8_Format; 11028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 11038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkMaskFilter* filter = paint ? paint->getMaskFilter() : NULL; 11048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 11058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // compute our (larger?) dst bounds if we have a filter 110649f085dddff10473b6ebf832a974288300224e60bsalomon if (filter) { 11078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com identity.reset(); 11088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com srcM.fImage = NULL; 11098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (!filter->filterMask(&dstM, srcM, identity, NULL)) { 11108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com goto NO_FILTER_CASE; 11118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 11128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com dstM.fRowBytes = SkAlign4(dstM.fBounds.width()); 11138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 11148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com NO_FILTER_CASE: 1115a3264e53ee3f3c5d6a2c813df7e44b5b96d207f2commit-bot@chromium.org tmpBitmap.setInfo(SkImageInfo::MakeA8(this->width(), this->height()), srcM.fRowBytes); 1116848250415eddc54075f7eb8795e8db79e749c6abreed if (!tmpBitmap.tryAllocPixels(allocator, NULL)) { 1117cd9d69b9ce7eb301a9fd8d91b9f95fd99b07bae5djsollen@google.com // Allocation of pixels for alpha bitmap failed. 1118cd9d69b9ce7eb301a9fd8d91b9f95fd99b07bae5djsollen@google.com SkDebugf("extractAlpha failed to allocate (%d,%d) alpha bitmap\n", 1119cd9d69b9ce7eb301a9fd8d91b9f95fd99b07bae5djsollen@google.com tmpBitmap.width(), tmpBitmap.height()); 1120cd9d69b9ce7eb301a9fd8d91b9f95fd99b07bae5djsollen@google.com return false; 1121cd9d69b9ce7eb301a9fd8d91b9f95fd99b07bae5djsollen@google.com } 1122cd9d69b9ce7eb301a9fd8d91b9f95fd99b07bae5djsollen@google.com GetBitmapAlpha(*this, tmpBitmap.getAddr8(0, 0), srcM.fRowBytes); 11238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (offset) { 11248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com offset->set(0, 0); 11258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1126cd9d69b9ce7eb301a9fd8d91b9f95fd99b07bae5djsollen@google.com tmpBitmap.swap(*dst); 1127cd9d69b9ce7eb301a9fd8d91b9f95fd99b07bae5djsollen@google.com return true; 11288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 112902f55841854ae32f21a13417e9ee711463e488cfbungeman@google.com srcM.fImage = SkMask::AllocImage(srcM.computeImageSize()); 113002f55841854ae32f21a13417e9ee711463e488cfbungeman@google.com SkAutoMaskFreeImage srcCleanup(srcM.fImage); 11318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 11328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com GetBitmapAlpha(*this, srcM.fImage, srcM.fRowBytes); 11338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (!filter->filterMask(&dstM, srcM, identity, NULL)) { 11348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com goto NO_FILTER_CASE; 11358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 113602f55841854ae32f21a13417e9ee711463e488cfbungeman@google.com SkAutoMaskFreeImage dstCleanup(dstM.fImage); 11378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1138a3264e53ee3f3c5d6a2c813df7e44b5b96d207f2commit-bot@chromium.org tmpBitmap.setInfo(SkImageInfo::MakeA8(dstM.fBounds.width(), dstM.fBounds.height()), 1139a3264e53ee3f3c5d6a2c813df7e44b5b96d207f2commit-bot@chromium.org dstM.fRowBytes); 1140848250415eddc54075f7eb8795e8db79e749c6abreed if (!tmpBitmap.tryAllocPixels(allocator, NULL)) { 1141cd9d69b9ce7eb301a9fd8d91b9f95fd99b07bae5djsollen@google.com // Allocation of pixels for alpha bitmap failed. 1142cd9d69b9ce7eb301a9fd8d91b9f95fd99b07bae5djsollen@google.com SkDebugf("extractAlpha failed to allocate (%d,%d) alpha bitmap\n", 1143cd9d69b9ce7eb301a9fd8d91b9f95fd99b07bae5djsollen@google.com tmpBitmap.width(), tmpBitmap.height()); 1144cd9d69b9ce7eb301a9fd8d91b9f95fd99b07bae5djsollen@google.com return false; 1145cd9d69b9ce7eb301a9fd8d91b9f95fd99b07bae5djsollen@google.com } 1146cd9d69b9ce7eb301a9fd8d91b9f95fd99b07bae5djsollen@google.com memcpy(tmpBitmap.getPixels(), dstM.fImage, dstM.computeImageSize()); 11478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (offset) { 11488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com offset->set(dstM.fBounds.fLeft, dstM.fBounds.fTop); 11498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1150cd9d69b9ce7eb301a9fd8d91b9f95fd99b07bae5djsollen@google.com SkDEBUGCODE(tmpBitmap.validate();) 1151cd9d69b9ce7eb301a9fd8d91b9f95fd99b07bae5djsollen@google.com 1152cd9d69b9ce7eb301a9fd8d91b9f95fd99b07bae5djsollen@google.com tmpBitmap.swap(*dst); 1153cd9d69b9ce7eb301a9fd8d91b9f95fd99b07bae5djsollen@google.com return true; 11548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 11558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 11568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 11578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1158968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.orgvoid SkBitmap::WriteRawPixels(SkWriteBuffer* buffer, const SkBitmap& bitmap) { 1159968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org const SkImageInfo info = bitmap.info(); 1160968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org SkAutoLockPixels alp(bitmap); 1161968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org if (0 == info.width() || 0 == info.height() || NULL == bitmap.getPixels()) { 1162968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org buffer->writeUInt(0); // instead of snugRB, signaling no pixels 1163968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org return; 1164968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org } 1165968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org 1166968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org const size_t snugRB = info.width() * info.bytesPerPixel(); 1167968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org const char* src = (const char*)bitmap.getPixels(); 1168968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org const size_t ramRB = bitmap.rowBytes(); 11693c134a97ed128ca95345e13619512df0f42e95f8skia.committer@gmail.com 1170968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org buffer->write32(SkToU32(snugRB)); 1171968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org info.flatten(*buffer); 1172968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org 1173968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org const size_t size = snugRB * info.height(); 1174968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org SkAutoMalloc storage(size); 1175968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org char* dst = (char*)storage.get(); 1176968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org for (int y = 0; y < info.height(); ++y) { 1177968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org memcpy(dst, src, snugRB); 1178968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org dst += snugRB; 1179968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org src += ramRB; 1180968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org } 1181968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org buffer->writeByteArray(storage.get(), size); 1182968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org 1183968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org SkColorTable* ct = bitmap.getColorTable(); 1184968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org if (kIndex_8_SkColorType == info.colorType() && ct) { 1185968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org buffer->writeBool(true); 1186968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org ct->writeToBuffer(*buffer); 1187968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org } else { 1188968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org buffer->writeBool(false); 1189968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org } 1190968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org} 1191968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org 1192968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.orgbool SkBitmap::ReadRawPixels(SkReadBuffer* buffer, SkBitmap* bitmap) { 1193968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org const size_t snugRB = buffer->readUInt(); 1194968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org if (0 == snugRB) { // no pixels 1195968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org return false; 1196968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org } 1197968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org 1198968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org SkImageInfo info; 1199968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org info.unflatten(*buffer); 1200968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org 1201ca95c19d27b505a1ac8f57b53cb49c198bc29267sugoi // If there was an error reading "info", don't use it to compute minRowBytes() 1202ca95c19d27b505a1ac8f57b53cb49c198bc29267sugoi if (!buffer->validate(true)) { 1203ca95c19d27b505a1ac8f57b53cb49c198bc29267sugoi return false; 1204ca95c19d27b505a1ac8f57b53cb49c198bc29267sugoi } 1205ca95c19d27b505a1ac8f57b53cb49c198bc29267sugoi 1206968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org const size_t ramRB = info.minRowBytes(); 1207968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org const int height = info.height(); 1208968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org const size_t snugSize = snugRB * height; 1209968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org const size_t ramSize = ramRB * height; 121005858435ee8744de863be7e5ade05e4fd6edfb46commit-bot@chromium.org if (!buffer->validate(snugSize <= ramSize)) { 121105858435ee8744de863be7e5ade05e4fd6edfb46commit-bot@chromium.org return false; 121205858435ee8744de863be7e5ade05e4fd6edfb46commit-bot@chromium.org } 1213968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org 121433a30503d76fdd989358cedd78445ba96bb809ddreed SkAutoDataUnref data(SkData::NewUninitialized(ramSize)); 121533a30503d76fdd989358cedd78445ba96bb809ddreed char* dst = (char*)data->writable_data(); 1216968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org buffer->readByteArray(dst, snugSize); 1217968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org 1218968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org if (snugSize != ramSize) { 1219968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org const char* srcRow = dst + snugRB * (height - 1); 1220968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org char* dstRow = dst + ramRB * (height - 1); 1221968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org for (int y = height - 1; y >= 1; --y) { 1222968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org memmove(dstRow, srcRow, snugRB); 1223968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org srcRow -= snugRB; 1224968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org dstRow -= ramRB; 1225968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org } 1226968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org SkASSERT(srcRow == dstRow); // first row does not need to be moved 1227968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org } 12283c134a97ed128ca95345e13619512df0f42e95f8skia.committer@gmail.com 1229968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org SkAutoTUnref<SkColorTable> ctable; 1230968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org if (buffer->readBool()) { 1231968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org ctable.reset(SkNEW_ARGS(SkColorTable, (*buffer))); 1232968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org } 12333c134a97ed128ca95345e13619512df0f42e95f8skia.committer@gmail.com 1234968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org SkAutoTUnref<SkPixelRef> pr(SkMallocPixelRef::NewWithData(info, info.minRowBytes(), 1235968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org ctable.get(), data.get())); 1236a3264e53ee3f3c5d6a2c813df7e44b5b96d207f2commit-bot@chromium.org bitmap->setInfo(pr->info()); 1237968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org bitmap->setPixelRef(pr, 0, 0); 1238968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org return true; 1239968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org} 1240968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org 12418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comenum { 12428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SERIALIZE_PIXELTYPE_NONE, 124321830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com SERIALIZE_PIXELTYPE_REF_DATA 12448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 12458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1246851155c28e18e3f5b702ef15ee7bfb12f3cbacdacommit-bot@chromium.orgvoid SkBitmap::legacyUnflatten(SkReadBuffer& buffer) { 12479a9eae21ed5235869702a66d6decddd6643792c3reed#ifdef SK_SUPPORT_LEGACY_PIXELREF_UNFLATTENABLE 12488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->reset(); 1249f9ab99aaade8c451c0e9309b4c61a448373019e3weita@google.com 125061e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org SkImageInfo info; 125161e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org info.unflatten(buffer); 125261e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org size_t rowBytes = buffer.readInt(); 125333fed14b1d4867015ac518874013e0b3e06ea982commit-bot@chromium.org if (!buffer.validate((info.width() >= 0) && (info.height() >= 0) && 125433fed14b1d4867015ac518874013e0b3e06ea982commit-bot@chromium.org SkColorTypeIsValid(info.fColorType) && 125533fed14b1d4867015ac518874013e0b3e06ea982commit-bot@chromium.org SkAlphaTypeIsValid(info.fAlphaType) && 12562fd0d14b9be34a7a945942733c3516d97d07f516scroggo SkColorTypeValidateAlphaType(info.fColorType, info.fAlphaType) && 125733fed14b1d4867015ac518874013e0b3e06ea982commit-bot@chromium.org info.validRowBytes(rowBytes))) { 125833fed14b1d4867015ac518874013e0b3e06ea982commit-bot@chromium.org return; 125933fed14b1d4867015ac518874013e0b3e06ea982commit-bot@chromium.org } 1260f9ab99aaade8c451c0e9309b4c61a448373019e3weita@google.com 1261a3264e53ee3f3c5d6a2c813df7e44b5b96d207f2commit-bot@chromium.org bool configIsValid = this->setInfo(info, rowBytes); 126261e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org buffer.validate(configIsValid); 1263f9ab99aaade8c451c0e9309b4c61a448373019e3weita@google.com 1264c73dd5c6880739f26216f198c757028fd28df1a4djsollen@google.com int reftype = buffer.readInt(); 1265ce33d60187718e7bb01944ee130c9f5d9fb335eccommit-bot@chromium.org if (buffer.validate((SERIALIZE_PIXELTYPE_REF_DATA == reftype) || 1266ce33d60187718e7bb01944ee130c9f5d9fb335eccommit-bot@chromium.org (SERIALIZE_PIXELTYPE_NONE == reftype))) { 1267ce33d60187718e7bb01944ee130c9f5d9fb335eccommit-bot@chromium.org switch (reftype) { 1268ce33d60187718e7bb01944ee130c9f5d9fb335eccommit-bot@chromium.org case SERIALIZE_PIXELTYPE_REF_DATA: { 1269672588b684d484dce6ae251e9e163e4a46924322reed@google.com SkIPoint origin; 1270672588b684d484dce6ae251e9e163e4a46924322reed@google.com origin.fX = buffer.readInt(); 1271672588b684d484dce6ae251e9e163e4a46924322reed@google.com origin.fY = buffer.readInt(); 127261e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org size_t offset = origin.fY * rowBytes + origin.fX * info.bytesPerPixel(); 12739a9eae21ed5235869702a66d6decddd6643792c3reed SkPixelRef* pr = buffer.readFlattenable<SkPixelRef>(); 1274cd3b15ca6364a04b0eeeb4f89c7daa8aefe854c8commit-bot@chromium.org if (!buffer.validate((NULL == pr) || 1275cd3b15ca6364a04b0eeeb4f89c7daa8aefe854c8commit-bot@chromium.org (pr->getAllocatedSizeInBytes() >= (offset + this->getSafeSize())))) { 1276672588b684d484dce6ae251e9e163e4a46924322reed@google.com origin.setZero(); 1277cd3b15ca6364a04b0eeeb4f89c7daa8aefe854c8commit-bot@chromium.org } 1278672588b684d484dce6ae251e9e163e4a46924322reed@google.com SkSafeUnref(this->setPixelRef(pr, origin)); 1279ce33d60187718e7bb01944ee130c9f5d9fb335eccommit-bot@chromium.org break; 1280ce33d60187718e7bb01944ee130c9f5d9fb335eccommit-bot@chromium.org } 1281ce33d60187718e7bb01944ee130c9f5d9fb335eccommit-bot@chromium.org case SERIALIZE_PIXELTYPE_NONE: 1282ce33d60187718e7bb01944ee130c9f5d9fb335eccommit-bot@chromium.org break; 1283ce33d60187718e7bb01944ee130c9f5d9fb335eccommit-bot@chromium.org default: 1284ce33d60187718e7bb01944ee130c9f5d9fb335eccommit-bot@chromium.org SkDEBUGFAIL("unrecognized pixeltype in serialized data"); 1285ce33d60187718e7bb01944ee130c9f5d9fb335eccommit-bot@chromium.org sk_throw(); 12868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 12878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 12889a9eae21ed5235869702a66d6decddd6643792c3reed#else 12899a9eae21ed5235869702a66d6decddd6643792c3reed sk_throw(); 12909a9eae21ed5235869702a66d6decddd6643792c3reed#endif 12918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 12928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 12938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 12948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 12958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkBitmap::RLEPixels::RLEPixels(int width, int height) { 12968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fHeight = height; 1297235002fb127fc5b7564910434faed84337c08238commit-bot@chromium.org fYPtrs = (uint8_t**)sk_calloc_throw(height * sizeof(uint8_t*)); 12988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 12998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 13008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkBitmap::RLEPixels::~RLEPixels() { 13018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com sk_free(fYPtrs); 13028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 13038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 13048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 13058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 13068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifdef SK_DEBUG 13078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkBitmap::validate() const { 130861e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org fInfo.validate(); 1309d5414e5efe0a6a0bce0b5499e2358e2be4cb9b61commit-bot@chromium.org 1310d5414e5efe0a6a0bce0b5499e2358e2be4cb9b61commit-bot@chromium.org // ImageInfo may not require this, but Bitmap ensures that opaque-only 1311d5414e5efe0a6a0bce0b5499e2358e2be4cb9b61commit-bot@chromium.org // colorTypes report opaque for their alphatype 1312d5414e5efe0a6a0bce0b5499e2358e2be4cb9b61commit-bot@chromium.org if (kRGB_565_SkColorType == fInfo.colorType()) { 1313d5414e5efe0a6a0bce0b5499e2358e2be4cb9b61commit-bot@chromium.org SkASSERT(kOpaque_SkAlphaType == fInfo.alphaType()); 1314d5414e5efe0a6a0bce0b5499e2358e2be4cb9b61commit-bot@chromium.org } 1315d5414e5efe0a6a0bce0b5499e2358e2be4cb9b61commit-bot@chromium.org 131661e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org SkASSERT(fInfo.validRowBytes(fRowBytes)); 13170847059fcffe11d53d4ea803ba2d51c696eb6d07scroggo uint8_t allFlags = kImageIsVolatile_Flag; 13188e990eb440e0f61386ba21b06b8428d5b285c341scroggo@google.com#ifdef SK_BUILD_FOR_ANDROID 13198e990eb440e0f61386ba21b06b8428d5b285c341scroggo@google.com allFlags |= kHasHardwareMipMap_Flag; 13208e990eb440e0f61386ba21b06b8428d5b285c341scroggo@google.com#endif 13210847059fcffe11d53d4ea803ba2d51c696eb6d07scroggo SkASSERT((~allFlags & fFlags) == 0); 13228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(fPixelLockCount >= 0); 13238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1324615316cefbf16382f6a99c72d88a13d2be1d2408reed@google.com if (fPixels) { 1325615316cefbf16382f6a99c72d88a13d2be1d2408reed@google.com SkASSERT(fPixelRef); 1326615316cefbf16382f6a99c72d88a13d2be1d2408reed@google.com SkASSERT(fPixelLockCount > 0); 1327615316cefbf16382f6a99c72d88a13d2be1d2408reed@google.com SkASSERT(fPixelRef->isLocked()); 1328615316cefbf16382f6a99c72d88a13d2be1d2408reed@google.com SkASSERT(fPixelRef->rowBytes() == fRowBytes); 1329615316cefbf16382f6a99c72d88a13d2be1d2408reed@google.com SkASSERT(fPixelRefOrigin.fX >= 0); 1330615316cefbf16382f6a99c72d88a13d2be1d2408reed@google.com SkASSERT(fPixelRefOrigin.fY >= 0); 133161e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org SkASSERT(fPixelRef->info().width() >= (int)this->width() + fPixelRefOrigin.fX); 1332e5ea500d4714a7d84de2bf913e81be3b65d2de68reed SkASSERT(fPixelRef->info().height() >= (int)this->height() + fPixelRefOrigin.fY); 133361e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org SkASSERT(fPixelRef->rowBytes() >= fInfo.minRowBytes()); 1334615316cefbf16382f6a99c72d88a13d2be1d2408reed@google.com } else { 1335615316cefbf16382f6a99c72d88a13d2be1d2408reed@google.com SkASSERT(NULL == fColorTable); 13368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 13378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 13388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 133976f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com 13400f10f7bf1fb43ca6346dc220a076773b1f19a367commit-bot@chromium.org#ifndef SK_IGNORE_TO_STRING 134176f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.comvoid SkBitmap::toString(SkString* str) const { 134276f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com 1343cba73780bbd12fd254229517aec04fcbf0b64b52commit-bot@chromium.org static const char* gColorTypeNames[kLastEnum_SkColorType + 1] = { 1344cba73780bbd12fd254229517aec04fcbf0b64b52commit-bot@chromium.org "UNKNOWN", "A8", "565", "4444", "RGBA", "BGRA", "INDEX8", 134576f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com }; 134676f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com 134776f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com str->appendf("bitmap: ((%d, %d) %s", this->width(), this->height(), 1348cba73780bbd12fd254229517aec04fcbf0b64b52commit-bot@chromium.org gColorTypeNames[this->colorType()]); 134976f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com 135076f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com str->append(" ("); 135176f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com if (this->isOpaque()) { 135276f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com str->append("opaque"); 135376f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com } else { 135476f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com str->append("transparent"); 135576f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com } 135676f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com if (this->isImmutable()) { 135776f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com str->append(", immutable"); 135876f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com } else { 135976f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com str->append(", not-immutable"); 136076f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com } 136176f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com str->append(")"); 136276f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com 136376f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com SkPixelRef* pr = this->pixelRef(); 136476f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com if (NULL == pr) { 136576f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com // show null or the explicit pixel address (rare) 136676f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com str->appendf(" pixels:%p", this->getPixels()); 136776f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com } else { 136876f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com const char* uri = pr->getURI(); 136949f085dddff10473b6ebf832a974288300224e60bsalomon if (uri) { 137076f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com str->appendf(" uri:\"%s\"", uri); 137176f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com } else { 137276f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com str->appendf(" pixelref:%p", pr); 137376f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com } 137476f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com } 137576f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com 137676f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com str->append(")"); 137776f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com} 137876f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com#endif 137961e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org 138061e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org/////////////////////////////////////////////////////////////////////////////// 138161e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org 138261e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org#ifdef SK_DEBUG 138361e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.orgvoid SkImageInfo::validate() const { 138461e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org SkASSERT(fWidth >= 0); 138561e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org SkASSERT(fHeight >= 0); 138661e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org SkASSERT(SkColorTypeIsValid(fColorType)); 138761e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org SkASSERT(SkAlphaTypeIsValid(fAlphaType)); 138861e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org} 138961e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org#endif 1390