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