1f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
2f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger/*
3f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger * Copyright 2008 The Android Open Source Project
4f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger *
5f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger * Use of this source code is governed by a BSD-style license that can be
6f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger * found in the LICENSE file.
7f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger */
8f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
9f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
10f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger#include "SkBitmap.h"
11f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger#include "SkColorPriv.h"
12f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger#include "SkDither.h"
13f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger#include "SkFlattenable.h"
14f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger#include "SkMallocPixelRef.h"
15f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger#include "SkMask.h"
16f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger#include "SkPixelRef.h"
17f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger#include "SkThread.h"
18f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger#include "SkUnPreMultiply.h"
19f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger#include "SkUtils.h"
20f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger#include "SkPackBits.h"
21f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger#include <new>
22f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
23f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerextern int32_t SkNextPixelRefGenerationID();
24f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
25f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerstatic bool isPos32Bits(const Sk64& value) {
26f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    return !value.isNeg() && value.is32();
27f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger}
28f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
29f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerstruct MipLevel {
30f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    void*       fPixels;
31f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    uint32_t    fRowBytes;
32f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    uint32_t    fWidth, fHeight;
33f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger};
34f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
35f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerstruct SkBitmap::MipMap : SkNoncopyable {
36f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    int32_t fRefCnt;
37f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    int     fLevelCount;
38f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger//  MipLevel    fLevel[fLevelCount];
39f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger//  Pixels[]
40f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
41f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    static MipMap* Alloc(int levelCount, size_t pixelSize) {
42f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        if (levelCount < 0) {
43f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            return NULL;
44f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        }
45f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        Sk64 size;
46f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        size.setMul(levelCount + 1, sizeof(MipLevel));
47f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        size.add(sizeof(MipMap));
48f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        size.add(pixelSize);
49f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        if (!isPos32Bits(size)) {
50f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            return NULL;
51f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        }
52f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        MipMap* mm = (MipMap*)sk_malloc_throw(size.get32());
53f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        mm->fRefCnt = 1;
54f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        mm->fLevelCount = levelCount;
55f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        return mm;
56f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    }
57f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
58f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    const MipLevel* levels() const { return (const MipLevel*)(this + 1); }
59f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    MipLevel* levels() { return (MipLevel*)(this + 1); }
60f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
61f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    const void* pixels() const { return levels() + fLevelCount; }
62f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    void* pixels() { return levels() + fLevelCount; }
63f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
64f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    void ref() {
65f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        if (SK_MaxS32 == sk_atomic_inc(&fRefCnt)) {
66f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            sk_throw();
67f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        }
68f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    }
69f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    void unref() {
70f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        SkASSERT(fRefCnt > 0);
71f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        if (sk_atomic_dec(&fRefCnt) == 1) {
72f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            sk_free(this);
73f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        }
74f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    }
75f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger};
76f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
77f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger///////////////////////////////////////////////////////////////////////////////
78f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger///////////////////////////////////////////////////////////////////////////////
79f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
80f8cacf6b11e35785df8efb613b0c3592d535f603Derek SollenbergerSkBitmap::SkBitmap() {
81f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    sk_bzero(this, sizeof(*this));
82f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger}
83f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
84f8cacf6b11e35785df8efb613b0c3592d535f603Derek SollenbergerSkBitmap::SkBitmap(const SkBitmap& src) {
85f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    SkDEBUGCODE(src.validate();)
86f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    sk_bzero(this, sizeof(*this));
87f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    *this = src;
88f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    SkDEBUGCODE(this->validate();)
89f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger}
90f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
91f8cacf6b11e35785df8efb613b0c3592d535f603Derek SollenbergerSkBitmap::~SkBitmap() {
92f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    SkDEBUGCODE(this->validate();)
93f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    this->freePixels();
94f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger}
95f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
96f8cacf6b11e35785df8efb613b0c3592d535f603Derek SollenbergerSkBitmap& SkBitmap::operator=(const SkBitmap& src) {
97f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    if (this != &src) {
98f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        this->freePixels();
99f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        memcpy(this, &src, sizeof(src));
100f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
101f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        // inc src reference counts
102f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        SkSafeRef(src.fPixelRef);
103f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        SkSafeRef(src.fMipMap);
104f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
105f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        // we reset our locks if we get blown away
106f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        fPixelLockCount = 0;
107f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
108f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        /*  The src could be in 3 states
109f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            1. no pixelref, in which case we just copy/ref the pixels/ctable
110f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            2. unlocked pixelref, pixels/ctable should be null
111f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            3. locked pixelref, we should lock the ref again ourselves
112f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        */
113f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        if (NULL == fPixelRef) {
114f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            // leave fPixels as it is
115f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            SkSafeRef(fColorTable); // ref the user's ctable if present
116f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        } else {    // we have a pixelref, so pixels/ctable reflect it
117f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            // ignore the values from the memcpy
118f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            fPixels = NULL;
119f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            fColorTable = NULL;
120f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            // Note that what to for genID is somewhat arbitrary. We have no
121f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            // way to track changes to raw pixels across multiple SkBitmaps.
122f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            // Would benefit from an SkRawPixelRef type created by
123f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            // setPixels.
124f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            // Just leave the memcpy'ed one but they'll get out of sync
125f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            // as soon either is modified.
126f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        }
127f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    }
128f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
129f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    SkDEBUGCODE(this->validate();)
130f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    return *this;
131f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger}
132f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
133f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergervoid SkBitmap::swap(SkBitmap& other) {
134f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    SkTSwap(fColorTable, other.fColorTable);
135f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    SkTSwap(fPixelRef, other.fPixelRef);
136f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    SkTSwap(fPixelRefOffset, other.fPixelRefOffset);
137f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    SkTSwap(fPixelLockCount, other.fPixelLockCount);
138f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    SkTSwap(fMipMap, other.fMipMap);
139f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    SkTSwap(fPixels, other.fPixels);
140f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    SkTSwap(fRawPixelGenerationID, other.fRawPixelGenerationID);
141f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    SkTSwap(fRowBytes, other.fRowBytes);
142f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    SkTSwap(fWidth, other.fWidth);
143f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    SkTSwap(fHeight, other.fHeight);
144f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    SkTSwap(fConfig, other.fConfig);
145f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    SkTSwap(fFlags, other.fFlags);
146f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    SkTSwap(fBytesPerPixel, other.fBytesPerPixel);
147f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
148f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    SkDEBUGCODE(this->validate();)
149f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger}
150f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
151f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergervoid SkBitmap::reset() {
152f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    this->freePixels();
153f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    sk_bzero(this, sizeof(*this));
154f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger}
155f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
156f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerint SkBitmap::ComputeBytesPerPixel(SkBitmap::Config config) {
157f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    int bpp;
158f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    switch (config) {
159f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        case kNo_Config:
160f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        case kA1_Config:
161f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            bpp = 0;   // not applicable
162f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            break;
163f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        case kRLE_Index8_Config:
164f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        case kA8_Config:
165f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        case kIndex8_Config:
166f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            bpp = 1;
167f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            break;
168f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        case kRGB_565_Config:
169f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        case kARGB_4444_Config:
170f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            bpp = 2;
171f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            break;
172f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        case kARGB_8888_Config:
173f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            bpp = 4;
174f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            break;
175f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        default:
176f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            SkDEBUGFAIL("unknown config");
177f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            bpp = 0;   // error
178f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            break;
179f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    }
180f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    return bpp;
181f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger}
182f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
183f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerint SkBitmap::ComputeRowBytes(Config c, int width) {
184f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    if (width < 0) {
185f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        return 0;
186f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    }
187f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
188f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    Sk64 rowBytes;
189f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    rowBytes.setZero();
190f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
191f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    switch (c) {
192f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        case kNo_Config:
193f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        case kRLE_Index8_Config:
194f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            break;
195f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        case kA1_Config:
196f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            rowBytes.set(width);
197f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            rowBytes.add(7);
198f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            rowBytes.shiftRight(3);
199f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            break;
200f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        case kA8_Config:
201f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        case kIndex8_Config:
202f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            rowBytes.set(width);
203f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            break;
204f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        case kRGB_565_Config:
205f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        case kARGB_4444_Config:
206f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            rowBytes.set(width);
207f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            rowBytes.shiftLeft(1);
208f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            break;
209f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        case kARGB_8888_Config:
210f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            rowBytes.set(width);
211f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            rowBytes.shiftLeft(2);
212f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            break;
213f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        default:
214f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            SkDEBUGFAIL("unknown config");
215f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            break;
216f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    }
217f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    return isPos32Bits(rowBytes) ? rowBytes.get32() : 0;
218f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger}
219f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
220f8cacf6b11e35785df8efb613b0c3592d535f603Derek SollenbergerSk64 SkBitmap::ComputeSize64(Config c, int width, int height) {
221f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    Sk64 size;
222f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    size.setMul(SkBitmap::ComputeRowBytes(c, width), height);
223f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    return size;
224f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger}
225f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
226f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergersize_t SkBitmap::ComputeSize(Config c, int width, int height) {
227f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    Sk64 size = SkBitmap::ComputeSize64(c, width, height);
228f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    return isPos32Bits(size) ? size.get32() : 0;
229f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger}
230f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
231f8cacf6b11e35785df8efb613b0c3592d535f603Derek SollenbergerSk64 SkBitmap::ComputeSafeSize64(Config config,
232f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                                 uint32_t width,
233f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                                 uint32_t height,
234f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                                 uint32_t rowBytes) {
235f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    Sk64 safeSize;
236f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    safeSize.setZero();
237f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    if (height > 0) {
238f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        safeSize.set(ComputeRowBytes(config, width));
239f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        Sk64 sizeAllButLastRow;
240f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        sizeAllButLastRow.setMul(height - 1, rowBytes);
241f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        safeSize.add(sizeAllButLastRow);
242f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    }
243f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    SkASSERT(!safeSize.isNeg());
244f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    return safeSize;
245f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger}
246f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
247f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergersize_t SkBitmap::ComputeSafeSize(Config config,
248f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                                 uint32_t width,
249f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                                 uint32_t height,
250f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                                 uint32_t rowBytes) {
251f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    Sk64 safeSize = ComputeSafeSize64(config, width, height, rowBytes);
252f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    return (safeSize.is32() ? safeSize.get32() : 0);
253f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger}
254f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
255f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergervoid SkBitmap::setConfig(Config c, int width, int height, int rowBytes) {
256f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    this->freePixels();
257f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
258f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    if ((width | height | rowBytes) < 0) {
259f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        goto err;
260f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    }
261f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
262f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    if (rowBytes == 0) {
263f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        rowBytes = SkBitmap::ComputeRowBytes(c, width);
264f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        if (0 == rowBytes && kNo_Config != c) {
265f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            goto err;
266f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        }
267f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    }
268f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
269f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    fConfig     = SkToU8(c);
270f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    fWidth      = width;
271f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    fHeight     = height;
272f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    fRowBytes   = rowBytes;
273f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
274f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    fBytesPerPixel = (uint8_t)ComputeBytesPerPixel(c);
275f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
276f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    SkDEBUGCODE(this->validate();)
277f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    return;
278f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
279f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    // if we got here, we had an error, so we reset the bitmap to empty
280f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergererr:
281f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    this->reset();
282f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger}
283f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
284f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergervoid SkBitmap::updatePixelsFromRef() const {
285f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    if (NULL != fPixelRef) {
286f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        if (fPixelLockCount > 0) {
287f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            SkASSERT(fPixelRef->isLocked());
288f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
289f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            void* p = fPixelRef->pixels();
290f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            if (NULL != p) {
291f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                p = (char*)p + fPixelRefOffset;
292f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            }
293f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            fPixels = p;
294f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            SkRefCnt_SafeAssign(fColorTable, fPixelRef->colorTable());
295f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        } else {
296f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            SkASSERT(0 == fPixelLockCount);
297f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            fPixels = NULL;
298f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            if (fColorTable) {
299f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                fColorTable->unref();
300f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                fColorTable = NULL;
301f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            }
302f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        }
303f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    }
304f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger}
305f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
306f8cacf6b11e35785df8efb613b0c3592d535f603Derek SollenbergerSkPixelRef* SkBitmap::setPixelRef(SkPixelRef* pr, size_t offset) {
307f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    // do this first, we that we never have a non-zero offset with a null ref
308f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    if (NULL == pr) {
309f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        offset = 0;
310f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    }
311f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
312f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    if (fPixelRef != pr || fPixelRefOffset != offset) {
313f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        if (fPixelRef != pr) {
314f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            this->freePixels();
315f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            SkASSERT(NULL == fPixelRef);
316f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
317f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            SkSafeRef(pr);
318f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            fPixelRef = pr;
319f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        }
320f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        fPixelRefOffset = offset;
321f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        this->updatePixelsFromRef();
322f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    }
323f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
324f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    SkDEBUGCODE(this->validate();)
325f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    return pr;
326f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger}
327f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
328f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergervoid SkBitmap::lockPixels() const {
329f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    if (NULL != fPixelRef && 1 == ++fPixelLockCount) {
330f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        fPixelRef->lockPixels();
331f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        this->updatePixelsFromRef();
332f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    }
333f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    SkDEBUGCODE(this->validate();)
334f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger}
335f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
336f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergervoid SkBitmap::unlockPixels() const {
337f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    SkASSERT(NULL == fPixelRef || fPixelLockCount > 0);
338f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
339f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    if (NULL != fPixelRef && 0 == --fPixelLockCount) {
340f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        fPixelRef->unlockPixels();
341f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        this->updatePixelsFromRef();
342f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    }
343f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    SkDEBUGCODE(this->validate();)
344f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger}
345f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
346f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerbool SkBitmap::lockPixelsAreWritable() const {
347f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    if (fPixelRef) {
348f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        return fPixelRef->lockPixelsAreWritable();
349f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    } else {
350f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        return fPixels != NULL;
351f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    }
352f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger}
353f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
354f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergervoid SkBitmap::setPixels(void* p, SkColorTable* ctable) {
355f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    this->freePixels();
356f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    fPixels = p;
357f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    SkRefCnt_SafeAssign(fColorTable, ctable);
358f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
359f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    SkDEBUGCODE(this->validate();)
360f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger}
361f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
362f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerbool SkBitmap::allocPixels(Allocator* allocator, SkColorTable* ctable) {
363f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    HeapAllocator stdalloc;
364f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
365f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    if (NULL == allocator) {
366f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        allocator = &stdalloc;
367f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    }
368f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    return allocator->allocPixelRef(this, ctable);
369f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger}
370f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
371f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergervoid SkBitmap::freePixels() {
372f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    // if we're gonna free the pixels, we certainly need to free the mipmap
373f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    this->freeMipMap();
374f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
375f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    if (fColorTable) {
376f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        fColorTable->unref();
377f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        fColorTable = NULL;
378f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    }
379f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
380f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    if (NULL != fPixelRef) {
381f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        if (fPixelLockCount > 0) {
382f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            fPixelRef->unlockPixels();
383f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        }
384f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        fPixelRef->unref();
385f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        fPixelRef = NULL;
386f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        fPixelRefOffset = 0;
387f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    }
388f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    fPixelLockCount = 0;
389f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    fPixels = NULL;
390f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger}
391f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
392f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergervoid SkBitmap::freeMipMap() {
393f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    if (fMipMap) {
394f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        fMipMap->unref();
395f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        fMipMap = NULL;
396f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    }
397f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger}
398f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
399f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergeruint32_t SkBitmap::getGenerationID() const {
400f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    if (fPixelRef) {
401f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        return fPixelRef->getGenerationID();
402f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    } else {
403f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        SkASSERT(fPixels || !fRawPixelGenerationID);
404f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        if (fPixels && !fRawPixelGenerationID) {
405f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            fRawPixelGenerationID = SkNextPixelRefGenerationID();
406f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        }
407f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        return fRawPixelGenerationID;
408f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    }
409f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger}
410f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
411f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergervoid SkBitmap::notifyPixelsChanged() const {
412f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    SkASSERT(!this->isImmutable());
413f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    if (fPixelRef) {
414f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        fPixelRef->notifyPixelsChanged();
415f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    } else {
416f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        fRawPixelGenerationID = 0; // will grab next ID in getGenerationID
417f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    }
418f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger}
419f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
420f8cacf6b11e35785df8efb613b0c3592d535f603Derek SollenbergerSkGpuTexture* SkBitmap::getTexture() const {
421f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    return fPixelRef ? fPixelRef->getTexture() : NULL;
422f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger}
423f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
424f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger///////////////////////////////////////////////////////////////////////////////
425f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
426f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger/** We explicitly use the same allocator for our pixels that SkMask does,
427f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger so that we can freely assign memory allocated by one class to the other.
428f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger */
429f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerbool SkBitmap::HeapAllocator::allocPixelRef(SkBitmap* dst,
430f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                                            SkColorTable* ctable) {
431f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    Sk64 size = dst->getSize64();
432f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    if (size.isNeg() || !size.is32()) {
433f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        return false;
434f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    }
435f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
436f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    void* addr = sk_malloc_flags(size.get32(), 0);  // returns NULL on failure
437f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    if (NULL == addr) {
438f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        return false;
439f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    }
440f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
441f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    dst->setPixelRef(new SkMallocPixelRef(addr, size.get32(), ctable))->unref();
442f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    // since we're already allocated, we lockPixels right away
443f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    dst->lockPixels();
444f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    return true;
445f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger}
446f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
447f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger///////////////////////////////////////////////////////////////////////////////
448f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
449f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergersize_t SkBitmap::getSafeSize() const {
450f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    // This is intended to be a size_t version of ComputeSafeSize64(), just
451f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    // faster. The computation is meant to be identical.
452f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    return (fHeight ? ((fHeight - 1) * fRowBytes) +
453f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            ComputeRowBytes(getConfig(), fWidth): 0);
454f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger}
455f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
456f8cacf6b11e35785df8efb613b0c3592d535f603Derek SollenbergerSk64 SkBitmap::getSafeSize64() const {
457f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    return ComputeSafeSize64(getConfig(), fWidth, fHeight, fRowBytes);
458f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger}
459f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
460f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerbool SkBitmap::copyPixelsTo(void* const dst, size_t dstSize,
461f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                            int dstRowBytes, bool preserveDstPad) const {
462f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
463f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    if (dstRowBytes == -1)
464f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        dstRowBytes = fRowBytes;
465f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    SkASSERT(dstRowBytes >= 0);
466f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
467f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    if (getConfig() == kRLE_Index8_Config ||
468f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        dstRowBytes < ComputeRowBytes(getConfig(), fWidth) ||
469f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        dst == NULL || (getPixels() == NULL && pixelRef() == NULL))
470f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        return false;
471f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
472f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    if (!preserveDstPad && static_cast<uint32_t>(dstRowBytes) == fRowBytes) {
473f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        size_t safeSize = getSafeSize();
474f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        if (safeSize > dstSize || safeSize == 0)
475f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            return false;
476f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        else {
477f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            SkAutoLockPixels lock(*this);
478f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            // This implementation will write bytes beyond the end of each row,
479f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            // excluding the last row, if the bitmap's stride is greater than
480f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            // strictly required by the current config.
481f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            memcpy(dst, getPixels(), safeSize);
482f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
483f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            return true;
484f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        }
485f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    } else {
486f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        // If destination has different stride than us, then copy line by line.
487f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        if (ComputeSafeSize(getConfig(), fWidth, fHeight, dstRowBytes) >
488f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            dstSize)
489f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            return false;
490f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        else {
491f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            // Just copy what we need on each line.
492f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            uint32_t rowBytes = ComputeRowBytes(getConfig(), fWidth);
493f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            SkAutoLockPixels lock(*this);
494f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            const uint8_t* srcP = reinterpret_cast<const uint8_t*>(getPixels());
495f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            uint8_t* dstP = reinterpret_cast<uint8_t*>(dst);
496f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            for (uint32_t row = 0; row < fHeight;
497f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                 row++, srcP += fRowBytes, dstP += dstRowBytes) {
498f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                memcpy(dstP, srcP, rowBytes);
499f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            }
500f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
501f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            return true;
502f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        }
503f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    }
504f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger}
505f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
506f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger///////////////////////////////////////////////////////////////////////////////
507f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
508f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerbool SkBitmap::isImmutable() const {
509f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    return fPixelRef ? fPixelRef->isImmutable() :
510f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        fFlags & kImageIsImmutable_Flag;
511f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger}
512f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
513f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergervoid SkBitmap::setImmutable() {
514f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    if (fPixelRef) {
515f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        fPixelRef->setImmutable();
516f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    } else {
517f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        fFlags |= kImageIsImmutable_Flag;
518f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    }
519f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger}
520f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
521f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerbool SkBitmap::isOpaque() const {
522f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    switch (fConfig) {
523f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        case kNo_Config:
524f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            return true;
525f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
526f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        case kA1_Config:
527f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        case kA8_Config:
528f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        case kARGB_4444_Config:
529f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        case kARGB_8888_Config:
530f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            return (fFlags & kImageIsOpaque_Flag) != 0;
531f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
532f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        case kIndex8_Config:
533f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        case kRLE_Index8_Config: {
534f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                uint32_t flags = 0;
535f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
536f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                this->lockPixels();
537f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                // if lockPixels failed, we may not have a ctable ptr
538f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                if (fColorTable) {
539f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                    flags = fColorTable->getFlags();
540f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                }
541f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                this->unlockPixels();
542f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
543f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                return (flags & SkColorTable::kColorsAreOpaque_Flag) != 0;
544f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            }
545f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
546f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        case kRGB_565_Config:
547f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            return true;
548f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
549f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        default:
550f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            SkDEBUGFAIL("unknown bitmap config pased to isOpaque");
551f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            return false;
552f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    }
553f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger}
554f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
555f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergervoid SkBitmap::setIsOpaque(bool isOpaque) {
556f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    /*  we record this regardless of fConfig, though it is ignored in
557f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        isOpaque() for configs that can't support per-pixel alpha.
558f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    */
559f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    if (isOpaque) {
560f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        fFlags |= kImageIsOpaque_Flag;
561f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    } else {
562f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        fFlags &= ~kImageIsOpaque_Flag;
563f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    }
564f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger}
565f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
566f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerbool SkBitmap::isVolatile() const {
567f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    return (fFlags & kImageIsVolatile_Flag) != 0;
568f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger}
569f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
570f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergervoid SkBitmap::setIsVolatile(bool isVolatile) {
571f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    if (isVolatile) {
572f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        fFlags |= kImageIsVolatile_Flag;
573f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    } else {
574f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        fFlags &= ~kImageIsVolatile_Flag;
575f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    }
576f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger}
577f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
578f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergervoid* SkBitmap::getAddr(int x, int y) const {
579f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    SkASSERT((unsigned)x < (unsigned)this->width());
580f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    SkASSERT((unsigned)y < (unsigned)this->height());
581f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
582f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    char* base = (char*)this->getPixels();
583f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    if (base) {
584f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        base += y * this->rowBytes();
585f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        switch (this->config()) {
586f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            case SkBitmap::kARGB_8888_Config:
587f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                base += x << 2;
588f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                break;
589f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            case SkBitmap::kARGB_4444_Config:
590f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            case SkBitmap::kRGB_565_Config:
591f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                base += x << 1;
592f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                break;
593f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            case SkBitmap::kA8_Config:
594f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            case SkBitmap::kIndex8_Config:
595f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                base += x;
596f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                break;
597f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            case SkBitmap::kA1_Config:
598f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                base += x >> 3;
599f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                break;
600f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            case kRLE_Index8_Config:
601f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                SkDEBUGFAIL("Can't return addr for kRLE_Index8_Config");
602f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                base = NULL;
603f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                break;
604f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            default:
605f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                SkDEBUGFAIL("Can't return addr for config");
606f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                base = NULL;
607f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                break;
608f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        }
609f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    }
610f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    return base;
611f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger}
612f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
613f8cacf6b11e35785df8efb613b0c3592d535f603Derek SollenbergerSkColor SkBitmap::getColor(int x, int y) const {
614f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    SkASSERT((unsigned)x < (unsigned)this->width());
615f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    SkASSERT((unsigned)y < (unsigned)this->height());
616f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
617f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    switch (this->config()) {
618f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        case SkBitmap::kA1_Config: {
619f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            uint8_t* addr = this->getAddr1(x, y);
620f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            uint8_t mask = 1 << (7  - (x % 8));
621f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            if (addr[0] & mask) {
622f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                return SK_ColorBLACK;
623f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            } else {
624f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                return 0;
625f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            }
626f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        }
627f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        case SkBitmap::kA8_Config: {
628f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            uint8_t* addr = this->getAddr8(x, y);
629f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            return SkColorSetA(0, addr[0]);
630f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        }
631f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        case SkBitmap::kIndex8_Config: {
632f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            SkPMColor c = this->getIndex8Color(x, y);
633f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            return SkUnPreMultiply::PMColorToColor(c);
634f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        }
635f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        case SkBitmap::kRGB_565_Config: {
636f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            uint16_t* addr = this->getAddr16(x, y);
637f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            return SkPixel16ToColor(addr[0]);
638f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        }
639f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        case SkBitmap::kARGB_4444_Config: {
640f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            uint16_t* addr = this->getAddr16(x, y);
641f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            SkPMColor c = SkPixel4444ToPixel32(addr[0]);
642f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            return SkUnPreMultiply::PMColorToColor(c);
643f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        }
644f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        case SkBitmap::kARGB_8888_Config: {
645f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            uint32_t* addr = this->getAddr32(x, y);
646f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            return SkUnPreMultiply::PMColorToColor(addr[0]);
647f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        }
648f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        case kRLE_Index8_Config: {
649f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            uint8_t dst;
650f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            const SkBitmap::RLEPixels* rle =
651f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                (const SkBitmap::RLEPixels*)this->getPixels();
652f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            SkPackBits::Unpack8(&dst, x, 1, rle->packedAtY(y));
653f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            return SkUnPreMultiply::PMColorToColor((*fColorTable)[dst]);
654f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        }
655f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        case kNo_Config:
656f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        case kConfigCount:
657f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            SkASSERT(false);
658f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            return 0;
659f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    }
660f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    SkASSERT(false);  // Not reached.
661f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    return 0;
662f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger}
663f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
664f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger///////////////////////////////////////////////////////////////////////////////
665f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger///////////////////////////////////////////////////////////////////////////////
666f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
667f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergervoid SkBitmap::eraseARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b) const {
668f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    SkDEBUGCODE(this->validate();)
669f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
670f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    if (0 == fWidth || 0 == fHeight ||
671f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            kNo_Config == fConfig || kIndex8_Config == fConfig) {
672f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        return;
673f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    }
674f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
675f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    SkAutoLockPixels alp(*this);
676f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    // perform this check after the lock call
677f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    if (!this->readyToDraw()) {
678f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        return;
679f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    }
680f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
681f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    int height = fHeight;
682f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    const int width = fWidth;
683f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    const int rowBytes = fRowBytes;
684f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
685f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    // make rgb premultiplied
686f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    if (255 != a) {
687f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        r = SkAlphaMul(r, a);
688f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        g = SkAlphaMul(g, a);
689f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        b = SkAlphaMul(b, a);
690f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    }
691f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
692f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    switch (fConfig) {
693f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        case kA1_Config: {
694f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            uint8_t* p = (uint8_t*)fPixels;
695f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            const int count = (width + 7) >> 3;
696f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            a = (a >> 7) ? 0xFF : 0;
697f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            SkASSERT(count <= rowBytes);
698f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            while (--height >= 0) {
699f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                memset(p, a, count);
700f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                p += rowBytes;
701f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            }
702f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            break;
703f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        }
704f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        case kA8_Config: {
705f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            uint8_t* p = (uint8_t*)fPixels;
706f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            while (--height >= 0) {
707f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                memset(p, a, width);
708f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                p += rowBytes;
709f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            }
710f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            break;
711f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        }
712f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        case kARGB_4444_Config:
713f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        case kRGB_565_Config: {
714f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            uint16_t* p = (uint16_t*)fPixels;
715f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            uint16_t v;
716f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
717f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            if (kARGB_4444_Config == fConfig) {
718f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                v = SkPackARGB4444(a >> 4, r >> 4, g >> 4, b >> 4);
719f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            } else {    // kRGB_565_Config
720f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                v = SkPackRGB16(r >> (8 - SK_R16_BITS), g >> (8 - SK_G16_BITS),
721f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                                b >> (8 - SK_B16_BITS));
722f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            }
723f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            while (--height >= 0) {
724f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                sk_memset16(p, v, width);
725f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                p = (uint16_t*)((char*)p + rowBytes);
726f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            }
727f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            break;
728f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        }
729f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        case kARGB_8888_Config: {
730f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            uint32_t* p = (uint32_t*)fPixels;
731f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            uint32_t  v = SkPackARGB32(a, r, g, b);
732f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
733f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            while (--height >= 0) {
734f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                sk_memset32(p, v, width);
735f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                p = (uint32_t*)((char*)p + rowBytes);
736f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            }
737f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            break;
738f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        }
739f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    }
740f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
741f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    this->notifyPixelsChanged();
742f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger}
743f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
744f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger//////////////////////////////////////////////////////////////////////////////////////
745f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger//////////////////////////////////////////////////////////////////////////////////////
746f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
747f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger#define SUB_OFFSET_FAILURE  ((size_t)-1)
748f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
749f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerstatic size_t getSubOffset(const SkBitmap& bm, int x, int y) {
750f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    SkASSERT((unsigned)x < (unsigned)bm.width());
751f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    SkASSERT((unsigned)y < (unsigned)bm.height());
752f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
753f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    switch (bm.getConfig()) {
754f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        case SkBitmap::kA8_Config:
755f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        case SkBitmap:: kIndex8_Config:
756f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            // x is fine as is for the calculation
757f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            break;
758f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
759f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        case SkBitmap::kRGB_565_Config:
760f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        case SkBitmap::kARGB_4444_Config:
761f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            x <<= 1;
762f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            break;
763f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
764f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        case SkBitmap::kARGB_8888_Config:
765f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            x <<= 2;
766f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            break;
767f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
768f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        case SkBitmap::kNo_Config:
769f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        case SkBitmap::kA1_Config:
770f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        default:
771f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            return SUB_OFFSET_FAILURE;
772f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    }
773f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    return y * bm.rowBytes() + x;
774f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger}
775f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
776f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerbool SkBitmap::extractSubset(SkBitmap* result, const SkIRect& subset) const {
777f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    SkDEBUGCODE(this->validate();)
778f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
779f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    if (NULL == result || (NULL == fPixelRef && NULL == fPixels)) {
780f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        return false;   // no src pixels
781f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    }
782f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
783f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    SkIRect srcRect, r;
784f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    srcRect.set(0, 0, this->width(), this->height());
785f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    if (!r.intersect(srcRect, subset)) {
786f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        return false;   // r is empty (i.e. no intersection)
787f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    }
788f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
789f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    if (kRLE_Index8_Config == fConfig) {
790f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        SkAutoLockPixels alp(*this);
791f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        // don't call readyToDraw(), since we can operate w/o a colortable
792f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        // at this stage
793f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        if (this->getPixels() == NULL) {
794f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            return false;
795f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        }
796f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        SkBitmap bm;
797f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
798f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        bm.setConfig(kIndex8_Config, r.width(), r.height());
799f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        bm.allocPixels(this->getColorTable());
800f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        if (NULL == bm.getPixels()) {
801f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            return false;
802f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        }
803f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
804f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        const RLEPixels* rle = (const RLEPixels*)this->getPixels();
805f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        uint8_t* dst = bm.getAddr8(0, 0);
806f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        const int width = bm.width();
807f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        const int rowBytes = bm.rowBytes();
808f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
809f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        for (int y = r.fTop; y < r.fBottom; y++) {
810f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            SkPackBits::Unpack8(dst, r.fLeft, width, rle->packedAtY(y));
811f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            dst += rowBytes;
812f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        }
813f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        result->swap(bm);
814f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        return true;
815f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    }
816f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
817f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    size_t offset = getSubOffset(*this, r.fLeft, r.fTop);
818f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    if (SUB_OFFSET_FAILURE == offset) {
819f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        return false;   // config not supported
820f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    }
821f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
822f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    SkBitmap dst;
823f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    dst.setConfig(this->config(), r.width(), r.height(), this->rowBytes());
824f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    dst.setIsVolatile(this->isVolatile());
825f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
826f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    if (fPixelRef) {
827f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        // share the pixelref with a custom offset
828f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        dst.setPixelRef(fPixelRef, fPixelRefOffset + offset);
829f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    } else {
830f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        // share the pixels (owned by the caller)
831f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        dst.setPixels((char*)fPixels + offset, this->getColorTable());
832f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    }
833f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    SkDEBUGCODE(dst.validate();)
834f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
835f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    // we know we're good, so commit to result
836f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    result->swap(dst);
837f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    return true;
838f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger}
839f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
840f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger///////////////////////////////////////////////////////////////////////////////
841f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
842f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger#include "SkCanvas.h"
843f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger#include "SkPaint.h"
844f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
845f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerbool SkBitmap::canCopyTo(Config dstConfig) const {
846f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    if (this->getConfig() == kNo_Config) {
847f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        return false;
848f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    }
849f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
850f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    bool sameConfigs = (this->config() == dstConfig);
851f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    switch (dstConfig) {
852f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        case kA8_Config:
853f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        case kARGB_4444_Config:
854f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        case kRGB_565_Config:
855f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        case kARGB_8888_Config:
856f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            break;
857f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        case kA1_Config:
858f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        case kIndex8_Config:
859f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            if (!sameConfigs) {
860f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                return false;
861f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            }
862f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            break;
863f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        default:
864f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            return false;
865f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    }
866f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
867f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    // do not copy src if srcConfig == kA1_Config while dstConfig != kA1_Config
868f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    if (this->getConfig() == kA1_Config && !sameConfigs) {
869f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        return false;
870f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    }
871f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
872f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    return true;
873f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger}
874f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
875f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerbool SkBitmap::copyTo(SkBitmap* dst, Config dstConfig, Allocator* alloc) const {
876f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    if (!this->canCopyTo(dstConfig)) {
877f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        return false;
878f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    }
879f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
880f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    // if we have a texture, first get those pixels
881f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    SkBitmap tmpSrc;
882f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    const SkBitmap* src = this;
883f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
884f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    if (fPixelRef && fPixelRef->readPixels(&tmpSrc)) {
885f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        SkASSERT(tmpSrc.width() == this->width());
886f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        SkASSERT(tmpSrc.height() == this->height());
887f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
888f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        // did we get lucky and we can just return tmpSrc?
889f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        if (tmpSrc.config() == dstConfig && NULL == alloc) {
890f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            dst->swap(tmpSrc);
891f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            return true;
892f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        }
893f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
894f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        // fall through to the raster case
895f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        src = &tmpSrc;
896f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    }
897f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
898f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    // we lock this now, since we may need its colortable
899f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    SkAutoLockPixels srclock(*src);
900f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    if (!src->readyToDraw()) {
901f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        return false;
902f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    }
903f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
904f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    SkBitmap tmpDst;
905f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    tmpDst.setConfig(dstConfig, src->width(), src->height());
906f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
907f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    // allocate colortable if srcConfig == kIndex8_Config
908f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    SkColorTable* ctable = (dstConfig == kIndex8_Config) ?
909f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    new SkColorTable(*src->getColorTable()) : NULL;
910f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    SkAutoUnref au(ctable);
911f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    if (!tmpDst.allocPixels(alloc, ctable)) {
912f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        return false;
913f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    }
914f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
915f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    SkAutoLockPixels dstlock(tmpDst);
916f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    if (!tmpDst.readyToDraw()) {
917f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        // allocator/lock failed
918f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        return false;
919f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    }
920f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
921f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    /* do memcpy for the same configs cases, else use drawing
922f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    */
923f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    if (src->config() == dstConfig) {
924f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        if (tmpDst.getSize() == src->getSize()) {
925f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            memcpy(tmpDst.getPixels(), src->getPixels(), src->getSafeSize());
926f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        } else {
927f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            const char* srcP = reinterpret_cast<const char*>(src->getPixels());
928f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            char* dstP = reinterpret_cast<char*>(tmpDst.getPixels());
929f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            // to be sure we don't read too much, only copy our logical pixels
930f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            size_t bytesToCopy = tmpDst.width() * tmpDst.bytesPerPixel();
931f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            for (int y = 0; y < tmpDst.height(); y++) {
932f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                memcpy(dstP, srcP, bytesToCopy);
933f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                srcP += src->rowBytes();
934f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                dstP += tmpDst.rowBytes();
935f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            }
936f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        }
937f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    } else {
938f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        // if the src has alpha, we have to clear the dst first
939f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        if (!src->isOpaque()) {
940f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            tmpDst.eraseColor(0);
941f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        }
942f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
943f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        SkCanvas canvas(tmpDst);
944f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        SkPaint  paint;
945f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
946f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        paint.setDither(true);
947f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        canvas.drawBitmap(*src, 0, 0, &paint);
948f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    }
949f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
950f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    tmpDst.setIsOpaque(src->isOpaque());
951f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
952f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    dst->swap(tmpDst);
953f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    return true;
954f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger}
955f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
956f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerbool SkBitmap::deepCopyTo(SkBitmap* dst, Config dstConfig) const {
957f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    if (!this->canCopyTo(dstConfig)) {
958f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        return false;
959f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    }
960f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
961f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    // If we have a PixelRef, and it supports deep copy, use it.
962f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    // Currently supported only by texture-backed bitmaps.
963f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    if (fPixelRef) {
964f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        SkPixelRef* pixelRef = fPixelRef->deepCopy(dstConfig);
965f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        if (pixelRef) {
966f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            dst->setConfig(dstConfig, fWidth, fHeight);
967f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            dst->setPixelRef(pixelRef)->unref();
968f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            return true;
969f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        }
970f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    }
971f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
972f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    if (this->getTexture()) {
973f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        return false;
974f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    } else {
975f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        return this->copyTo(dst, dstConfig, NULL);
976f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    }
977f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger}
978f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
979f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger///////////////////////////////////////////////////////////////////////////////
980f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger///////////////////////////////////////////////////////////////////////////////
981f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
982f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerstatic void downsampleby2_proc32(SkBitmap* dst, int x, int y,
983f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                                 const SkBitmap& src) {
984f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    x <<= 1;
985f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    y <<= 1;
986f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    const SkPMColor* p = src.getAddr32(x, y);
987f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    const SkPMColor* baseP = p;
988f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    SkPMColor c, ag, rb;
989f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
990f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    c = *p; ag = (c >> 8) & 0xFF00FF; rb = c & 0xFF00FF;
991f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    if (x < src.width() - 1) {
992f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        p += 1;
993f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    }
994f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    c = *p; ag += (c >> 8) & 0xFF00FF; rb += c & 0xFF00FF;
995f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
996f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    p = baseP;
997f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    if (y < src.height() - 1) {
998f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        p += src.rowBytes() >> 2;
999f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    }
1000f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    c = *p; ag += (c >> 8) & 0xFF00FF; rb += c & 0xFF00FF;
1001f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    if (x < src.width() - 1) {
1002f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        p += 1;
1003f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    }
1004f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    c = *p; ag += (c >> 8) & 0xFF00FF; rb += c & 0xFF00FF;
1005f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
1006f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    *dst->getAddr32(x >> 1, y >> 1) =
1007f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        ((rb >> 2) & 0xFF00FF) | ((ag << 6) & 0xFF00FF00);
1008f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger}
1009f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
1010f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerstatic inline uint32_t expand16(U16CPU c) {
1011f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    return (c & ~SK_G16_MASK_IN_PLACE) | ((c & SK_G16_MASK_IN_PLACE) << 16);
1012f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger}
1013f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
1014f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger// returns dirt in the top 16bits, but we don't care, since we only
1015f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger// store the low 16bits.
1016f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerstatic inline U16CPU pack16(uint32_t c) {
1017f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    return (c & ~SK_G16_MASK_IN_PLACE) | ((c >> 16) & SK_G16_MASK_IN_PLACE);
1018f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger}
1019f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
1020f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerstatic void downsampleby2_proc16(SkBitmap* dst, int x, int y,
1021f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                                 const SkBitmap& src) {
1022f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    x <<= 1;
1023f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    y <<= 1;
1024f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    const uint16_t* p = src.getAddr16(x, y);
1025f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    const uint16_t* baseP = p;
1026f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    SkPMColor       c;
1027f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
1028f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    c = expand16(*p);
1029f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    if (x < src.width() - 1) {
1030f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        p += 1;
1031f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    }
1032f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    c += expand16(*p);
1033f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
1034f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    p = baseP;
1035f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    if (y < src.height() - 1) {
1036f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        p += src.rowBytes() >> 1;
1037f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    }
1038f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    c += expand16(*p);
1039f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    if (x < src.width() - 1) {
1040f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        p += 1;
1041f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    }
1042f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    c += expand16(*p);
1043f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
1044f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    *dst->getAddr16(x >> 1, y >> 1) = (uint16_t)pack16(c >> 2);
1045f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger}
1046f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
1047f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerstatic uint32_t expand4444(U16CPU c) {
1048f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    return (c & 0xF0F) | ((c & ~0xF0F) << 12);
1049f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger}
1050f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
1051f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerstatic U16CPU collaps4444(uint32_t c) {
1052f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    return (c & 0xF0F) | ((c >> 12) & ~0xF0F);
1053f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger}
1054f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
1055f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerstatic void downsampleby2_proc4444(SkBitmap* dst, int x, int y,
1056f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                                   const SkBitmap& src) {
1057f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    x <<= 1;
1058f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    y <<= 1;
1059f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    const uint16_t* p = src.getAddr16(x, y);
1060f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    const uint16_t* baseP = p;
1061f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    uint32_t        c;
1062f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
1063f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    c = expand4444(*p);
1064f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    if (x < src.width() - 1) {
1065f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        p += 1;
1066f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    }
1067f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    c += expand4444(*p);
1068f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
1069f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    p = baseP;
1070f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    if (y < src.height() - 1) {
1071f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        p += src.rowBytes() >> 1;
1072f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    }
1073f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    c += expand4444(*p);
1074f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    if (x < src.width() - 1) {
1075f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        p += 1;
1076f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    }
1077f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    c += expand4444(*p);
1078f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
1079f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    *dst->getAddr16(x >> 1, y >> 1) = (uint16_t)collaps4444(c >> 2);
1080f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger}
1081f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
1082f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergervoid SkBitmap::buildMipMap(bool forceRebuild) {
1083f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    if (forceRebuild)
1084f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        this->freeMipMap();
1085f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    else if (fMipMap)
1086f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        return; // we're already built
1087f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
1088f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    SkASSERT(NULL == fMipMap);
1089f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
1090f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    void (*proc)(SkBitmap* dst, int x, int y, const SkBitmap& src);
1091f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
1092f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    const SkBitmap::Config config = this->getConfig();
1093f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
1094f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    switch (config) {
1095f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        case kARGB_8888_Config:
1096f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            proc = downsampleby2_proc32;
1097f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            break;
1098f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        case kRGB_565_Config:
1099f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            proc = downsampleby2_proc16;
1100f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            break;
1101f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        case kARGB_4444_Config:
1102f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            proc = downsampleby2_proc4444;
1103f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            break;
1104f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        case kIndex8_Config:
1105f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        case kA8_Config:
1106f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        default:
1107f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            return; // don't build mipmaps for these configs
1108f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    }
1109f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
1110f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    SkAutoLockPixels alp(*this);
1111f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    if (!this->readyToDraw()) {
1112f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        return;
1113f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    }
1114f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
1115f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    // whip through our loop to compute the exact size needed
1116f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    size_t  size = 0;
1117f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    int     maxLevels = 0;
1118f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    {
1119f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        int width = this->width();
1120f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        int height = this->height();
1121f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        for (;;) {
1122f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            width >>= 1;
1123f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            height >>= 1;
1124f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            if (0 == width || 0 == height) {
1125f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                break;
1126f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            }
1127f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            size += ComputeRowBytes(config, width) * height;
1128f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            maxLevels += 1;
1129f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        }
1130f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    }
1131f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
1132f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    // nothing to build
1133f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    if (0 == maxLevels) {
1134f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        return;
1135f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    }
1136f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
1137f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    SkBitmap srcBM(*this);
1138f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    srcBM.lockPixels();
1139f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    if (!srcBM.readyToDraw()) {
1140f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        return;
1141f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    }
1142f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
1143f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    MipMap* mm = MipMap::Alloc(maxLevels, size);
1144f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    if (NULL == mm) {
1145f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        return;
1146f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    }
1147f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
1148f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    MipLevel*   level = mm->levels();
1149f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    uint8_t*    addr = (uint8_t*)mm->pixels();
1150f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    int         width = this->width();
1151f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    int         height = this->height();
1152f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    unsigned    rowBytes = this->rowBytes();
1153f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    SkBitmap    dstBM;
1154f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
1155f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    for (int i = 0; i < maxLevels; i++) {
1156f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        width >>= 1;
1157f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        height >>= 1;
1158f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        rowBytes = ComputeRowBytes(config, width);
1159f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
1160f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        level[i].fPixels   = addr;
1161f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        level[i].fWidth    = width;
1162f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        level[i].fHeight   = height;
1163f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        level[i].fRowBytes = rowBytes;
1164f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
1165f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        dstBM.setConfig(config, width, height, rowBytes);
1166f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        dstBM.setPixels(addr);
1167f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
1168f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        for (int y = 0; y < height; y++) {
1169f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            for (int x = 0; x < width; x++) {
1170f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                proc(&dstBM, x, y, srcBM);
1171f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            }
1172f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        }
1173f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
1174f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        srcBM = dstBM;
1175f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        addr += height * rowBytes;
1176f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    }
1177f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    SkASSERT(addr == (uint8_t*)mm->pixels() + size);
1178f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    fMipMap = mm;
1179f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger}
1180f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
1181f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerbool SkBitmap::hasMipMap() const {
1182f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    return fMipMap != NULL;
1183f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger}
1184f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
1185f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerint SkBitmap::extractMipLevel(SkBitmap* dst, SkFixed sx, SkFixed sy) {
1186f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    if (NULL == fMipMap) {
1187f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        return 0;
1188f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    }
1189f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
1190f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    int level = ComputeMipLevel(sx, sy) >> 16;
1191f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    SkASSERT(level >= 0);
1192f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    if (level <= 0) {
1193f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        return 0;
1194f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    }
1195f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
1196f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    if (level >= fMipMap->fLevelCount) {
1197f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        level = fMipMap->fLevelCount - 1;
1198f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    }
1199f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    if (dst) {
1200f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        const MipLevel& mip = fMipMap->levels()[level - 1];
1201f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        dst->setConfig((SkBitmap::Config)this->config(),
1202f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                       mip.fWidth, mip.fHeight, mip.fRowBytes);
1203f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        dst->setPixels(mip.fPixels);
1204f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    }
1205f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    return level;
1206f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger}
1207f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
1208f8cacf6b11e35785df8efb613b0c3592d535f603Derek SollenbergerSkFixed SkBitmap::ComputeMipLevel(SkFixed sx, SkFixed sy) {
1209f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    sx = SkAbs32(sx);
1210f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    sy = SkAbs32(sy);
1211f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    if (sx < sy) {
1212f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        sx = sy;
1213f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    }
1214f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    if (sx < SK_Fixed1) {
1215f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        return 0;
1216f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    }
1217f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    int clz = SkCLZ(sx);
1218f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    SkASSERT(clz >= 1 && clz <= 15);
1219f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    return SkIntToFixed(15 - clz) + ((unsigned)(sx << (clz + 1)) >> 16);
1220f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger}
1221f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
1222f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger///////////////////////////////////////////////////////////////////////////////
1223f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
1224f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerstatic bool GetBitmapAlpha(const SkBitmap& src, uint8_t* SK_RESTRICT alpha,
1225f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                           int alphaRowBytes) {
1226f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    SkASSERT(alpha != NULL);
1227f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    SkASSERT(alphaRowBytes >= src.width());
1228f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
1229f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    SkBitmap::Config config = src.getConfig();
1230f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    int              w = src.width();
1231f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    int              h = src.height();
1232f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    int              rb = src.rowBytes();
1233f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
1234f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    SkAutoLockPixels alp(src);
1235f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    if (!src.readyToDraw()) {
1236f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        // zero out the alpha buffer and return
1237f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        while (--h >= 0) {
1238f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            memset(alpha, 0, w);
1239f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            alpha += alphaRowBytes;
1240f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        }
1241f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        return false;
1242f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    }
1243f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
1244f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    if (SkBitmap::kA8_Config == config && !src.isOpaque()) {
1245f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        const uint8_t* s = src.getAddr8(0, 0);
1246f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        while (--h >= 0) {
1247f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            memcpy(alpha, s, w);
1248f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            s += rb;
1249f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            alpha += alphaRowBytes;
1250f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        }
1251f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    } else if (SkBitmap::kARGB_8888_Config == config && !src.isOpaque()) {
1252f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        const SkPMColor* SK_RESTRICT s = src.getAddr32(0, 0);
1253f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        while (--h >= 0) {
1254f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            for (int x = 0; x < w; x++) {
1255f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                alpha[x] = SkGetPackedA32(s[x]);
1256f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            }
1257f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            s = (const SkPMColor*)((const char*)s + rb);
1258f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            alpha += alphaRowBytes;
1259f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        }
1260f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    } else if (SkBitmap::kARGB_4444_Config == config && !src.isOpaque()) {
1261f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        const SkPMColor16* SK_RESTRICT s = src.getAddr16(0, 0);
1262f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        while (--h >= 0) {
1263f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            for (int x = 0; x < w; x++) {
1264f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                alpha[x] = SkPacked4444ToA32(s[x]);
1265f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            }
1266f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            s = (const SkPMColor16*)((const char*)s + rb);
1267f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            alpha += alphaRowBytes;
1268f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        }
1269f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    } else if (SkBitmap::kIndex8_Config == config && !src.isOpaque()) {
1270f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        SkColorTable* ct = src.getColorTable();
1271f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        if (ct) {
1272f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            const SkPMColor* SK_RESTRICT table = ct->lockColors();
1273f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            const uint8_t* SK_RESTRICT s = src.getAddr8(0, 0);
1274f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            while (--h >= 0) {
1275f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                for (int x = 0; x < w; x++) {
1276f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                    alpha[x] = SkGetPackedA32(table[s[x]]);
1277f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                }
1278f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                s += rb;
1279f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                alpha += alphaRowBytes;
1280f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            }
1281f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            ct->unlockColors(false);
1282f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        }
1283f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    } else {    // src is opaque, so just fill alpha[] with 0xFF
1284f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        memset(alpha, 0xFF, h * alphaRowBytes);
1285f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    }
1286f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    return true;
1287f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger}
1288f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
1289f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger#include "SkPaint.h"
1290f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger#include "SkMaskFilter.h"
1291f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger#include "SkMatrix.h"
1292f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
1293f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerbool SkBitmap::extractAlpha(SkBitmap* dst, const SkPaint* paint,
1294f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                            Allocator *allocator, SkIPoint* offset) const {
1295f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    SkDEBUGCODE(this->validate();)
1296f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
1297f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    SkBitmap    tmpBitmap;
1298f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    SkMatrix    identity;
1299f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    SkMask      srcM, dstM;
1300f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
1301f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    srcM.fBounds.set(0, 0, this->width(), this->height());
1302f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    srcM.fRowBytes = SkAlign4(this->width());
1303f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    srcM.fFormat = SkMask::kA8_Format;
1304f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
1305f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    SkMaskFilter* filter = paint ? paint->getMaskFilter() : NULL;
1306f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
1307f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    // compute our (larger?) dst bounds if we have a filter
1308f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    if (NULL != filter) {
1309f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        identity.reset();
1310f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        srcM.fImage = NULL;
1311f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        if (!filter->filterMask(&dstM, srcM, identity, NULL)) {
1312f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            goto NO_FILTER_CASE;
1313f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        }
1314f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        dstM.fRowBytes = SkAlign4(dstM.fBounds.width());
1315f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    } else {
1316f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    NO_FILTER_CASE:
1317f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        tmpBitmap.setConfig(SkBitmap::kA8_Config, this->width(), this->height(),
1318f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                       srcM.fRowBytes);
1319f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        if (!tmpBitmap.allocPixels(allocator, NULL)) {
1320f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            // Allocation of pixels for alpha bitmap failed.
1321f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            SkDebugf("extractAlpha failed to allocate (%d,%d) alpha bitmap\n",
1322f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                    tmpBitmap.width(), tmpBitmap.height());
1323f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            return false;
1324f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        }
1325f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        GetBitmapAlpha(*this, tmpBitmap.getAddr8(0, 0), srcM.fRowBytes);
1326f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        if (offset) {
1327f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            offset->set(0, 0);
1328f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        }
1329f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        tmpBitmap.swap(*dst);
1330f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        return true;
1331f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    }
1332f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    srcM.fImage = SkMask::AllocImage(srcM.computeImageSize());
1333f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    SkAutoMaskFreeImage srcCleanup(srcM.fImage);
1334f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
1335f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    GetBitmapAlpha(*this, srcM.fImage, srcM.fRowBytes);
1336f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    if (!filter->filterMask(&dstM, srcM, identity, NULL)) {
1337f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        goto NO_FILTER_CASE;
1338f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    }
1339f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    SkAutoMaskFreeImage dstCleanup(dstM.fImage);
1340f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
1341f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    tmpBitmap.setConfig(SkBitmap::kA8_Config, dstM.fBounds.width(),
1342f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                   dstM.fBounds.height(), dstM.fRowBytes);
1343f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    if (!tmpBitmap.allocPixels(allocator, NULL)) {
1344f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        // Allocation of pixels for alpha bitmap failed.
1345f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        SkDebugf("extractAlpha failed to allocate (%d,%d) alpha bitmap\n",
1346f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                tmpBitmap.width(), tmpBitmap.height());
1347f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        return false;
1348f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    }
1349f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    memcpy(tmpBitmap.getPixels(), dstM.fImage, dstM.computeImageSize());
1350f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    if (offset) {
1351f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        offset->set(dstM.fBounds.fLeft, dstM.fBounds.fTop);
1352f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    }
1353f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    SkDEBUGCODE(tmpBitmap.validate();)
1354f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
1355f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    tmpBitmap.swap(*dst);
1356f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    return true;
1357f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger}
1358f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
1359f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger///////////////////////////////////////////////////////////////////////////////
1360f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
1361f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerenum {
1362f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    SERIALIZE_PIXELTYPE_NONE,
1363f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    SERIALIZE_PIXELTYPE_RAW_WITH_CTABLE,
1364f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    SERIALIZE_PIXELTYPE_RAW_NO_CTABLE,
1365f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    SERIALIZE_PIXELTYPE_REF_DATA,
1366f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    SERIALIZE_PIXELTYPE_REF_PTR,
1367f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger};
1368f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
1369f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerstatic void writeString(SkFlattenableWriteBuffer& buffer, const char str[]) {
1370f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    size_t len = strlen(str);
1371f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    buffer.write32(len);
1372f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    buffer.writePad(str, len);
1373f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger}
1374f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
1375f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerstatic SkPixelRef::Factory deserialize_factory(SkFlattenableReadBuffer& buffer) {
1376f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    size_t len = buffer.readInt();
1377f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    SkAutoSMalloc<256> storage(len + 1);
1378f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    char* str = (char*)storage.get();
1379f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    buffer.read(str, len);
1380f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    str[len] = 0;
1381f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    return SkPixelRef::NameToFactory(str);
1382f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger}
1383f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
1384f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger/*
1385f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    It is tricky to know how much to flatten. If we don't have a pixelref (i.e.
1386f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    we just have pixels, then we can only flatten the pixels, or write out an
1387f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    empty bitmap.
1388f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
1389f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    With a pixelref, we still have the question of recognizing when two sitings
1390f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    of the same pixelref are the same, and when they are different. Perhaps we
1391f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    should look at the generationID and keep a record of that in some dictionary
1392f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    associated with the buffer. SkGLTextureCache does this sort of thing to know
1393f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    when to create a new texture.
1394f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger*/
1395f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergervoid SkBitmap::flatten(SkFlattenableWriteBuffer& buffer) const {
1396f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    buffer.write32(fWidth);
1397f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    buffer.write32(fHeight);
1398f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    buffer.write32(fRowBytes);
1399f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    buffer.write8(fConfig);
1400f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    buffer.writeBool(this->isOpaque());
1401f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
1402f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    /*  If we are called in this mode, then it is up to the caller to manage
1403f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        the owner-counts on the pixelref, as we just record the ptr itself.
1404f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    */
1405f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    if (!buffer.persistBitmapPixels()) {
1406f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        if (fPixelRef) {
1407f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            buffer.write8(SERIALIZE_PIXELTYPE_REF_PTR);
1408f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            buffer.write32(fPixelRefOffset);
1409f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            buffer.writeRefCnt(fPixelRef);
1410f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            return;
1411f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        } else {
1412f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            // we ignore the non-persist request, since we don't have a ref
1413f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            // ... or we could just write an empty bitmap...
1414f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            // (true) will write an empty bitmap, (false) will flatten the pix
1415f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            if (true) {
1416f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                buffer.write8(SERIALIZE_PIXELTYPE_NONE);
1417f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                return;
1418f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            }
1419f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        }
1420f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    }
1421f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
1422f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    if (fPixelRef) {
1423f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        SkPixelRef::Factory fact = fPixelRef->getFactory();
1424f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        if (fact) {
1425f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            const char* name = SkPixelRef::FactoryToName(fact);
1426f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            if (name && *name) {
1427f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                buffer.write8(SERIALIZE_PIXELTYPE_REF_DATA);
1428f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                buffer.write32(fPixelRefOffset);
1429f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                writeString(buffer, name);
1430f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                fPixelRef->flatten(buffer);
1431f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                return;
1432f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            }
1433f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        }
1434f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        // if we get here, we can't record the pixels
1435f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        buffer.write8(SERIALIZE_PIXELTYPE_NONE);
1436f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    } else if (fPixels) {
1437f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        if (fColorTable) {
1438f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            buffer.write8(SERIALIZE_PIXELTYPE_RAW_WITH_CTABLE);
1439f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            fColorTable->flatten(buffer);
1440f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        } else {
1441f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            buffer.write8(SERIALIZE_PIXELTYPE_RAW_NO_CTABLE);
1442f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        }
1443f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        buffer.writePad(fPixels, this->getSafeSize());
1444f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        // There is no writeZeroPad() fcn, so write individual bytes.
1445f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        if (this->getSize() > this->getSafeSize()) {
1446f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            size_t deltaSize = this->getSize() - this->getSafeSize();
1447f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            // Need aligned pointer to write into due to internal implementa-
1448f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            // tion of SkWriter32.
1449f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            memset(buffer.reserve(SkAlign4(deltaSize)), 0, deltaSize);
1450f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        }
1451f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    } else {
1452f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        buffer.write8(SERIALIZE_PIXELTYPE_NONE);
1453f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    }
1454f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger}
1455f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
1456f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergervoid SkBitmap::unflatten(SkFlattenableReadBuffer& buffer) {
1457f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    this->reset();
1458f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
1459f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    int width = buffer.readInt();
1460f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    int height = buffer.readInt();
1461f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    int rowBytes = buffer.readInt();
1462f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    int config = buffer.readU8();
1463f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
1464f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    this->setConfig((Config)config, width, height, rowBytes);
1465f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    this->setIsOpaque(buffer.readBool());
1466f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
1467f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    int reftype = buffer.readU8();
1468f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    switch (reftype) {
1469f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        case SERIALIZE_PIXELTYPE_REF_PTR: {
1470f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            size_t offset = buffer.readU32();
1471f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            SkPixelRef* pr = (SkPixelRef*)buffer.readRefCnt();
1472f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            this->setPixelRef(pr, offset);
1473f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            break;
1474f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        }
1475f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        case SERIALIZE_PIXELTYPE_REF_DATA: {
1476f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            size_t offset = buffer.readU32();
1477f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            SkPixelRef::Factory fact = deserialize_factory(buffer);
1478f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            SkPixelRef* pr = fact(buffer);
1479f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            SkSafeUnref(this->setPixelRef(pr, offset));
1480f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            break;
1481f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        }
1482f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        case SERIALIZE_PIXELTYPE_RAW_WITH_CTABLE:
1483f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        case SERIALIZE_PIXELTYPE_RAW_NO_CTABLE: {
1484f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            SkColorTable* ctable = NULL;
1485f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            if (SERIALIZE_PIXELTYPE_RAW_WITH_CTABLE == reftype) {
1486f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                ctable = SkNEW_ARGS(SkColorTable, (buffer));
1487f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            }
1488f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            size_t size = this->getSize();
1489f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            if (this->allocPixels(ctable)) {
1490f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                this->lockPixels();
1491f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                // Just read what we need.
1492f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                buffer.read(this->getPixels(), this->getSafeSize());
1493f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                // Keep aligned for subsequent reads.
1494f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                buffer.skip(size - this->getSafeSize());
1495f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                this->unlockPixels();
1496f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            } else {
1497f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                buffer.skip(size); // Still skip the full-sized buffer though.
1498f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            }
1499f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            SkSafeUnref(ctable);
1500f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            break;
1501f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        }
1502f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        case SERIALIZE_PIXELTYPE_NONE:
1503f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            break;
1504f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        default:
1505f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            SkDEBUGFAIL("unrecognized pixeltype in serialized data");
1506f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            sk_throw();
1507f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    }
1508f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger}
1509f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
1510f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger///////////////////////////////////////////////////////////////////////////////
1511f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
1512f8cacf6b11e35785df8efb613b0c3592d535f603Derek SollenbergerSkBitmap::RLEPixels::RLEPixels(int width, int height) {
1513f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    fHeight = height;
1514f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    fYPtrs = (uint8_t**)sk_malloc_throw(height * sizeof(uint8_t*));
1515f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    sk_bzero(fYPtrs, height * sizeof(uint8_t*));
1516f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger}
1517f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
1518f8cacf6b11e35785df8efb613b0c3592d535f603Derek SollenbergerSkBitmap::RLEPixels::~RLEPixels() {
1519f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    sk_free(fYPtrs);
1520f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger}
1521f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
1522f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger///////////////////////////////////////////////////////////////////////////////
1523f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
1524f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger#ifdef SK_DEBUG
1525f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergervoid SkBitmap::validate() const {
1526f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    SkASSERT(fConfig < kConfigCount);
1527f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    SkASSERT(fRowBytes >= (unsigned)ComputeRowBytes((Config)fConfig, fWidth));
1528f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    SkASSERT(fFlags <= (kImageIsOpaque_Flag | kImageIsVolatile_Flag));
1529f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    SkASSERT(fPixelLockCount >= 0);
1530f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    SkASSERT(NULL == fColorTable || (unsigned)fColorTable->getRefCnt() < 10000);
1531f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    SkASSERT((uint8_t)ComputeBytesPerPixel((Config)fConfig) == fBytesPerPixel);
1532f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
1533f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger#if 0   // these asserts are not thread-correct, so disable for now
1534f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    if (fPixelRef) {
1535f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        if (fPixelLockCount > 0) {
1536f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            SkASSERT(fPixelRef->isLocked());
1537f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        } else {
1538f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            SkASSERT(NULL == fPixels);
1539f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            SkASSERT(NULL == fColorTable);
1540f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        }
1541f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    }
1542f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger#endif
1543f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger}
1544f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger#endif
1545