OLD | NEW |
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2008 The Android Open Source Project | 3 * Copyright 2008 The Android Open Source Project |
4 * | 4 * |
5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
7 */ | 7 */ |
8 | 8 |
9 | 9 |
10 #include "SkBitmap.h" | 10 #include "SkBitmap.h" |
(...skipping 343 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
354 SkASSERT(0 == fPixelLockCount); | 354 SkASSERT(0 == fPixelLockCount); |
355 fPixels = NULL; | 355 fPixels = NULL; |
356 if (fColorTable) { | 356 if (fColorTable) { |
357 fColorTable->unref(); | 357 fColorTable->unref(); |
358 fColorTable = NULL; | 358 fColorTable = NULL; |
359 } | 359 } |
360 } | 360 } |
361 } | 361 } |
362 } | 362 } |
363 | 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 = kIndex8_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) { | 364 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 | 365 // do this first, we that we never have a non-zero offset with a null ref |
408 if (NULL == pr) { | 366 if (NULL == pr) { |
409 offset = 0; | 367 offset = 0; |
410 } | 368 } |
411 | 369 |
412 if (fPixelRef != pr || fPixelRefOffset != offset) { | 370 if (fPixelRef != pr || fPixelRefOffset != offset) { |
413 if (fPixelRef != pr) { | 371 if (fPixelRef != pr) { |
414 this->freePixels(); | 372 this->freePixels(); |
415 SkASSERT(NULL == fPixelRef); | 373 SkASSERT(NULL == fPixelRef); |
(...skipping 30 matching lines...) Expand all Loading... |
446 bool SkBitmap::lockPixelsAreWritable() const { | 404 bool SkBitmap::lockPixelsAreWritable() const { |
447 return (fPixelRef) ? fPixelRef->lockPixelsAreWritable() : false; | 405 return (fPixelRef) ? fPixelRef->lockPixelsAreWritable() : false; |
448 } | 406 } |
449 | 407 |
450 void SkBitmap::setPixels(void* p, SkColorTable* ctable) { | 408 void SkBitmap::setPixels(void* p, SkColorTable* ctable) { |
451 if (NULL == p) { | 409 if (NULL == p) { |
452 this->setPixelRef(NULL, 0); | 410 this->setPixelRef(NULL, 0); |
453 return; | 411 return; |
454 } | 412 } |
455 | 413 |
456 SkImageInfo info; | 414 Sk64 size = this->getSize64(); |
457 if (!this->asImageInfo(&info)) { | 415 SkASSERT(!size.isNeg() && size.is32()); |
458 this->setPixelRef(NULL, 0); | |
459 return; | |
460 } | |
461 | 416 |
462 SkPixelRef* pr = SkMallocPixelRef::NewDirect(info, p, fRowBytes, ctable); | 417 this->setPixelRef(new SkMallocPixelRef(p, size.get32(), ctable, false))->unr
ef(); |
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 | 418 // since we're already allocated, we lockPixels right away |
471 this->lockPixels(); | 419 this->lockPixels(); |
472 SkDEBUGCODE(this->validate();) | 420 SkDEBUGCODE(this->validate();) |
473 } | 421 } |
474 | 422 |
475 bool SkBitmap::allocPixels(Allocator* allocator, SkColorTable* ctable) { | 423 bool SkBitmap::allocPixels(Allocator* allocator, SkColorTable* ctable) { |
476 HeapAllocator stdalloc; | 424 HeapAllocator stdalloc; |
477 | 425 |
478 if (NULL == allocator) { | 426 if (NULL == allocator) { |
479 allocator = &stdalloc; | 427 allocator = &stdalloc; |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
524 return fPixelRef ? fPixelRef->getTexture() : NULL; | 472 return fPixelRef ? fPixelRef->getTexture() : NULL; |
525 } | 473 } |
526 | 474 |
527 /////////////////////////////////////////////////////////////////////////////// | 475 /////////////////////////////////////////////////////////////////////////////// |
528 | 476 |
529 /** We explicitly use the same allocator for our pixels that SkMask does, | 477 /** 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. | 478 so that we can freely assign memory allocated by one class to the other. |
531 */ | 479 */ |
532 bool SkBitmap::HeapAllocator::allocPixelRef(SkBitmap* dst, | 480 bool SkBitmap::HeapAllocator::allocPixelRef(SkBitmap* dst, |
533 SkColorTable* ctable) { | 481 SkColorTable* ctable) { |
534 SkImageInfo info; | 482 Sk64 size = dst->getSize64(); |
535 if (!dst->asImageInfo(&info)) { | 483 if (size.isNeg() || !size.is32()) { |
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; | 484 return false; |
544 } | 485 } |
545 | 486 |
546 dst->setPixelRef(pr, 0)->unref(); | 487 void* addr = sk_malloc_flags(size.get32(), 0); // returns NULL on failure |
| 488 if (NULL == addr) { |
| 489 return false; |
| 490 } |
| 491 |
| 492 dst->setPixelRef(new SkMallocPixelRef(addr, size.get32(), ctable))->unref(); |
547 // since we're already allocated, we lockPixels right away | 493 // since we're already allocated, we lockPixels right away |
548 dst->lockPixels(); | 494 dst->lockPixels(); |
549 return true; | 495 return true; |
550 } | 496 } |
551 | 497 |
552 /////////////////////////////////////////////////////////////////////////////// | 498 /////////////////////////////////////////////////////////////////////////////// |
553 | 499 |
554 size_t SkBitmap::getSafeSize() const { | 500 size_t SkBitmap::getSafeSize() const { |
555 // This is intended to be a size_t version of ComputeSafeSize64(), just | 501 // This is intended to be a size_t version of ComputeSafeSize64(), just |
556 // faster. The computation is meant to be identical. | 502 // faster. The computation is meant to be identical. |
(...skipping 1089 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1646 fHeight = height; | 1592 fHeight = height; |
1647 fYPtrs = (uint8_t**)sk_calloc_throw(height * sizeof(uint8_t*)); | 1593 fYPtrs = (uint8_t**)sk_calloc_throw(height * sizeof(uint8_t*)); |
1648 } | 1594 } |
1649 | 1595 |
1650 SkBitmap::RLEPixels::~RLEPixels() { | 1596 SkBitmap::RLEPixels::~RLEPixels() { |
1651 sk_free(fYPtrs); | 1597 sk_free(fYPtrs); |
1652 } | 1598 } |
1653 | 1599 |
1654 /////////////////////////////////////////////////////////////////////////////// | 1600 /////////////////////////////////////////////////////////////////////////////// |
1655 | 1601 |
1656 void SkImageInfo::unflatten(SkFlattenableReadBuffer& buffer) { | |
1657 fWidth = buffer.read32(); | |
1658 fHeight = buffer.read32(); | |
1659 | |
1660 uint32_t packed = buffer.read32(); | |
1661 SkASSERT(0 == (packed >> 16)); | |
1662 fAlphaType = (SkAlphaType)((packed >> 8) & 0xFF); | |
1663 fColorType = (SkColorType)((packed >> 0) & 0xFF); | |
1664 } | |
1665 | |
1666 void SkImageInfo::flatten(SkFlattenableWriteBuffer& buffer) const { | |
1667 buffer.write32(fWidth); | |
1668 buffer.write32(fHeight); | |
1669 | |
1670 SkASSERT(0 == (fAlphaType & ~0xFF)); | |
1671 SkASSERT(0 == (fColorType & ~0xFF)); | |
1672 uint32_t packed = (fAlphaType << 8) | fColorType; | |
1673 buffer.write32(packed); | |
1674 } | |
1675 | |
1676 /////////////////////////////////////////////////////////////////////////////// | |
1677 | |
1678 #ifdef SK_DEBUG | 1602 #ifdef SK_DEBUG |
1679 void SkBitmap::validate() const { | 1603 void SkBitmap::validate() const { |
1680 SkASSERT(fConfig < kConfigCount); | 1604 SkASSERT(fConfig < kConfigCount); |
1681 SkASSERT(fRowBytes >= (unsigned)ComputeRowBytes((Config)fConfig, fWidth)); | 1605 SkASSERT(fRowBytes >= (unsigned)ComputeRowBytes((Config)fConfig, fWidth)); |
1682 uint8_t allFlags = kImageIsOpaque_Flag | kImageIsVolatile_Flag | kImageIsImm
utable_Flag; | 1606 uint8_t allFlags = kImageIsOpaque_Flag | kImageIsVolatile_Flag | kImageIsImm
utable_Flag; |
1683 #ifdef SK_BUILD_FOR_ANDROID | 1607 #ifdef SK_BUILD_FOR_ANDROID |
1684 allFlags |= kHasHardwareMipMap_Flag; | 1608 allFlags |= kHasHardwareMipMap_Flag; |
1685 #endif | 1609 #endif |
1686 SkASSERT(fFlags <= allFlags); | 1610 SkASSERT(fFlags <= allFlags); |
1687 SkASSERT(fPixelLockCount >= 0); | 1611 SkASSERT(fPixelLockCount >= 0); |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1733 if (NULL != uri) { | 1657 if (NULL != uri) { |
1734 str->appendf(" uri:\"%s\"", uri); | 1658 str->appendf(" uri:\"%s\"", uri); |
1735 } else { | 1659 } else { |
1736 str->appendf(" pixelref:%p", pr); | 1660 str->appendf(" pixelref:%p", pr); |
1737 } | 1661 } |
1738 } | 1662 } |
1739 | 1663 |
1740 str->append(")"); | 1664 str->append(")"); |
1741 } | 1665 } |
1742 #endif | 1666 #endif |
OLD | NEW |