Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(306)

Side by Side Diff: src/core/SkBitmap.cpp

Issue 25275004: store SkAlphaType inside SkBitmap, on road to support unpremul (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: Created 7 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698