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 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
259 SkIntToScalar(fWidth), SkIntToScalar(fHeight)); | 259 SkIntToScalar(fWidth), SkIntToScalar(fHeight)); |
260 } | 260 } |
261 | 261 |
262 void SkBitmap::getBounds(SkIRect* bounds) const { | 262 void SkBitmap::getBounds(SkIRect* bounds) const { |
263 SkASSERT(bounds); | 263 SkASSERT(bounds); |
264 bounds->set(0, 0, fWidth, fHeight); | 264 bounds->set(0, 0, fWidth, fHeight); |
265 } | 265 } |
266 | 266 |
267 /////////////////////////////////////////////////////////////////////////////// | 267 /////////////////////////////////////////////////////////////////////////////// |
268 | 268 |
269 void SkBitmap::setConfig(Config c, int width, int height, size_t rowBytes) { | 269 bool SkBitmap::setConfig(Config config, int width, int height, size_t rowBytes, |
270 this->freePixels(); | 270 SkAlphaType alphaType) { |
271 | |
272 if ((width | height) < 0) { | 271 if ((width | height) < 0) { |
273 goto err; | 272 goto ERROR; |
274 } | 273 } |
275 | |
276 if (rowBytes == 0) { | 274 if (rowBytes == 0) { |
277 rowBytes = SkBitmap::ComputeRowBytes(c, width); | 275 rowBytes = SkBitmap::ComputeRowBytes(config, width); |
278 if (0 == rowBytes && kNo_Config != c) { | 276 if (0 == rowBytes && kNo_Config != config) { |
279 goto err; | 277 goto ERROR; |
280 } | 278 } |
281 } | 279 } |
282 | 280 |
283 fConfig = SkToU8(c); | 281 // check for legal/supported config+alphaType combinations |
282 // | |
283 switch (config) { | |
scroggo
2013/10/18 19:32:40
Should this call setAlphaType so we don't have cod
| |
284 case kNo_Config: | |
285 alphaType = kIgnore_SkAlphaType; // canonicalize | |
286 break; | |
287 case kA1_Config: | |
288 case kA8_Config: | |
289 if (kUnpremul_SkAlphaType == alphaType) { | |
290 alphaType = kPremul_SkAlphaType; | |
291 } | |
292 // fall-through | |
293 case kIndex8_Config: | |
294 case kARGB_4444_Config: | |
295 case kARGB_8888_Config: | |
296 if (kIgnore_SkAlphaType == alphaType) { | |
297 goto ERROR; // not supported yet | |
298 } | |
299 break; | |
300 case kRGB_565_Config: | |
301 alphaType = kOpaque_SkAlphaType; // canonicalize | |
302 break; | |
303 } | |
304 | |
305 this->freePixels(); | |
306 | |
307 fConfig = SkToU8(config); | |
308 fAlphaType = SkToU8(alphaType); | |
284 fWidth = width; | 309 fWidth = width; |
285 fHeight = height; | 310 fHeight = height; |
286 fRowBytes = SkToU32(rowBytes); | 311 fRowBytes = SkToU32(rowBytes); |
287 | 312 |
288 fBytesPerPixel = (uint8_t)ComputeBytesPerPixel(c); | 313 fBytesPerPixel = (uint8_t)ComputeBytesPerPixel(config); |
289 | 314 |
290 SkDEBUGCODE(this->validate();) | 315 SkDEBUGCODE(this->validate();) |
291 return; | 316 return true; |
292 | 317 |
293 // if we got here, we had an error, so we reset the bitmap to empty | 318 // if we got here, we had an error, so we reset the bitmap to empty |
294 err: | 319 ERROR: |
295 this->reset(); | 320 this->reset(); |
321 return false; | |
322 } | |
323 | |
324 void SkBitmap::setAlphaType(SkAlphaType alphaType) { | |
325 // check for legal/supported config+alphaType combinations | |
326 // | |
327 switch (this->config()) { | |
328 case kNo_Config: | |
329 alphaType = kIgnore_SkAlphaType; // canonicalize | |
330 break; | |
331 case kA1_Config: | |
332 case kA8_Config: | |
333 if (kUnpremul_SkAlphaType == alphaType) { | |
334 alphaType = kPremul_SkAlphaType; | |
335 } | |
336 // fall-through | |
337 case kIndex8_Config: | |
338 case kARGB_4444_Config: | |
339 case kARGB_8888_Config: | |
340 if (kIgnore_SkAlphaType == alphaType) { | |
341 SkDEBUGFAIL("bad alphaType for existing config"); | |
342 return; | |
343 } | |
344 break; | |
345 case kRGB_565_Config: | |
346 alphaType = kOpaque_SkAlphaType; // canonicalize | |
347 break; | |
348 } | |
349 | |
350 fAlphaType = SkToU8(alphaType); | |
296 } | 351 } |
297 | 352 |
298 void SkBitmap::updatePixelsFromRef() const { | 353 void SkBitmap::updatePixelsFromRef() const { |
299 if (NULL != fPixelRef) { | 354 if (NULL != fPixelRef) { |
300 if (fPixelLockCount > 0) { | 355 if (fPixelLockCount > 0) { |
301 SkASSERT(fPixelRef->isLocked()); | 356 SkASSERT(fPixelRef->isLocked()); |
302 | 357 |
303 void* p = fPixelRef->pixels(); | 358 void* p = fPixelRef->pixels(); |
304 if (NULL != p) { | 359 if (NULL != p) { |
305 p = (char*)p + fPixelRefOffset; | 360 p = (char*)p + fPixelRefOffset; |
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
518 | 573 |
519 void SkBitmap::setImmutable() { | 574 void SkBitmap::setImmutable() { |
520 if (fPixelRef) { | 575 if (fPixelRef) { |
521 fPixelRef->setImmutable(); | 576 fPixelRef->setImmutable(); |
522 } else { | 577 } else { |
523 fFlags |= kImageIsImmutable_Flag; | 578 fFlags |= kImageIsImmutable_Flag; |
524 } | 579 } |
525 } | 580 } |
526 | 581 |
527 bool SkBitmap::isOpaque() const { | 582 bool SkBitmap::isOpaque() const { |
583 return kOpaque_SkAlphaType == fAlphaType || | |
584 kIgnore_SkAlphaType == fAlphaType; | |
585 #if 0 | |
scroggo
2013/10/18 19:32:40
Any reason not to delete this code?
| |
528 switch (fConfig) { | 586 switch (fConfig) { |
529 case kNo_Config: | 587 case kNo_Config: |
530 return true; | 588 return true; |
531 | 589 |
532 case kA1_Config: | 590 case kA1_Config: |
533 case kA8_Config: | 591 case kA8_Config: |
534 case kARGB_4444_Config: | 592 case kARGB_4444_Config: |
535 case kARGB_8888_Config: | 593 case kARGB_8888_Config: |
536 return (fFlags & kImageIsOpaque_Flag) != 0; | 594 return (fFlags & kImageIsOpaque_Flag) != 0; |
537 | 595 |
538 case kIndex8_Config: { | 596 case kIndex8_Config: { |
539 bool isOpaque; | 597 bool isOpaque; |
540 | 598 |
541 this->lockPixels(); | 599 this->lockPixels(); |
542 isOpaque = fColorTable && fColorTable->isOpaque(); | 600 isOpaque = fColorTable && fColorTable->isOpaque(); |
543 this->unlockPixels(); | 601 this->unlockPixels(); |
544 return isOpaque; | 602 return isOpaque; |
545 } | 603 } |
546 | 604 |
547 case kRGB_565_Config: | 605 case kRGB_565_Config: |
548 return true; | 606 return true; |
549 | 607 |
550 default: | 608 default: |
551 SkDEBUGFAIL("unknown bitmap config pased to isOpaque"); | 609 SkDEBUGFAIL("unknown bitmap config pased to isOpaque"); |
552 return false; | 610 return false; |
553 } | 611 } |
612 #endif | |
554 } | 613 } |
555 | 614 |
615 #if 0 | |
scroggo
2013/10/18 19:32:40
Any reason not to delete this code?
| |
556 void SkBitmap::setIsOpaque(bool isOpaque) { | 616 void SkBitmap::setIsOpaque(bool isOpaque) { |
557 /* we record this regardless of fConfig, though it is ignored in | 617 /* we record this regardless of fConfig, though it is ignored in |
558 isOpaque() for configs that can't support per-pixel alpha. | 618 isOpaque() for configs that can't support per-pixel alpha. |
559 */ | 619 */ |
560 if (isOpaque) { | 620 if (isOpaque) { |
561 fFlags |= kImageIsOpaque_Flag; | 621 fFlags |= kImageIsOpaque_Flag; |
562 } else { | 622 } else { |
563 fFlags &= ~kImageIsOpaque_Flag; | 623 fFlags &= ~kImageIsOpaque_Flag; |
564 } | 624 } |
565 } | 625 } |
626 #endif | |
566 | 627 |
567 bool SkBitmap::isVolatile() const { | 628 bool SkBitmap::isVolatile() const { |
568 return (fFlags & kImageIsVolatile_Flag) != 0; | 629 return (fFlags & kImageIsVolatile_Flag) != 0; |
569 } | 630 } |
570 | 631 |
571 void SkBitmap::setIsVolatile(bool isVolatile) { | 632 void SkBitmap::setIsVolatile(bool isVolatile) { |
572 if (isVolatile) { | 633 if (isVolatile) { |
573 fFlags |= kImageIsVolatile_Flag; | 634 fFlags |= kImageIsVolatile_Flag; |
574 } else { | 635 } else { |
575 fFlags &= ~kImageIsVolatile_Flag; | 636 fFlags &= ~kImageIsVolatile_Flag; |
(...skipping 375 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
951 srcRect.set(0, 0, this->width(), this->height()); | 1012 srcRect.set(0, 0, this->width(), this->height()); |
952 if (!r.intersect(srcRect, subset)) { | 1013 if (!r.intersect(srcRect, subset)) { |
953 return false; // r is empty (i.e. no intersection) | 1014 return false; // r is empty (i.e. no intersection) |
954 } | 1015 } |
955 | 1016 |
956 if (fPixelRef->getTexture() != NULL) { | 1017 if (fPixelRef->getTexture() != NULL) { |
957 // Do a deep copy | 1018 // Do a deep copy |
958 SkPixelRef* pixelRef = fPixelRef->deepCopy(this->config(), &subset); | 1019 SkPixelRef* pixelRef = fPixelRef->deepCopy(this->config(), &subset); |
959 if (pixelRef != NULL) { | 1020 if (pixelRef != NULL) { |
960 SkBitmap dst; | 1021 SkBitmap dst; |
961 dst.setConfig(this->config(), subset.width(), subset.height()); | 1022 dst.setConfig(this->config(), subset.width(), subset.height(), 0, |
1023 this->isOpaque() ? | |
scroggo
2013/10/18 19:32:40
Why not use fAlphaType?
| |
1024 kOpaque_SkAlphaType : kPremul_SkAlphaType); | |
962 dst.setIsVolatile(this->isVolatile()); | 1025 dst.setIsVolatile(this->isVolatile()); |
963 dst.setIsOpaque(this->isOpaque()); | |
964 dst.setPixelRef(pixelRef)->unref(); | 1026 dst.setPixelRef(pixelRef)->unref(); |
965 SkDEBUGCODE(dst.validate()); | 1027 SkDEBUGCODE(dst.validate()); |
966 result->swap(dst); | 1028 result->swap(dst); |
967 return true; | 1029 return true; |
968 } | 1030 } |
969 } | 1031 } |
970 | 1032 |
971 // If the upper left of the rectangle was outside the bounds of this SkBitma p, we should have | 1033 // If the upper left of the rectangle was outside the bounds of this SkBitma p, we should have |
972 // exited above. | 1034 // exited above. |
973 SkASSERT(static_cast<unsigned>(r.fLeft) < static_cast<unsigned>(this->width( ))); | 1035 SkASSERT(static_cast<unsigned>(r.fLeft) < static_cast<unsigned>(this->width( ))); |
974 SkASSERT(static_cast<unsigned>(r.fTop) < static_cast<unsigned>(this->height( ))); | 1036 SkASSERT(static_cast<unsigned>(r.fTop) < static_cast<unsigned>(this->height( ))); |
975 | 1037 |
976 size_t offset = get_sub_offset(*this, r.fLeft, r.fTop); | 1038 size_t offset = get_sub_offset(*this, r.fLeft, r.fTop); |
977 if (SUB_OFFSET_FAILURE == offset) { | 1039 if (SUB_OFFSET_FAILURE == offset) { |
978 return false; // config not supported | 1040 return false; // config not supported |
979 } | 1041 } |
980 | 1042 |
981 SkBitmap dst; | 1043 SkBitmap dst; |
982 dst.setConfig(this->config(), r.width(), r.height(), this->rowBytes()); | 1044 dst.setConfig(this->config(), r.width(), r.height(), this->rowBytes(), |
1045 this->isOpaque() ? kOpaque_SkAlphaType : kPremul_SkAlphaType); | |
scroggo
2013/10/18 19:32:40
fAlphaType?
| |
983 dst.setIsVolatile(this->isVolatile()); | 1046 dst.setIsVolatile(this->isVolatile()); |
984 dst.setIsOpaque(this->isOpaque()); | |
985 | 1047 |
986 if (fPixelRef) { | 1048 if (fPixelRef) { |
987 // share the pixelref with a custom offset | 1049 // share the pixelref with a custom offset |
988 dst.setPixelRef(fPixelRef, fPixelRefOffset + offset); | 1050 dst.setPixelRef(fPixelRef, fPixelRefOffset + offset); |
989 } | 1051 } |
990 SkDEBUGCODE(dst.validate();) | 1052 SkDEBUGCODE(dst.validate();) |
991 | 1053 |
992 // we know we're good, so commit to result | 1054 // we know we're good, so commit to result |
993 result->swap(dst); | 1055 result->swap(dst); |
994 return true; | 1056 return true; |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1123 // TODO: switch the allocation of tmpDst to call sk_calloc_throw | 1185 // TODO: switch the allocation of tmpDst to call sk_calloc_throw |
1124 tmpDst.eraseColor(SK_ColorTRANSPARENT); | 1186 tmpDst.eraseColor(SK_ColorTRANSPARENT); |
1125 | 1187 |
1126 SkCanvas canvas(tmpDst); | 1188 SkCanvas canvas(tmpDst); |
1127 SkPaint paint; | 1189 SkPaint paint; |
1128 | 1190 |
1129 paint.setDither(true); | 1191 paint.setDither(true); |
1130 canvas.drawBitmap(*src, 0, 0, &paint); | 1192 canvas.drawBitmap(*src, 0, 0, &paint); |
1131 } | 1193 } |
1132 | 1194 |
1133 tmpDst.setIsOpaque(src->isOpaque()); | 1195 tmpDst.setAlphaType(src->isOpaque() ? |
scroggo
2013/10/18 19:32:40
It seems odd here to set the alpha type after we'v
| |
1196 kOpaque_SkAlphaType : kPremul_SkAlphaType); | |
1134 | 1197 |
1135 dst->swap(tmpDst); | 1198 dst->swap(tmpDst); |
1136 return true; | 1199 return true; |
1137 } | 1200 } |
1138 | 1201 |
1139 bool SkBitmap::deepCopyTo(SkBitmap* dst, Config dstConfig) const { | 1202 bool SkBitmap::deepCopyTo(SkBitmap* dst, Config dstConfig) const { |
1140 if (!this->canCopyTo(dstConfig)) { | 1203 if (!this->canCopyTo(dstConfig)) { |
1141 return false; | 1204 return false; |
1142 } | 1205 } |
1143 | 1206 |
(...skipping 452 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1596 } | 1659 } |
1597 | 1660 |
1598 void SkBitmap::unflatten(SkFlattenableReadBuffer& buffer) { | 1661 void SkBitmap::unflatten(SkFlattenableReadBuffer& buffer) { |
1599 this->reset(); | 1662 this->reset(); |
1600 | 1663 |
1601 int width = buffer.readInt(); | 1664 int width = buffer.readInt(); |
1602 int height = buffer.readInt(); | 1665 int height = buffer.readInt(); |
1603 int rowBytes = buffer.readInt(); | 1666 int rowBytes = buffer.readInt(); |
1604 int config = buffer.readInt(); | 1667 int config = buffer.readInt(); |
1605 | 1668 |
1606 this->setConfig((Config)config, width, height, rowBytes); | 1669 bool isOpaque = buffer.readBool(); |
scroggo
2013/10/18 19:32:40
Why not update flatten to write the alpha type and
| |
1607 this->setIsOpaque(buffer.readBool()); | 1670 this->setConfig((Config)config, width, height, rowBytes, |
1671 isOpaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType); | |
1608 | 1672 |
1609 int reftype = buffer.readInt(); | 1673 int reftype = buffer.readInt(); |
1610 switch (reftype) { | 1674 switch (reftype) { |
1611 case SERIALIZE_PIXELTYPE_REF_DATA: { | 1675 case SERIALIZE_PIXELTYPE_REF_DATA: { |
1612 size_t offset = buffer.readUInt(); | 1676 size_t offset = buffer.readUInt(); |
1613 SkPixelRef* pr = buffer.readPixelRef(); | 1677 SkPixelRef* pr = buffer.readPixelRef(); |
1614 SkSafeUnref(this->setPixelRef(pr, offset)); | 1678 SkSafeUnref(this->setPixelRef(pr, offset)); |
1615 break; | 1679 break; |
1616 } | 1680 } |
1617 case SERIALIZE_PIXELTYPE_NONE: | 1681 case SERIALIZE_PIXELTYPE_NONE: |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1693 if (NULL != uri) { | 1757 if (NULL != uri) { |
1694 str->appendf(" uri:\"%s\"", uri); | 1758 str->appendf(" uri:\"%s\"", uri); |
1695 } else { | 1759 } else { |
1696 str->appendf(" pixelref:%p", pr); | 1760 str->appendf(" pixelref:%p", pr); |
1697 } | 1761 } |
1698 } | 1762 } |
1699 | 1763 |
1700 str->append(")"); | 1764 str->append(")"); |
1701 } | 1765 } |
1702 #endif | 1766 #endif |
OLD | NEW |