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()) { 18544977485bdac75c055c3fa638f118874ccd2d22freed case kUnknown_SkAlphaType: 18644977485bdac75c055c3fa638f118874ccd2d22freed SkASSERT(fInfo.alphaType() == kUnknown_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 } 287775b8199a214af57c3ea7969e9d456f5f3eb137fmtklein 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; 294775b8199a214af57c3ea7969e9d456f5f3eb137fmtklein 295f0aed97aec3fa1c7f6460d8d6327358f3dcbabe6reed SkPixelRef* pr = defaultFactory.create(correctedInfo, rowBytes, NULL); 296bae704b050491a8a98c67cb23eaccb10852d2bd5reed if (NULL == pr) { 297bae704b050491a8a98c67cb23eaccb10852d2bd5reed return reset_return_false(this); 298bae704b050491a8a98c67cb23eaccb10852d2bd5reed } 299bae704b050491a8a98c67cb23eaccb10852d2bd5reed this->setPixelRef(pr)->unref(); 300775b8199a214af57c3ea7969e9d456f5f3eb137fmtklein 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: 5190c9b1a8d05ea6ec5dfae0ead854304673d94d2c2reed case kGray_8_SkColorType: 5208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com base += x; 5218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com break; 5228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com default: 5230c00f21fee3f5cfa3aa7e5d46ff94cb8cf340451tomhudson@google.com SkDEBUGFAIL("Can't return addr for config"); 5248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com base = NULL; 5258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com break; 5268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 5278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 5288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return base; 5298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 5308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 531112706d4c566e283890322bb246b4b86d59837e1vandebo@chromium.orgSkColor SkBitmap::getColor(int x, int y) const { 532112706d4c566e283890322bb246b4b86d59837e1vandebo@chromium.org SkASSERT((unsigned)x < (unsigned)this->width()); 533112706d4c566e283890322bb246b4b86d59837e1vandebo@chromium.org SkASSERT((unsigned)y < (unsigned)this->height()); 534112706d4c566e283890322bb246b4b86d59837e1vandebo@chromium.org 535cba73780bbd12fd254229517aec04fcbf0b64b52commit-bot@chromium.org switch (this->colorType()) { 5360c9b1a8d05ea6ec5dfae0ead854304673d94d2c2reed case kGray_8_SkColorType: { 5370c9b1a8d05ea6ec5dfae0ead854304673d94d2c2reed uint8_t* addr = this->getAddr8(x, y); 5380c9b1a8d05ea6ec5dfae0ead854304673d94d2c2reed return SkColorSetRGB(*addr, *addr, *addr); 5390c9b1a8d05ea6ec5dfae0ead854304673d94d2c2reed } 540cba73780bbd12fd254229517aec04fcbf0b64b52commit-bot@chromium.org case kAlpha_8_SkColorType: { 5413b521d05335a1bf76be3456feb9dbfba0a51b339reed@google.com uint8_t* addr = this->getAddr8(x, y); 542112706d4c566e283890322bb246b4b86d59837e1vandebo@chromium.org return SkColorSetA(0, addr[0]); 543112706d4c566e283890322bb246b4b86d59837e1vandebo@chromium.org } 544cba73780bbd12fd254229517aec04fcbf0b64b52commit-bot@chromium.org case kIndex_8_SkColorType: { 5453b521d05335a1bf76be3456feb9dbfba0a51b339reed@google.com SkPMColor c = this->getIndex8Color(x, y); 546112706d4c566e283890322bb246b4b86d59837e1vandebo@chromium.org return SkUnPreMultiply::PMColorToColor(c); 547112706d4c566e283890322bb246b4b86d59837e1vandebo@chromium.org } 548cba73780bbd12fd254229517aec04fcbf0b64b52commit-bot@chromium.org case kRGB_565_SkColorType: { 5493b521d05335a1bf76be3456feb9dbfba0a51b339reed@google.com uint16_t* addr = this->getAddr16(x, y); 550112706d4c566e283890322bb246b4b86d59837e1vandebo@chromium.org return SkPixel16ToColor(addr[0]); 551112706d4c566e283890322bb246b4b86d59837e1vandebo@chromium.org } 552cba73780bbd12fd254229517aec04fcbf0b64b52commit-bot@chromium.org case kARGB_4444_SkColorType: { 5533b521d05335a1bf76be3456feb9dbfba0a51b339reed@google.com uint16_t* addr = this->getAddr16(x, y); 554112706d4c566e283890322bb246b4b86d59837e1vandebo@chromium.org SkPMColor c = SkPixel4444ToPixel32(addr[0]); 555112706d4c566e283890322bb246b4b86d59837e1vandebo@chromium.org return SkUnPreMultiply::PMColorToColor(c); 556112706d4c566e283890322bb246b4b86d59837e1vandebo@chromium.org } 557cba73780bbd12fd254229517aec04fcbf0b64b52commit-bot@chromium.org case kBGRA_8888_SkColorType: 558cba73780bbd12fd254229517aec04fcbf0b64b52commit-bot@chromium.org case kRGBA_8888_SkColorType: { 5593b521d05335a1bf76be3456feb9dbfba0a51b339reed@google.com uint32_t* addr = this->getAddr32(x, y); 560112706d4c566e283890322bb246b4b86d59837e1vandebo@chromium.org return SkUnPreMultiply::PMColorToColor(addr[0]); 561112706d4c566e283890322bb246b4b86d59837e1vandebo@chromium.org } 562d6bab0238655dbab24dfe92bd0b16b464310a8c7rmistry@google.com default: 563112706d4c566e283890322bb246b4b86d59837e1vandebo@chromium.org SkASSERT(false); 564112706d4c566e283890322bb246b4b86d59837e1vandebo@chromium.org return 0; 565112706d4c566e283890322bb246b4b86d59837e1vandebo@chromium.org } 566112706d4c566e283890322bb246b4b86d59837e1vandebo@chromium.org SkASSERT(false); // Not reached. 567112706d4c566e283890322bb246b4b86d59837e1vandebo@chromium.org return 0; 568112706d4c566e283890322bb246b4b86d59837e1vandebo@chromium.org} 569112706d4c566e283890322bb246b4b86d59837e1vandebo@chromium.org 5702a7579d11796866b0026755ab52597d09f4509ccreed@google.combool SkBitmap::ComputeIsOpaque(const SkBitmap& bm) { 5712a7579d11796866b0026755ab52597d09f4509ccreed@google.com SkAutoLockPixels alp(bm); 5722a7579d11796866b0026755ab52597d09f4509ccreed@google.com if (!bm.getPixels()) { 5732a7579d11796866b0026755ab52597d09f4509ccreed@google.com return false; 5742a7579d11796866b0026755ab52597d09f4509ccreed@google.com } 5752a7579d11796866b0026755ab52597d09f4509ccreed@google.com 5762a7579d11796866b0026755ab52597d09f4509ccreed@google.com const int height = bm.height(); 5772a7579d11796866b0026755ab52597d09f4509ccreed@google.com const int width = bm.width(); 5782a7579d11796866b0026755ab52597d09f4509ccreed@google.com 579cba73780bbd12fd254229517aec04fcbf0b64b52commit-bot@chromium.org switch (bm.colorType()) { 580cba73780bbd12fd254229517aec04fcbf0b64b52commit-bot@chromium.org case kAlpha_8_SkColorType: { 5812a7579d11796866b0026755ab52597d09f4509ccreed@google.com unsigned a = 0xFF; 5822a7579d11796866b0026755ab52597d09f4509ccreed@google.com for (int y = 0; y < height; ++y) { 5832a7579d11796866b0026755ab52597d09f4509ccreed@google.com const uint8_t* row = bm.getAddr8(0, y); 5842a7579d11796866b0026755ab52597d09f4509ccreed@google.com for (int x = 0; x < width; ++x) { 5852a7579d11796866b0026755ab52597d09f4509ccreed@google.com a &= row[x]; 5862a7579d11796866b0026755ab52597d09f4509ccreed@google.com } 5872a7579d11796866b0026755ab52597d09f4509ccreed@google.com if (0xFF != a) { 5882a7579d11796866b0026755ab52597d09f4509ccreed@google.com return false; 5892a7579d11796866b0026755ab52597d09f4509ccreed@google.com } 5902a7579d11796866b0026755ab52597d09f4509ccreed@google.com } 5912a7579d11796866b0026755ab52597d09f4509ccreed@google.com return true; 5922a7579d11796866b0026755ab52597d09f4509ccreed@google.com } break; 593cba73780bbd12fd254229517aec04fcbf0b64b52commit-bot@chromium.org case kIndex_8_SkColorType: { 594775b8199a214af57c3ea7969e9d456f5f3eb137fmtklein if (!bm.getColorTable()) { 5952a7579d11796866b0026755ab52597d09f4509ccreed@google.com return false; 5962a7579d11796866b0026755ab52597d09f4509ccreed@google.com } 597775b8199a214af57c3ea7969e9d456f5f3eb137fmtklein const SkPMColor* table = bm.getColorTable()->readColors(); 598140d7286c5a40058932696eaa28818c313bd2ddfreed@google.com SkPMColor c = (SkPMColor)~0; 5992a7579d11796866b0026755ab52597d09f4509ccreed@google.com for (int i = bm.getColorTable()->count() - 1; i >= 0; --i) { 6002a7579d11796866b0026755ab52597d09f4509ccreed@google.com c &= table[i]; 6012a7579d11796866b0026755ab52597d09f4509ccreed@google.com } 6022a7579d11796866b0026755ab52597d09f4509ccreed@google.com return 0xFF == SkGetPackedA32(c); 6032a7579d11796866b0026755ab52597d09f4509ccreed@google.com } break; 604cba73780bbd12fd254229517aec04fcbf0b64b52commit-bot@chromium.org case kRGB_565_SkColorType: 6050c9b1a8d05ea6ec5dfae0ead854304673d94d2c2reed case kGray_8_SkColorType: 6062a7579d11796866b0026755ab52597d09f4509ccreed@google.com return true; 6072a7579d11796866b0026755ab52597d09f4509ccreed@google.com break; 608cba73780bbd12fd254229517aec04fcbf0b64b52commit-bot@chromium.org case kARGB_4444_SkColorType: { 6092a7579d11796866b0026755ab52597d09f4509ccreed@google.com unsigned c = 0xFFFF; 6102a7579d11796866b0026755ab52597d09f4509ccreed@google.com for (int y = 0; y < height; ++y) { 6112a7579d11796866b0026755ab52597d09f4509ccreed@google.com const SkPMColor16* row = bm.getAddr16(0, y); 6122a7579d11796866b0026755ab52597d09f4509ccreed@google.com for (int x = 0; x < width; ++x) { 6132a7579d11796866b0026755ab52597d09f4509ccreed@google.com c &= row[x]; 6142a7579d11796866b0026755ab52597d09f4509ccreed@google.com } 6152a7579d11796866b0026755ab52597d09f4509ccreed@google.com if (0xF != SkGetPackedA4444(c)) { 6162a7579d11796866b0026755ab52597d09f4509ccreed@google.com return false; 6172a7579d11796866b0026755ab52597d09f4509ccreed@google.com } 6182a7579d11796866b0026755ab52597d09f4509ccreed@google.com } 6192a7579d11796866b0026755ab52597d09f4509ccreed@google.com return true; 6202a7579d11796866b0026755ab52597d09f4509ccreed@google.com } break; 621cba73780bbd12fd254229517aec04fcbf0b64b52commit-bot@chromium.org case kBGRA_8888_SkColorType: 622cba73780bbd12fd254229517aec04fcbf0b64b52commit-bot@chromium.org case kRGBA_8888_SkColorType: { 623140d7286c5a40058932696eaa28818c313bd2ddfreed@google.com SkPMColor c = (SkPMColor)~0; 6242a7579d11796866b0026755ab52597d09f4509ccreed@google.com for (int y = 0; y < height; ++y) { 6252a7579d11796866b0026755ab52597d09f4509ccreed@google.com const SkPMColor* row = bm.getAddr32(0, y); 6262a7579d11796866b0026755ab52597d09f4509ccreed@google.com for (int x = 0; x < width; ++x) { 6272a7579d11796866b0026755ab52597d09f4509ccreed@google.com c &= row[x]; 6282a7579d11796866b0026755ab52597d09f4509ccreed@google.com } 6292a7579d11796866b0026755ab52597d09f4509ccreed@google.com if (0xFF != SkGetPackedA32(c)) { 6302a7579d11796866b0026755ab52597d09f4509ccreed@google.com return false; 6312a7579d11796866b0026755ab52597d09f4509ccreed@google.com } 6322a7579d11796866b0026755ab52597d09f4509ccreed@google.com } 6332a7579d11796866b0026755ab52597d09f4509ccreed@google.com return true; 6342a7579d11796866b0026755ab52597d09f4509ccreed@google.com } 6352a7579d11796866b0026755ab52597d09f4509ccreed@google.com default: 6362a7579d11796866b0026755ab52597d09f4509ccreed@google.com break; 6372a7579d11796866b0026755ab52597d09f4509ccreed@google.com } 6382a7579d11796866b0026755ab52597d09f4509ccreed@google.com return false; 6392a7579d11796866b0026755ab52597d09f4509ccreed@google.com} 6402a7579d11796866b0026755ab52597d09f4509ccreed@google.com 6412a7579d11796866b0026755ab52597d09f4509ccreed@google.com 6428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 6438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 6448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 64545f746f521d6925d22a304921f6e17196f4f8157reed@google.comstatic uint16_t pack_8888_to_4444(unsigned a, unsigned r, unsigned g, unsigned b) { 64645f746f521d6925d22a304921f6e17196f4f8157reed@google.com unsigned pixel = (SkA32To4444(a) << SK_A4444_SHIFT) | 64745f746f521d6925d22a304921f6e17196f4f8157reed@google.com (SkR32To4444(r) << SK_R4444_SHIFT) | 64845f746f521d6925d22a304921f6e17196f4f8157reed@google.com (SkG32To4444(g) << SK_G4444_SHIFT) | 64945f746f521d6925d22a304921f6e17196f4f8157reed@google.com (SkB32To4444(b) << SK_B4444_SHIFT); 65045f746f521d6925d22a304921f6e17196f4f8157reed@google.com return SkToU16(pixel); 65145f746f521d6925d22a304921f6e17196f4f8157reed@google.com} 65245f746f521d6925d22a304921f6e17196f4f8157reed@google.com 65360d3235ab42bd1d32a070695ee30d6e3ec2fa222reed@google.comvoid SkBitmap::internalErase(const SkIRect& area, 65460d3235ab42bd1d32a070695ee30d6e3ec2fa222reed@google.com U8CPU a, U8CPU r, U8CPU g, U8CPU b) const { 65560d3235ab42bd1d32a070695ee30d6e3ec2fa222reed@google.com#ifdef SK_DEBUG 6568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDEBUGCODE(this->validate();) 65760d3235ab42bd1d32a070695ee30d6e3ec2fa222reed@google.com SkASSERT(!area.isEmpty()); 65860d3235ab42bd1d32a070695ee30d6e3ec2fa222reed@google.com { 65992833f99b99f1f955c350f6f4f70acd3356a79a5reed@google.com SkIRect total = { 0, 0, this->width(), this->height() }; 66060d3235ab42bd1d32a070695ee30d6e3ec2fa222reed@google.com SkASSERT(total.contains(area)); 66160d3235ab42bd1d32a070695ee30d6e3ec2fa222reed@google.com } 66260d3235ab42bd1d32a070695ee30d6e3ec2fa222reed@google.com#endif 6638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 66461e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org switch (fInfo.colorType()) { 66561e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org case kUnknown_SkColorType: 66661e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org case kIndex_8_SkColorType: 6677669a77cd16fbab3618ca1f1a03bcfa05a93c447commit-bot@chromium.org return; // can't erase. Should we bzero so the memory is not uninitialized? 66861e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org default: 66961e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org break; 6708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 6718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 6728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkAutoLockPixels alp(*this); 6738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // perform this check after the lock call 6748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (!this->readyToDraw()) { 6758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 6768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 6778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 67860d3235ab42bd1d32a070695ee30d6e3ec2fa222reed@google.com int height = area.height(); 67960d3235ab42bd1d32a070695ee30d6e3ec2fa222reed@google.com const int width = area.width(); 6808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const int rowBytes = fRowBytes; 6818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 68261e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org switch (this->colorType()) { 6830c9b1a8d05ea6ec5dfae0ead854304673d94d2c2reed case kGray_8_SkColorType: { 6840c9b1a8d05ea6ec5dfae0ead854304673d94d2c2reed if (255 != a) { 6850c9b1a8d05ea6ec5dfae0ead854304673d94d2c2reed r = SkMulDiv255Round(r, a); 6860c9b1a8d05ea6ec5dfae0ead854304673d94d2c2reed g = SkMulDiv255Round(g, a); 6870c9b1a8d05ea6ec5dfae0ead854304673d94d2c2reed b = SkMulDiv255Round(b, a); 6880c9b1a8d05ea6ec5dfae0ead854304673d94d2c2reed } 6890c9b1a8d05ea6ec5dfae0ead854304673d94d2c2reed int gray = SkComputeLuminance(r, g, b); 6900c9b1a8d05ea6ec5dfae0ead854304673d94d2c2reed uint8_t* p = this->getAddr8(area.fLeft, area.fTop); 6910c9b1a8d05ea6ec5dfae0ead854304673d94d2c2reed while (--height >= 0) { 6920c9b1a8d05ea6ec5dfae0ead854304673d94d2c2reed memset(p, gray, width); 6930c9b1a8d05ea6ec5dfae0ead854304673d94d2c2reed p += rowBytes; 6940c9b1a8d05ea6ec5dfae0ead854304673d94d2c2reed } 6950c9b1a8d05ea6ec5dfae0ead854304673d94d2c2reed break; 6960c9b1a8d05ea6ec5dfae0ead854304673d94d2c2reed } 69761e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org case kAlpha_8_SkColorType: { 69860d3235ab42bd1d32a070695ee30d6e3ec2fa222reed@google.com uint8_t* p = this->getAddr8(area.fLeft, area.fTop); 6998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (--height >= 0) { 7008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com memset(p, a, width); 7018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com p += rowBytes; 7028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 7038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com break; 7048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 70561e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org case kARGB_4444_SkColorType: 70661e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org case kRGB_565_SkColorType: { 707567ff2f6143ecb993dbedede402a43feb71c420atfarina uint16_t* p = this->getAddr16(area.fLeft, area.fTop); 70845f746f521d6925d22a304921f6e17196f4f8157reed@google.com uint16_t v; 709020b25becb4a99061e8643780c887ad472eb0648skia.committer@gmail.com 7107669a77cd16fbab3618ca1f1a03bcfa05a93c447commit-bot@chromium.org // make rgb premultiplied 7117669a77cd16fbab3618ca1f1a03bcfa05a93c447commit-bot@chromium.org if (255 != a) { 7127669a77cd16fbab3618ca1f1a03bcfa05a93c447commit-bot@chromium.org r = SkAlphaMul(r, a); 7137669a77cd16fbab3618ca1f1a03bcfa05a93c447commit-bot@chromium.org g = SkAlphaMul(g, a); 7147669a77cd16fbab3618ca1f1a03bcfa05a93c447commit-bot@chromium.org b = SkAlphaMul(b, a); 7157669a77cd16fbab3618ca1f1a03bcfa05a93c447commit-bot@chromium.org } 7167669a77cd16fbab3618ca1f1a03bcfa05a93c447commit-bot@chromium.org 71761e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org if (kARGB_4444_SkColorType == this->colorType()) { 71845f746f521d6925d22a304921f6e17196f4f8157reed@google.com v = pack_8888_to_4444(a, r, g, b); 71945f746f521d6925d22a304921f6e17196f4f8157reed@google.com } else { 72045f746f521d6925d22a304921f6e17196f4f8157reed@google.com v = SkPackRGB16(r >> (8 - SK_R16_BITS), 72145f746f521d6925d22a304921f6e17196f4f8157reed@google.com g >> (8 - SK_G16_BITS), 72245f746f521d6925d22a304921f6e17196f4f8157reed@google.com b >> (8 - SK_B16_BITS)); 72345f746f521d6925d22a304921f6e17196f4f8157reed@google.com } 7248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (--height >= 0) { 7258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com sk_memset16(p, v, width); 7268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com p = (uint16_t*)((char*)p + rowBytes); 7278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 7288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com break; 7298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 7307669a77cd16fbab3618ca1f1a03bcfa05a93c447commit-bot@chromium.org case kBGRA_8888_SkColorType: 7317669a77cd16fbab3618ca1f1a03bcfa05a93c447commit-bot@chromium.org case kRGBA_8888_SkColorType: { 73260d3235ab42bd1d32a070695ee30d6e3ec2fa222reed@google.com uint32_t* p = this->getAddr32(area.fLeft, area.fTop); 7337669a77cd16fbab3618ca1f1a03bcfa05a93c447commit-bot@chromium.org 7347669a77cd16fbab3618ca1f1a03bcfa05a93c447commit-bot@chromium.org if (255 != a && kPremul_SkAlphaType == this->alphaType()) { 7357669a77cd16fbab3618ca1f1a03bcfa05a93c447commit-bot@chromium.org r = SkAlphaMul(r, a); 7367669a77cd16fbab3618ca1f1a03bcfa05a93c447commit-bot@chromium.org g = SkAlphaMul(g, a); 7377669a77cd16fbab3618ca1f1a03bcfa05a93c447commit-bot@chromium.org b = SkAlphaMul(b, a); 7387669a77cd16fbab3618ca1f1a03bcfa05a93c447commit-bot@chromium.org } 7397669a77cd16fbab3618ca1f1a03bcfa05a93c447commit-bot@chromium.org uint32_t v = kRGBA_8888_SkColorType == this->colorType() ? 7407669a77cd16fbab3618ca1f1a03bcfa05a93c447commit-bot@chromium.org SkPackARGB_as_RGBA(a, r, g, b) : SkPackARGB_as_BGRA(a, r, g, b); 7418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 7428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (--height >= 0) { 7438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com sk_memset32(p, v, width); 7448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com p = (uint32_t*)((char*)p + rowBytes); 7458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 7468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com break; 7478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 74861e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org default: 74961e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org return; // no change, so don't call notifyPixelsChanged() 7508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 751f9ab99aaade8c451c0e9309b4c61a448373019e3weita@google.com 7528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->notifyPixelsChanged(); 7538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 7548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 75560d3235ab42bd1d32a070695ee30d6e3ec2fa222reed@google.comvoid SkBitmap::eraseARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b) const { 75692833f99b99f1f955c350f6f4f70acd3356a79a5reed@google.com SkIRect area = { 0, 0, this->width(), this->height() }; 75760d3235ab42bd1d32a070695ee30d6e3ec2fa222reed@google.com if (!area.isEmpty()) { 75860d3235ab42bd1d32a070695ee30d6e3ec2fa222reed@google.com this->internalErase(area, a, r, g, b); 75960d3235ab42bd1d32a070695ee30d6e3ec2fa222reed@google.com } 76060d3235ab42bd1d32a070695ee30d6e3ec2fa222reed@google.com} 76160d3235ab42bd1d32a070695ee30d6e3ec2fa222reed@google.com 76260d3235ab42bd1d32a070695ee30d6e3ec2fa222reed@google.comvoid SkBitmap::eraseArea(const SkIRect& rect, SkColor c) const { 76392833f99b99f1f955c350f6f4f70acd3356a79a5reed@google.com SkIRect area = { 0, 0, this->width(), this->height() }; 76460d3235ab42bd1d32a070695ee30d6e3ec2fa222reed@google.com if (area.intersect(rect)) { 76560d3235ab42bd1d32a070695ee30d6e3ec2fa222reed@google.com this->internalErase(area, SkColorGetA(c), SkColorGetR(c), 76660d3235ab42bd1d32a070695ee30d6e3ec2fa222reed@google.com SkColorGetG(c), SkColorGetB(c)); 76760d3235ab42bd1d32a070695ee30d6e3ec2fa222reed@google.com } 76860d3235ab42bd1d32a070695ee30d6e3ec2fa222reed@google.com} 76960d3235ab42bd1d32a070695ee30d6e3ec2fa222reed@google.com 7708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////////////// 7718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////////////// 7728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 7738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SkBitmap::extractSubset(SkBitmap* result, const SkIRect& subset) const { 7748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDEBUGCODE(this->validate();) 7758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 776c84b8335ee4fd864c30a4703afc643cf4b5010d9djsollen@google.com if (NULL == result || NULL == fPixelRef) { 7778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return false; // no src pixels 7788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 7798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 7808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkIRect srcRect, r; 7818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com srcRect.set(0, 0, this->width(), this->height()); 7828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (!r.intersect(srcRect, subset)) { 7838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return false; // r is empty (i.e. no intersection) 7848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 7858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 786a2a31928470dfb642880f6ab2e4d34b1c7f5d476scroggo@google.com if (fPixelRef->getTexture() != NULL) { 787a2a31928470dfb642880f6ab2e4d34b1c7f5d476scroggo@google.com // Do a deep copy 788fa1e8a7cefd71f7b75f0b85f8eefe111814dd86fjvanverth SkPixelRef* pixelRef = fPixelRef->deepCopy(this->colorType(), this->profileType(), &subset); 789a2a31928470dfb642880f6ab2e4d34b1c7f5d476scroggo@google.com if (pixelRef != NULL) { 790a2a31928470dfb642880f6ab2e4d34b1c7f5d476scroggo@google.com SkBitmap dst; 791a3264e53ee3f3c5d6a2c813df7e44b5b96d207f2commit-bot@chromium.org dst.setInfo(SkImageInfo::Make(subset.width(), subset.height(), 792a3264e53ee3f3c5d6a2c813df7e44b5b96d207f2commit-bot@chromium.org this->colorType(), this->alphaType())); 793a2a31928470dfb642880f6ab2e4d34b1c7f5d476scroggo@google.com dst.setIsVolatile(this->isVolatile()); 794a2a31928470dfb642880f6ab2e4d34b1c7f5d476scroggo@google.com dst.setPixelRef(pixelRef)->unref(); 795a2a31928470dfb642880f6ab2e4d34b1c7f5d476scroggo@google.com SkDEBUGCODE(dst.validate()); 796a2a31928470dfb642880f6ab2e4d34b1c7f5d476scroggo@google.com result->swap(dst); 797a2a31928470dfb642880f6ab2e4d34b1c7f5d476scroggo@google.com return true; 798a2a31928470dfb642880f6ab2e4d34b1c7f5d476scroggo@google.com } 799a2a31928470dfb642880f6ab2e4d34b1c7f5d476scroggo@google.com } 800a2a31928470dfb642880f6ab2e4d34b1c7f5d476scroggo@google.com 801a2a31928470dfb642880f6ab2e4d34b1c7f5d476scroggo@google.com // If the upper left of the rectangle was outside the bounds of this SkBitmap, we should have 802a2a31928470dfb642880f6ab2e4d34b1c7f5d476scroggo@google.com // exited above. 803a2a31928470dfb642880f6ab2e4d34b1c7f5d476scroggo@google.com SkASSERT(static_cast<unsigned>(r.fLeft) < static_cast<unsigned>(this->width())); 804a2a31928470dfb642880f6ab2e4d34b1c7f5d476scroggo@google.com SkASSERT(static_cast<unsigned>(r.fTop) < static_cast<unsigned>(this->height())); 805a2a31928470dfb642880f6ab2e4d34b1c7f5d476scroggo@google.com 8068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkBitmap dst; 807a3264e53ee3f3c5d6a2c813df7e44b5b96d207f2commit-bot@chromium.org dst.setInfo(SkImageInfo::Make(r.width(), r.height(), this->colorType(), this->alphaType()), 808a3264e53ee3f3c5d6a2c813df7e44b5b96d207f2commit-bot@chromium.org this->rowBytes()); 8090eb7576c659a165f1d73b6b7ddfd43dc3782f62bskyostil@google.com dst.setIsVolatile(this->isVolatile()); 8108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (fPixelRef) { 812672588b684d484dce6ae251e9e163e4a46924322reed@google.com SkIPoint origin = fPixelRefOrigin; 813672588b684d484dce6ae251e9e163e4a46924322reed@google.com origin.fX += r.fLeft; 814672588b684d484dce6ae251e9e163e4a46924322reed@google.com origin.fY += r.fTop; 8158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // share the pixelref with a custom offset 816672588b684d484dce6ae251e9e163e4a46924322reed@google.com dst.setPixelRef(fPixelRef, origin); 8178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 8188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDEBUGCODE(dst.validate();) 8198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // we know we're good, so commit to result 8218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com result->swap(dst); 8228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return true; 8238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 8248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 8268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkCanvas.h" 8288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkPaint.h" 8298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8308a2ad3cae710f05cca57e48dd1732d575dba2dc7commit-bot@chromium.orgbool SkBitmap::canCopyTo(SkColorType dstColorType) const { 831b184f7f52b2a94e95aee326a3ca37110d2e43336reed const SkColorType srcCT = this->colorType(); 832b184f7f52b2a94e95aee326a3ca37110d2e43336reed 833b184f7f52b2a94e95aee326a3ca37110d2e43336reed if (srcCT == kUnknown_SkColorType) { 8348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return false; 8358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 8368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 837b184f7f52b2a94e95aee326a3ca37110d2e43336reed bool sameConfigs = (srcCT == dstColorType); 8388a2ad3cae710f05cca57e48dd1732d575dba2dc7commit-bot@chromium.org switch (dstColorType) { 8398a2ad3cae710f05cca57e48dd1732d575dba2dc7commit-bot@chromium.org case kAlpha_8_SkColorType: 8408a2ad3cae710f05cca57e48dd1732d575dba2dc7commit-bot@chromium.org case kRGB_565_SkColorType: 84160b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org case kRGBA_8888_SkColorType: 84260b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org case kBGRA_8888_SkColorType: 8438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com break; 8448a2ad3cae710f05cca57e48dd1732d575dba2dc7commit-bot@chromium.org case kIndex_8_SkColorType: 845f9ab99aaade8c451c0e9309b4c61a448373019e3weita@google.com if (!sameConfigs) { 846f9ab99aaade8c451c0e9309b4c61a448373019e3weita@google.com return false; 847f9ab99aaade8c451c0e9309b4c61a448373019e3weita@google.com } 848f9ab99aaade8c451c0e9309b4c61a448373019e3weita@google.com break; 8498a2ad3cae710f05cca57e48dd1732d575dba2dc7commit-bot@chromium.org case kARGB_4444_SkColorType: 850b184f7f52b2a94e95aee326a3ca37110d2e43336reed return sameConfigs || kN32_SkColorType == srcCT || kIndex_8_SkColorType == srcCT; 8510c9b1a8d05ea6ec5dfae0ead854304673d94d2c2reed case kGray_8_SkColorType: 8520c9b1a8d05ea6ec5dfae0ead854304673d94d2c2reed switch (srcCT) { 8530c9b1a8d05ea6ec5dfae0ead854304673d94d2c2reed case kGray_8_SkColorType: 8540c9b1a8d05ea6ec5dfae0ead854304673d94d2c2reed case kRGBA_8888_SkColorType: 8550c9b1a8d05ea6ec5dfae0ead854304673d94d2c2reed case kBGRA_8888_SkColorType: 8560c9b1a8d05ea6ec5dfae0ead854304673d94d2c2reed return true; 8570c9b1a8d05ea6ec5dfae0ead854304673d94d2c2reed default: 8580c9b1a8d05ea6ec5dfae0ead854304673d94d2c2reed break; 8590c9b1a8d05ea6ec5dfae0ead854304673d94d2c2reed } 8600c9b1a8d05ea6ec5dfae0ead854304673d94d2c2reed return false; 8618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com default: 8628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return false; 8638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 864fbaa88d9695347299321cbce2bf803726999fb58reed@android.com return true; 865fbaa88d9695347299321cbce2bf803726999fb58reed@android.com} 866fbaa88d9695347299321cbce2bf803726999fb58reed@android.com 867b184f7f52b2a94e95aee326a3ca37110d2e43336reed#include "SkConfig8888.h" 868b184f7f52b2a94e95aee326a3ca37110d2e43336reed 869b184f7f52b2a94e95aee326a3ca37110d2e43336reedbool SkBitmap::readPixels(const SkImageInfo& requestedDstInfo, void* dstPixels, size_t dstRB, 870b184f7f52b2a94e95aee326a3ca37110d2e43336reed int x, int y) const { 871b184f7f52b2a94e95aee326a3ca37110d2e43336reed if (kUnknown_SkColorType == requestedDstInfo.colorType()) { 872b184f7f52b2a94e95aee326a3ca37110d2e43336reed return false; 873b184f7f52b2a94e95aee326a3ca37110d2e43336reed } 874b184f7f52b2a94e95aee326a3ca37110d2e43336reed if (NULL == dstPixels || dstRB < requestedDstInfo.minRowBytes()) { 875b184f7f52b2a94e95aee326a3ca37110d2e43336reed return false; 876b184f7f52b2a94e95aee326a3ca37110d2e43336reed } 877b184f7f52b2a94e95aee326a3ca37110d2e43336reed if (0 == requestedDstInfo.width() || 0 == requestedDstInfo.height()) { 878b184f7f52b2a94e95aee326a3ca37110d2e43336reed return false; 879b184f7f52b2a94e95aee326a3ca37110d2e43336reed } 880775b8199a214af57c3ea7969e9d456f5f3eb137fmtklein 881b184f7f52b2a94e95aee326a3ca37110d2e43336reed SkIRect srcR = SkIRect::MakeXYWH(x, y, requestedDstInfo.width(), requestedDstInfo.height()); 882b184f7f52b2a94e95aee326a3ca37110d2e43336reed if (!srcR.intersect(0, 0, this->width(), this->height())) { 883b184f7f52b2a94e95aee326a3ca37110d2e43336reed return false; 884b184f7f52b2a94e95aee326a3ca37110d2e43336reed } 885775b8199a214af57c3ea7969e9d456f5f3eb137fmtklein 886b184f7f52b2a94e95aee326a3ca37110d2e43336reed // the intersect may have shrunk info's logical size 887e5ea500d4714a7d84de2bf913e81be3b65d2de68reed const SkImageInfo dstInfo = requestedDstInfo.makeWH(srcR.width(), srcR.height()); 888775b8199a214af57c3ea7969e9d456f5f3eb137fmtklein 889b184f7f52b2a94e95aee326a3ca37110d2e43336reed // if x or y are negative, then we have to adjust pixels 890b184f7f52b2a94e95aee326a3ca37110d2e43336reed if (x > 0) { 891b184f7f52b2a94e95aee326a3ca37110d2e43336reed x = 0; 892b184f7f52b2a94e95aee326a3ca37110d2e43336reed } 893b184f7f52b2a94e95aee326a3ca37110d2e43336reed if (y > 0) { 894b184f7f52b2a94e95aee326a3ca37110d2e43336reed y = 0; 895b184f7f52b2a94e95aee326a3ca37110d2e43336reed } 896b184f7f52b2a94e95aee326a3ca37110d2e43336reed // here x,y are either 0 or negative 897b184f7f52b2a94e95aee326a3ca37110d2e43336reed dstPixels = ((char*)dstPixels - y * dstRB - x * dstInfo.bytesPerPixel()); 898b184f7f52b2a94e95aee326a3ca37110d2e43336reed 899b184f7f52b2a94e95aee326a3ca37110d2e43336reed ////////////// 900775b8199a214af57c3ea7969e9d456f5f3eb137fmtklein 901b184f7f52b2a94e95aee326a3ca37110d2e43336reed SkAutoLockPixels alp(*this); 902775b8199a214af57c3ea7969e9d456f5f3eb137fmtklein 903b184f7f52b2a94e95aee326a3ca37110d2e43336reed // since we don't stop creating un-pixeled devices yet, check for no pixels here 904b184f7f52b2a94e95aee326a3ca37110d2e43336reed if (NULL == this->getPixels()) { 905b184f7f52b2a94e95aee326a3ca37110d2e43336reed return false; 906b184f7f52b2a94e95aee326a3ca37110d2e43336reed } 907775b8199a214af57c3ea7969e9d456f5f3eb137fmtklein 908e5ea500d4714a7d84de2bf913e81be3b65d2de68reed const SkImageInfo srcInfo = this->info().makeWH(dstInfo.width(), dstInfo.height()); 909775b8199a214af57c3ea7969e9d456f5f3eb137fmtklein 910b184f7f52b2a94e95aee326a3ca37110d2e43336reed const void* srcPixels = this->getAddr(srcR.x(), srcR.y()); 911b184f7f52b2a94e95aee326a3ca37110d2e43336reed return SkPixelInfo::CopyPixels(dstInfo, dstPixels, dstRB, srcInfo, srcPixels, this->rowBytes(), 912b184f7f52b2a94e95aee326a3ca37110d2e43336reed this->getColorTable()); 913b184f7f52b2a94e95aee326a3ca37110d2e43336reed} 914b184f7f52b2a94e95aee326a3ca37110d2e43336reed 915b184f7f52b2a94e95aee326a3ca37110d2e43336reedbool SkBitmap::copyTo(SkBitmap* dst, SkColorType dstColorType, Allocator* alloc) const { 9168a2ad3cae710f05cca57e48dd1732d575dba2dc7commit-bot@chromium.org if (!this->canCopyTo(dstColorType)) { 917fbaa88d9695347299321cbce2bf803726999fb58reed@android.com return false; 918fbaa88d9695347299321cbce2bf803726999fb58reed@android.com } 919fbaa88d9695347299321cbce2bf803726999fb58reed@android.com 92050dfa0130b0705414df7ba7da9915139f6320b09reed@google.com // if we have a texture, first get those pixels 92150dfa0130b0705414df7ba7da9915139f6320b09reed@google.com SkBitmap tmpSrc; 92250dfa0130b0705414df7ba7da9915139f6320b09reed@google.com const SkBitmap* src = this; 92350dfa0130b0705414df7ba7da9915139f6320b09reed@google.com 924a2a31928470dfb642880f6ab2e4d34b1c7f5d476scroggo@google.com if (fPixelRef) { 925a2a31928470dfb642880f6ab2e4d34b1c7f5d476scroggo@google.com SkIRect subset; 92661e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org subset.setXYWH(fPixelRefOrigin.fX, fPixelRefOrigin.fY, 92761e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org fInfo.width(), fInfo.height()); 928672588b684d484dce6ae251e9e163e4a46924322reed@google.com if (fPixelRef->readPixels(&tmpSrc, &subset)) { 9290187dc2155830c1ae3390d97463d5dd3971eca41scroggo if (fPixelRef->info().alphaType() == kUnpremul_SkAlphaType) { 9300187dc2155830c1ae3390d97463d5dd3971eca41scroggo // FIXME: The only meaningful implementation of readPixels 9310187dc2155830c1ae3390d97463d5dd3971eca41scroggo // (GrPixelRef) assumes premultiplied pixels. 9320187dc2155830c1ae3390d97463d5dd3971eca41scroggo return false; 9330187dc2155830c1ae3390d97463d5dd3971eca41scroggo } 934672588b684d484dce6ae251e9e163e4a46924322reed@google.com SkASSERT(tmpSrc.width() == this->width()); 935672588b684d484dce6ae251e9e163e4a46924322reed@google.com SkASSERT(tmpSrc.height() == this->height()); 936672588b684d484dce6ae251e9e163e4a46924322reed@google.com 937672588b684d484dce6ae251e9e163e4a46924322reed@google.com // did we get lucky and we can just return tmpSrc? 9388a2ad3cae710f05cca57e48dd1732d575dba2dc7commit-bot@chromium.org if (tmpSrc.colorType() == dstColorType && NULL == alloc) { 939672588b684d484dce6ae251e9e163e4a46924322reed@google.com dst->swap(tmpSrc); 9405ccae2c5b134d1b971c188215433305e88491aecscroggo@google.com // If the result is an exact copy, clone the gen ID. 9415ccae2c5b134d1b971c188215433305e88491aecscroggo@google.com if (dst->pixelRef() && dst->pixelRef()->info() == fPixelRef->info()) { 942672588b684d484dce6ae251e9e163e4a46924322reed@google.com dst->pixelRef()->cloneGenID(*fPixelRef); 943a2a31928470dfb642880f6ab2e4d34b1c7f5d476scroggo@google.com } 944672588b684d484dce6ae251e9e163e4a46924322reed@google.com return true; 945d5764e8ab731dd12df9293e52ce644eaa45333bdscroggo@google.com } 946672588b684d484dce6ae251e9e163e4a46924322reed@google.com 947672588b684d484dce6ae251e9e163e4a46924322reed@google.com // fall through to the raster case 948672588b684d484dce6ae251e9e163e4a46924322reed@google.com src = &tmpSrc; 94950dfa0130b0705414df7ba7da9915139f6320b09reed@google.com } 95050dfa0130b0705414df7ba7da9915139f6320b09reed@google.com } 95150dfa0130b0705414df7ba7da9915139f6320b09reed@google.com 952311c82db3115fc6810855cbcc42a6bc6fbd48265reed@android.com // we lock this now, since we may need its colortable 95350dfa0130b0705414df7ba7da9915139f6320b09reed@google.com SkAutoLockPixels srclock(*src); 95450dfa0130b0705414df7ba7da9915139f6320b09reed@google.com if (!src->readyToDraw()) { 955fbaa88d9695347299321cbce2bf803726999fb58reed@android.com return false; 956fbaa88d9695347299321cbce2bf803726999fb58reed@android.com } 957fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 9585ccae2c5b134d1b971c188215433305e88491aecscroggo@google.com // The only way to be readyToDraw is if fPixelRef is non NULL. 9595ccae2c5b134d1b971c188215433305e88491aecscroggo@google.com SkASSERT(fPixelRef != NULL); 9605ccae2c5b134d1b971c188215433305e88491aecscroggo@google.com 961e5ea500d4714a7d84de2bf913e81be3b65d2de68reed const SkImageInfo dstInfo = src->info().makeColorType(dstColorType); 9628a2ad3cae710f05cca57e48dd1732d575dba2dc7commit-bot@chromium.org 96350dfa0130b0705414df7ba7da9915139f6320b09reed@google.com SkBitmap tmpDst; 964a3264e53ee3f3c5d6a2c813df7e44b5b96d207f2commit-bot@chromium.org if (!tmpDst.setInfo(dstInfo)) { 9658a2ad3cae710f05cca57e48dd1732d575dba2dc7commit-bot@chromium.org return false; 9668a2ad3cae710f05cca57e48dd1732d575dba2dc7commit-bot@chromium.org } 967fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 968f9ab99aaade8c451c0e9309b4c61a448373019e3weita@google.com // allocate colortable if srcConfig == kIndex8_Config 9698a2ad3cae710f05cca57e48dd1732d575dba2dc7commit-bot@chromium.org SkAutoTUnref<SkColorTable> ctable; 9708a2ad3cae710f05cca57e48dd1732d575dba2dc7commit-bot@chromium.org if (dstColorType == kIndex_8_SkColorType) { 971cc969c4dd936c97670788395c9cbee3f346e87d1mtklein ctable.reset(SkRef(src->getColorTable())); 9728a2ad3cae710f05cca57e48dd1732d575dba2dc7commit-bot@chromium.org } 973848250415eddc54075f7eb8795e8db79e749c6abreed if (!tmpDst.tryAllocPixels(alloc, ctable)) { 9748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return false; 9758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 976fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 97750dfa0130b0705414df7ba7da9915139f6320b09reed@google.com if (!tmpDst.readyToDraw()) { 9788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // allocator/lock failed 9798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return false; 9808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 981fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 9825ccae2c5b134d1b971c188215433305e88491aecscroggo@google.com // pixelRef must be non NULL or tmpDst.readyToDraw() would have 9835ccae2c5b134d1b971c188215433305e88491aecscroggo@google.com // returned false. 9845ccae2c5b134d1b971c188215433305e88491aecscroggo@google.com SkASSERT(tmpDst.pixelRef() != NULL); 9855ccae2c5b134d1b971c188215433305e88491aecscroggo@google.com 986b184f7f52b2a94e95aee326a3ca37110d2e43336reed if (!src->readPixels(tmpDst.info(), tmpDst.getPixels(), tmpDst.rowBytes(), 0, 0)) { 987b184f7f52b2a94e95aee326a3ca37110d2e43336reed return false; 988b184f7f52b2a94e95aee326a3ca37110d2e43336reed } 9890187dc2155830c1ae3390d97463d5dd3971eca41scroggo 990b184f7f52b2a94e95aee326a3ca37110d2e43336reed // (for BitmapHeap) Clone the pixelref genID even though we have a new pixelref. 991b184f7f52b2a94e95aee326a3ca37110d2e43336reed // The old copyTo impl did this, so we continue it for now. 992b184f7f52b2a94e95aee326a3ca37110d2e43336reed // 993b184f7f52b2a94e95aee326a3ca37110d2e43336reed // TODO: should we ignore rowbytes (i.e. getSize)? Then it could just be 994b184f7f52b2a94e95aee326a3ca37110d2e43336reed // if (src_pixelref->info == dst_pixelref->info) 995b184f7f52b2a94e95aee326a3ca37110d2e43336reed // 996b184f7f52b2a94e95aee326a3ca37110d2e43336reed if (src->colorType() == dstColorType && tmpDst.getSize() == src->getSize()) { 997b184f7f52b2a94e95aee326a3ca37110d2e43336reed SkPixelRef* dstPixelRef = tmpDst.pixelRef(); 998b184f7f52b2a94e95aee326a3ca37110d2e43336reed if (dstPixelRef->info() == fPixelRef->info()) { 999b184f7f52b2a94e95aee326a3ca37110d2e43336reed dstPixelRef->cloneGenID(*fPixelRef); 1000311c82db3115fc6810855cbcc42a6bc6fbd48265reed@android.com } 10018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 10028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 100350dfa0130b0705414df7ba7da9915139f6320b09reed@google.com dst->swap(tmpDst); 10048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return true; 10058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 10068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1007fab349c0bf3a305b7a7388b77bab13b0f7b37393commit-bot@chromium.orgbool SkBitmap::deepCopyTo(SkBitmap* dst) const { 1008e4538f5b46d70798e34eb078f5d5e76a59d02318reed const SkColorType dstCT = this->colorType(); 1009fa1e8a7cefd71f7b75f0b85f8eefe111814dd86fjvanverth const SkColorProfileType dstPT = this->profileType(); 101061e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org 10118a2ad3cae710f05cca57e48dd1732d575dba2dc7commit-bot@chromium.org if (!this->canCopyTo(dstCT)) { 1012ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org return false; 1013ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org } 1014ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org 1015ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org // If we have a PixelRef, and it supports deep copy, use it. 1016ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org // Currently supported only by texture-backed bitmaps. 1017ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org if (fPixelRef) { 1018fa1e8a7cefd71f7b75f0b85f8eefe111814dd86fjvanverth SkPixelRef* pixelRef = fPixelRef->deepCopy(dstCT, dstPT, NULL); 1019eeef0cc49bf71e8b5e044d6a73b79cfe2b2c87b3commit-bot@chromium.org if (pixelRef) { 1020eeef0cc49bf71e8b5e044d6a73b79cfe2b2c87b3commit-bot@chromium.org uint32_t rowBytes; 1021fa1e8a7cefd71f7b75f0b85f8eefe111814dd86fjvanverth if (this->colorType() == dstCT && this->profileType() == dstPT) { 1022eeef0cc49bf71e8b5e044d6a73b79cfe2b2c87b3commit-bot@chromium.org // Since there is no subset to pass to deepCopy, and deepCopy 1023eeef0cc49bf71e8b5e044d6a73b79cfe2b2c87b3commit-bot@chromium.org // succeeded, the new pixel ref must be identical. 1024eeef0cc49bf71e8b5e044d6a73b79cfe2b2c87b3commit-bot@chromium.org SkASSERT(fPixelRef->info() == pixelRef->info()); 1025eeef0cc49bf71e8b5e044d6a73b79cfe2b2c87b3commit-bot@chromium.org pixelRef->cloneGenID(*fPixelRef); 1026eeef0cc49bf71e8b5e044d6a73b79cfe2b2c87b3commit-bot@chromium.org // Use the same rowBytes as the original. 1027eeef0cc49bf71e8b5e044d6a73b79cfe2b2c87b3commit-bot@chromium.org rowBytes = fRowBytes; 1028eeef0cc49bf71e8b5e044d6a73b79cfe2b2c87b3commit-bot@chromium.org } else { 1029a3264e53ee3f3c5d6a2c813df7e44b5b96d207f2commit-bot@chromium.org // With the new config, an appropriate fRowBytes will be computed by setInfo. 1030eeef0cc49bf71e8b5e044d6a73b79cfe2b2c87b3commit-bot@chromium.org rowBytes = 0; 1031eeef0cc49bf71e8b5e044d6a73b79cfe2b2c87b3commit-bot@chromium.org } 1032eeef0cc49bf71e8b5e044d6a73b79cfe2b2c87b3commit-bot@chromium.org 1033e5ea500d4714a7d84de2bf913e81be3b65d2de68reed const SkImageInfo info = fInfo.makeColorType(dstCT); 1034a3264e53ee3f3c5d6a2c813df7e44b5b96d207f2commit-bot@chromium.org if (!dst->setInfo(info, rowBytes)) { 103561e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org return false; 103661e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org } 1037eeef0cc49bf71e8b5e044d6a73b79cfe2b2c87b3commit-bot@chromium.org dst->setPixelRef(pixelRef, fPixelRefOrigin)->unref(); 1038ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org return true; 1039ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org } 1040ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org } 1041ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org 1042ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org if (this->getTexture()) { 1043ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org return false; 1044ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org } else { 10458a2ad3cae710f05cca57e48dd1732d575dba2dc7commit-bot@chromium.org return this->copyTo(dst, dstCT, NULL); 1046ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org } 1047ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org} 1048ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org 10498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 10508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1051a87cd2af4c7f46ba8437c2e500805c9deb9e3a40tomhudson@google.comstatic bool GetBitmapAlpha(const SkBitmap& src, uint8_t* SK_RESTRICT alpha, 10528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int alphaRowBytes) { 10538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(alpha != NULL); 10548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(alphaRowBytes >= src.width()); 10558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1056cba73780bbd12fd254229517aec04fcbf0b64b52commit-bot@chromium.org SkColorType colorType = src.colorType(); 1057cba73780bbd12fd254229517aec04fcbf0b64b52commit-bot@chromium.org int w = src.width(); 1058cba73780bbd12fd254229517aec04fcbf0b64b52commit-bot@chromium.org int h = src.height(); 1059cba73780bbd12fd254229517aec04fcbf0b64b52commit-bot@chromium.org size_t rb = src.rowBytes(); 10608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 10611cdcb5138f9b70aff547ea1c3af96f0c90b12f8freed@android.com SkAutoLockPixels alp(src); 10621cdcb5138f9b70aff547ea1c3af96f0c90b12f8freed@android.com if (!src.readyToDraw()) { 10631cdcb5138f9b70aff547ea1c3af96f0c90b12f8freed@android.com // zero out the alpha buffer and return 10641cdcb5138f9b70aff547ea1c3af96f0c90b12f8freed@android.com while (--h >= 0) { 10651cdcb5138f9b70aff547ea1c3af96f0c90b12f8freed@android.com memset(alpha, 0, w); 10661cdcb5138f9b70aff547ea1c3af96f0c90b12f8freed@android.com alpha += alphaRowBytes; 10671cdcb5138f9b70aff547ea1c3af96f0c90b12f8freed@android.com } 10681cdcb5138f9b70aff547ea1c3af96f0c90b12f8freed@android.com return false; 10691cdcb5138f9b70aff547ea1c3af96f0c90b12f8freed@android.com } 107082065d667f64e232bcde2ad849756a6096fcbe6freed@google.com 1071cba73780bbd12fd254229517aec04fcbf0b64b52commit-bot@chromium.org if (kAlpha_8_SkColorType == colorType && !src.isOpaque()) { 10728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const uint8_t* s = src.getAddr8(0, 0); 10738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (--h >= 0) { 10748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com memcpy(alpha, s, w); 10758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com s += rb; 10768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com alpha += alphaRowBytes; 10778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1078cba73780bbd12fd254229517aec04fcbf0b64b52commit-bot@chromium.org } else if (kN32_SkColorType == colorType && !src.isOpaque()) { 10798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPMColor* SK_RESTRICT s = src.getAddr32(0, 0); 10808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (--h >= 0) { 10818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com for (int x = 0; x < w; x++) { 10828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com alpha[x] = SkGetPackedA32(s[x]); 10838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 10848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com s = (const SkPMColor*)((const char*)s + rb); 10858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com alpha += alphaRowBytes; 10868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1087cba73780bbd12fd254229517aec04fcbf0b64b52commit-bot@chromium.org } else if (kARGB_4444_SkColorType == colorType && !src.isOpaque()) { 10888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPMColor16* SK_RESTRICT s = src.getAddr16(0, 0); 10898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (--h >= 0) { 10908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com for (int x = 0; x < w; x++) { 10918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com alpha[x] = SkPacked4444ToA32(s[x]); 10928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 10938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com s = (const SkPMColor16*)((const char*)s + rb); 10948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com alpha += alphaRowBytes; 10958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1096cba73780bbd12fd254229517aec04fcbf0b64b52commit-bot@chromium.org } else if (kIndex_8_SkColorType == colorType && !src.isOpaque()) { 10978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkColorTable* ct = src.getColorTable(); 10988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (ct) { 1099775b8199a214af57c3ea7969e9d456f5f3eb137fmtklein const SkPMColor* SK_RESTRICT table = ct->readColors(); 11008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const uint8_t* SK_RESTRICT s = src.getAddr8(0, 0); 11018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (--h >= 0) { 11028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com for (int x = 0; x < w; x++) { 11038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com alpha[x] = SkGetPackedA32(table[s[x]]); 11048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 11058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com s += rb; 11068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com alpha += alphaRowBytes; 11078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 11088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 11098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { // src is opaque, so just fill alpha[] with 0xFF 11108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com memset(alpha, 0xFF, h * alphaRowBytes); 11118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 11121cdcb5138f9b70aff547ea1c3af96f0c90b12f8freed@android.com return true; 11138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 11148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 11158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkPaint.h" 11168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkMaskFilter.h" 11178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkMatrix.h" 11188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1119cd9d69b9ce7eb301a9fd8d91b9f95fd99b07bae5djsollen@google.combool SkBitmap::extractAlpha(SkBitmap* dst, const SkPaint* paint, 112057f4969724a1dd88c8d9ae35a863e6cf621181d5djsollen@google.com Allocator *allocator, SkIPoint* offset) const { 11218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDEBUGCODE(this->validate();) 11228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1123cd9d69b9ce7eb301a9fd8d91b9f95fd99b07bae5djsollen@google.com SkBitmap tmpBitmap; 11248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkMatrix identity; 11258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkMask srcM, dstM; 11268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 11278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com srcM.fBounds.set(0, 0, this->width(), this->height()); 11288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com srcM.fRowBytes = SkAlign4(this->width()); 11298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com srcM.fFormat = SkMask::kA8_Format; 11308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 11318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkMaskFilter* filter = paint ? paint->getMaskFilter() : NULL; 11328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 11338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // compute our (larger?) dst bounds if we have a filter 113449f085dddff10473b6ebf832a974288300224e60bsalomon if (filter) { 11358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com identity.reset(); 11368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com srcM.fImage = NULL; 11378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (!filter->filterMask(&dstM, srcM, identity, NULL)) { 11388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com goto NO_FILTER_CASE; 11398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 11408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com dstM.fRowBytes = SkAlign4(dstM.fBounds.width()); 11418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 11428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com NO_FILTER_CASE: 1143a3264e53ee3f3c5d6a2c813df7e44b5b96d207f2commit-bot@chromium.org tmpBitmap.setInfo(SkImageInfo::MakeA8(this->width(), this->height()), srcM.fRowBytes); 1144848250415eddc54075f7eb8795e8db79e749c6abreed if (!tmpBitmap.tryAllocPixels(allocator, NULL)) { 1145cd9d69b9ce7eb301a9fd8d91b9f95fd99b07bae5djsollen@google.com // Allocation of pixels for alpha bitmap failed. 1146cd9d69b9ce7eb301a9fd8d91b9f95fd99b07bae5djsollen@google.com SkDebugf("extractAlpha failed to allocate (%d,%d) alpha bitmap\n", 1147cd9d69b9ce7eb301a9fd8d91b9f95fd99b07bae5djsollen@google.com tmpBitmap.width(), tmpBitmap.height()); 1148cd9d69b9ce7eb301a9fd8d91b9f95fd99b07bae5djsollen@google.com return false; 1149cd9d69b9ce7eb301a9fd8d91b9f95fd99b07bae5djsollen@google.com } 1150cd9d69b9ce7eb301a9fd8d91b9f95fd99b07bae5djsollen@google.com GetBitmapAlpha(*this, tmpBitmap.getAddr8(0, 0), srcM.fRowBytes); 11518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (offset) { 11528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com offset->set(0, 0); 11538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1154cd9d69b9ce7eb301a9fd8d91b9f95fd99b07bae5djsollen@google.com tmpBitmap.swap(*dst); 1155cd9d69b9ce7eb301a9fd8d91b9f95fd99b07bae5djsollen@google.com return true; 11568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 115702f55841854ae32f21a13417e9ee711463e488cfbungeman@google.com srcM.fImage = SkMask::AllocImage(srcM.computeImageSize()); 115802f55841854ae32f21a13417e9ee711463e488cfbungeman@google.com SkAutoMaskFreeImage srcCleanup(srcM.fImage); 11598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 11608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com GetBitmapAlpha(*this, srcM.fImage, srcM.fRowBytes); 11618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (!filter->filterMask(&dstM, srcM, identity, NULL)) { 11628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com goto NO_FILTER_CASE; 11638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 116402f55841854ae32f21a13417e9ee711463e488cfbungeman@google.com SkAutoMaskFreeImage dstCleanup(dstM.fImage); 11658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1166a3264e53ee3f3c5d6a2c813df7e44b5b96d207f2commit-bot@chromium.org tmpBitmap.setInfo(SkImageInfo::MakeA8(dstM.fBounds.width(), dstM.fBounds.height()), 1167a3264e53ee3f3c5d6a2c813df7e44b5b96d207f2commit-bot@chromium.org dstM.fRowBytes); 1168848250415eddc54075f7eb8795e8db79e749c6abreed if (!tmpBitmap.tryAllocPixels(allocator, NULL)) { 1169cd9d69b9ce7eb301a9fd8d91b9f95fd99b07bae5djsollen@google.com // Allocation of pixels for alpha bitmap failed. 1170cd9d69b9ce7eb301a9fd8d91b9f95fd99b07bae5djsollen@google.com SkDebugf("extractAlpha failed to allocate (%d,%d) alpha bitmap\n", 1171cd9d69b9ce7eb301a9fd8d91b9f95fd99b07bae5djsollen@google.com tmpBitmap.width(), tmpBitmap.height()); 1172cd9d69b9ce7eb301a9fd8d91b9f95fd99b07bae5djsollen@google.com return false; 1173cd9d69b9ce7eb301a9fd8d91b9f95fd99b07bae5djsollen@google.com } 1174cd9d69b9ce7eb301a9fd8d91b9f95fd99b07bae5djsollen@google.com memcpy(tmpBitmap.getPixels(), dstM.fImage, dstM.computeImageSize()); 11758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (offset) { 11768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com offset->set(dstM.fBounds.fLeft, dstM.fBounds.fTop); 11778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1178cd9d69b9ce7eb301a9fd8d91b9f95fd99b07bae5djsollen@google.com SkDEBUGCODE(tmpBitmap.validate();) 1179cd9d69b9ce7eb301a9fd8d91b9f95fd99b07bae5djsollen@google.com 1180cd9d69b9ce7eb301a9fd8d91b9f95fd99b07bae5djsollen@google.com tmpBitmap.swap(*dst); 1181cd9d69b9ce7eb301a9fd8d91b9f95fd99b07bae5djsollen@google.com return true; 11828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 11838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 11848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 11858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1186968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.orgvoid SkBitmap::WriteRawPixels(SkWriteBuffer* buffer, const SkBitmap& bitmap) { 1187968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org const SkImageInfo info = bitmap.info(); 1188968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org SkAutoLockPixels alp(bitmap); 1189968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org if (0 == info.width() || 0 == info.height() || NULL == bitmap.getPixels()) { 1190968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org buffer->writeUInt(0); // instead of snugRB, signaling no pixels 1191968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org return; 1192968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org } 1193968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org 1194968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org const size_t snugRB = info.width() * info.bytesPerPixel(); 1195968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org const char* src = (const char*)bitmap.getPixels(); 1196968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org const size_t ramRB = bitmap.rowBytes(); 11973c134a97ed128ca95345e13619512df0f42e95f8skia.committer@gmail.com 1198968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org buffer->write32(SkToU32(snugRB)); 1199968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org info.flatten(*buffer); 1200968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org 1201968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org const size_t size = snugRB * info.height(); 1202968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org SkAutoMalloc storage(size); 1203968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org char* dst = (char*)storage.get(); 1204968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org for (int y = 0; y < info.height(); ++y) { 1205968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org memcpy(dst, src, snugRB); 1206968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org dst += snugRB; 1207968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org src += ramRB; 1208968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org } 1209968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org buffer->writeByteArray(storage.get(), size); 1210968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org 1211968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org SkColorTable* ct = bitmap.getColorTable(); 1212968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org if (kIndex_8_SkColorType == info.colorType() && ct) { 1213968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org buffer->writeBool(true); 1214968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org ct->writeToBuffer(*buffer); 1215968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org } else { 1216968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org buffer->writeBool(false); 1217968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org } 1218968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org} 1219968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org 1220968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.orgbool SkBitmap::ReadRawPixels(SkReadBuffer* buffer, SkBitmap* bitmap) { 1221968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org const size_t snugRB = buffer->readUInt(); 1222968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org if (0 == snugRB) { // no pixels 1223968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org return false; 1224968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org } 1225968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org 1226968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org SkImageInfo info; 1227968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org info.unflatten(*buffer); 1228968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org 1229ca95c19d27b505a1ac8f57b53cb49c198bc29267sugoi // If there was an error reading "info", don't use it to compute minRowBytes() 1230ca95c19d27b505a1ac8f57b53cb49c198bc29267sugoi if (!buffer->validate(true)) { 1231ca95c19d27b505a1ac8f57b53cb49c198bc29267sugoi return false; 1232ca95c19d27b505a1ac8f57b53cb49c198bc29267sugoi } 1233ca95c19d27b505a1ac8f57b53cb49c198bc29267sugoi 1234968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org const size_t ramRB = info.minRowBytes(); 1235bd0d9da981289504c9dcd8547eaad52b1f4a52cbsugoi const int height = SkMax32(info.height(), 0); 1236bd0d9da981289504c9dcd8547eaad52b1f4a52cbsugoi const uint64_t snugSize = sk_64_mul(snugRB, height); 1237bd0d9da981289504c9dcd8547eaad52b1f4a52cbsugoi const uint64_t ramSize = sk_64_mul(ramRB, height); 1238bd0d9da981289504c9dcd8547eaad52b1f4a52cbsugoi static const uint64_t max_size_t = (size_t)(-1); 1239bd0d9da981289504c9dcd8547eaad52b1f4a52cbsugoi if (!buffer->validate((snugSize <= ramSize) && (ramSize <= max_size_t))) { 124005858435ee8744de863be7e5ade05e4fd6edfb46commit-bot@chromium.org return false; 124105858435ee8744de863be7e5ade05e4fd6edfb46commit-bot@chromium.org } 1242968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org 1243bd0d9da981289504c9dcd8547eaad52b1f4a52cbsugoi SkAutoDataUnref data(SkData::NewUninitialized(SkToSizeT(ramSize))); 124433a30503d76fdd989358cedd78445ba96bb809ddreed char* dst = (char*)data->writable_data(); 1245bd0d9da981289504c9dcd8547eaad52b1f4a52cbsugoi buffer->readByteArray(dst, SkToSizeT(snugSize)); 1246968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org 1247968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org if (snugSize != ramSize) { 1248968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org const char* srcRow = dst + snugRB * (height - 1); 1249968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org char* dstRow = dst + ramRB * (height - 1); 1250968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org for (int y = height - 1; y >= 1; --y) { 1251968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org memmove(dstRow, srcRow, snugRB); 1252968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org srcRow -= snugRB; 1253968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org dstRow -= ramRB; 1254968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org } 1255968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org SkASSERT(srcRow == dstRow); // first row does not need to be moved 1256968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org } 12573c134a97ed128ca95345e13619512df0f42e95f8skia.committer@gmail.com 1258968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org SkAutoTUnref<SkColorTable> ctable; 1259968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org if (buffer->readBool()) { 1260968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org ctable.reset(SkNEW_ARGS(SkColorTable, (*buffer))); 1261968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org } 12623c134a97ed128ca95345e13619512df0f42e95f8skia.committer@gmail.com 1263968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org SkAutoTUnref<SkPixelRef> pr(SkMallocPixelRef::NewWithData(info, info.minRowBytes(), 1264968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org ctable.get(), data.get())); 12656af314724f51ad79a640844536c667bb83de5690sugoi if (!pr.get()) { 12666af314724f51ad79a640844536c667bb83de5690sugoi return false; 12676af314724f51ad79a640844536c667bb83de5690sugoi } 1268a3264e53ee3f3c5d6a2c813df7e44b5b96d207f2commit-bot@chromium.org bitmap->setInfo(pr->info()); 1269968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org bitmap->setPixelRef(pr, 0, 0); 1270968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org return true; 1271968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org} 1272968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org 12738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comenum { 12748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SERIALIZE_PIXELTYPE_NONE, 127521830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com SERIALIZE_PIXELTYPE_REF_DATA 12768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 12778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 12788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 12798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 12808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkBitmap::RLEPixels::RLEPixels(int width, int height) { 12818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fHeight = height; 1282235002fb127fc5b7564910434faed84337c08238commit-bot@chromium.org fYPtrs = (uint8_t**)sk_calloc_throw(height * sizeof(uint8_t*)); 12838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 12848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 12858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkBitmap::RLEPixels::~RLEPixels() { 12868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com sk_free(fYPtrs); 12878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 12888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 12898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 12908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 12918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifdef SK_DEBUG 12928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkBitmap::validate() const { 129361e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org fInfo.validate(); 1294d5414e5efe0a6a0bce0b5499e2358e2be4cb9b61commit-bot@chromium.org 1295d5414e5efe0a6a0bce0b5499e2358e2be4cb9b61commit-bot@chromium.org // ImageInfo may not require this, but Bitmap ensures that opaque-only 1296d5414e5efe0a6a0bce0b5499e2358e2be4cb9b61commit-bot@chromium.org // colorTypes report opaque for their alphatype 1297d5414e5efe0a6a0bce0b5499e2358e2be4cb9b61commit-bot@chromium.org if (kRGB_565_SkColorType == fInfo.colorType()) { 1298d5414e5efe0a6a0bce0b5499e2358e2be4cb9b61commit-bot@chromium.org SkASSERT(kOpaque_SkAlphaType == fInfo.alphaType()); 1299d5414e5efe0a6a0bce0b5499e2358e2be4cb9b61commit-bot@chromium.org } 1300d5414e5efe0a6a0bce0b5499e2358e2be4cb9b61commit-bot@chromium.org 130161e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org SkASSERT(fInfo.validRowBytes(fRowBytes)); 13020847059fcffe11d53d4ea803ba2d51c696eb6d07scroggo uint8_t allFlags = kImageIsVolatile_Flag; 13038e990eb440e0f61386ba21b06b8428d5b285c341scroggo@google.com#ifdef SK_BUILD_FOR_ANDROID 13048e990eb440e0f61386ba21b06b8428d5b285c341scroggo@google.com allFlags |= kHasHardwareMipMap_Flag; 13058e990eb440e0f61386ba21b06b8428d5b285c341scroggo@google.com#endif 13060847059fcffe11d53d4ea803ba2d51c696eb6d07scroggo SkASSERT((~allFlags & fFlags) == 0); 13078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(fPixelLockCount >= 0); 13088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1309615316cefbf16382f6a99c72d88a13d2be1d2408reed@google.com if (fPixels) { 1310615316cefbf16382f6a99c72d88a13d2be1d2408reed@google.com SkASSERT(fPixelRef); 1311e77dadd91ae6f4319c2c047e7e36cc79bb4d1effrobertphillips SkASSERT(fPixelLockCount > 0); 1312615316cefbf16382f6a99c72d88a13d2be1d2408reed@google.com SkASSERT(fPixelRef->isLocked()); 1313615316cefbf16382f6a99c72d88a13d2be1d2408reed@google.com SkASSERT(fPixelRef->rowBytes() == fRowBytes); 1314615316cefbf16382f6a99c72d88a13d2be1d2408reed@google.com SkASSERT(fPixelRefOrigin.fX >= 0); 1315615316cefbf16382f6a99c72d88a13d2be1d2408reed@google.com SkASSERT(fPixelRefOrigin.fY >= 0); 131661e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org SkASSERT(fPixelRef->info().width() >= (int)this->width() + fPixelRefOrigin.fX); 1317e5ea500d4714a7d84de2bf913e81be3b65d2de68reed SkASSERT(fPixelRef->info().height() >= (int)this->height() + fPixelRefOrigin.fY); 131861e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org SkASSERT(fPixelRef->rowBytes() >= fInfo.minRowBytes()); 1319615316cefbf16382f6a99c72d88a13d2be1d2408reed@google.com } else { 1320615316cefbf16382f6a99c72d88a13d2be1d2408reed@google.com SkASSERT(NULL == fColorTable); 13218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 13228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 13238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 132476f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com 13250f10f7bf1fb43ca6346dc220a076773b1f19a367commit-bot@chromium.org#ifndef SK_IGNORE_TO_STRING 132676f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.comvoid SkBitmap::toString(SkString* str) const { 132776f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com 1328cba73780bbd12fd254229517aec04fcbf0b64b52commit-bot@chromium.org static const char* gColorTypeNames[kLastEnum_SkColorType + 1] = { 1329cba73780bbd12fd254229517aec04fcbf0b64b52commit-bot@chromium.org "UNKNOWN", "A8", "565", "4444", "RGBA", "BGRA", "INDEX8", 133076f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com }; 133176f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com 133276f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com str->appendf("bitmap: ((%d, %d) %s", this->width(), this->height(), 1333cba73780bbd12fd254229517aec04fcbf0b64b52commit-bot@chromium.org gColorTypeNames[this->colorType()]); 133476f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com 133576f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com str->append(" ("); 133676f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com if (this->isOpaque()) { 133776f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com str->append("opaque"); 133876f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com } else { 133976f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com str->append("transparent"); 134076f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com } 134176f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com if (this->isImmutable()) { 134276f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com str->append(", immutable"); 134376f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com } else { 134476f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com str->append(", not-immutable"); 134576f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com } 134676f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com str->append(")"); 134776f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com 134876f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com SkPixelRef* pr = this->pixelRef(); 134976f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com if (NULL == pr) { 135076f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com // show null or the explicit pixel address (rare) 135176f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com str->appendf(" pixels:%p", this->getPixels()); 135276f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com } else { 135376f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com const char* uri = pr->getURI(); 135449f085dddff10473b6ebf832a974288300224e60bsalomon if (uri) { 135576f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com str->appendf(" uri:\"%s\"", uri); 135676f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com } else { 135776f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com str->appendf(" pixelref:%p", pr); 135876f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com } 135976f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com } 136076f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com 136176f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com str->append(")"); 136276f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com} 136376f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com#endif 136461e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org 136561e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org/////////////////////////////////////////////////////////////////////////////// 136661e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org 136761e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org#ifdef SK_DEBUG 136861e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.orgvoid SkImageInfo::validate() const { 136961e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org SkASSERT(fWidth >= 0); 137061e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org SkASSERT(fHeight >= 0); 137161e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org SkASSERT(SkColorTypeIsValid(fColorType)); 137261e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org SkASSERT(SkAlphaTypeIsValid(fAlphaType)); 137361e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org} 137461e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org#endif 1375