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