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