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