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