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

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) {
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
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
(...skipping 10 matching lines...) Expand all
548 return (flags & SkColorTable::kColorsAreOpaque_Flag) != 0; 606 return (flags & SkColorTable::kColorsAreOpaque_Flag) != 0;
549 } 607 }
550 608
551 case kRGB_565_Config: 609 case kRGB_565_Config:
552 return true; 610 return true;
553 611
554 default: 612 default:
555 SkDEBUGFAIL("unknown bitmap config pased to isOpaque"); 613 SkDEBUGFAIL("unknown bitmap config pased to isOpaque");
556 return false; 614 return false;
557 } 615 }
616 #endif
558 } 617 }
559 618
619 #if 0
560 void SkBitmap::setIsOpaque(bool isOpaque) { 620 void SkBitmap::setIsOpaque(bool isOpaque) {
561 /* we record this regardless of fConfig, though it is ignored in 621 /* we record this regardless of fConfig, though it is ignored in
562 isOpaque() for configs that can't support per-pixel alpha. 622 isOpaque() for configs that can't support per-pixel alpha.
563 */ 623 */
564 if (isOpaque) { 624 if (isOpaque) {
565 fFlags |= kImageIsOpaque_Flag; 625 fFlags |= kImageIsOpaque_Flag;
566 } else { 626 } else {
567 fFlags &= ~kImageIsOpaque_Flag; 627 fFlags &= ~kImageIsOpaque_Flag;
568 } 628 }
569 } 629 }
630 #endif
570 631
571 bool SkBitmap::isVolatile() const { 632 bool SkBitmap::isVolatile() const {
572 return (fFlags & kImageIsVolatile_Flag) != 0; 633 return (fFlags & kImageIsVolatile_Flag) != 0;
573 } 634 }
574 635
575 void SkBitmap::setIsVolatile(bool isVolatile) { 636 void SkBitmap::setIsVolatile(bool isVolatile) {
576 if (isVolatile) { 637 if (isVolatile) {
577 fFlags |= kImageIsVolatile_Flag; 638 fFlags |= kImageIsVolatile_Flag;
578 } else { 639 } else {
579 fFlags &= ~kImageIsVolatile_Flag; 640 fFlags &= ~kImageIsVolatile_Flag;
(...skipping 375 matching lines...) Expand 10 before | Expand all | Expand 10 after
955 srcRect.set(0, 0, this->width(), this->height()); 1016 srcRect.set(0, 0, this->width(), this->height());
956 if (!r.intersect(srcRect, subset)) { 1017 if (!r.intersect(srcRect, subset)) {
957 return false; // r is empty (i.e. no intersection) 1018 return false; // r is empty (i.e. no intersection)
958 } 1019 }
959 1020
960 if (fPixelRef->getTexture() != NULL) { 1021 if (fPixelRef->getTexture() != NULL) {
961 // Do a deep copy 1022 // Do a deep copy
962 SkPixelRef* pixelRef = fPixelRef->deepCopy(this->config(), &subset); 1023 SkPixelRef* pixelRef = fPixelRef->deepCopy(this->config(), &subset);
963 if (pixelRef != NULL) { 1024 if (pixelRef != NULL) {
964 SkBitmap dst; 1025 SkBitmap dst;
965 dst.setConfig(this->config(), subset.width(), subset.height()); 1026 dst.setConfig(this->config(), subset.width(), subset.height(), 0,
1027 this->isOpaque() ?
1028 kOpaque_SkAlphaType : kPremul_SkAlphaType);
966 dst.setIsVolatile(this->isVolatile()); 1029 dst.setIsVolatile(this->isVolatile());
967 dst.setIsOpaque(this->isOpaque());
968 dst.setPixelRef(pixelRef)->unref(); 1030 dst.setPixelRef(pixelRef)->unref();
969 SkDEBUGCODE(dst.validate()); 1031 SkDEBUGCODE(dst.validate());
970 result->swap(dst); 1032 result->swap(dst);
971 return true; 1033 return true;
972 } 1034 }
973 } 1035 }
974 1036
975 // If the upper left of the rectangle was outside the bounds of this SkBitma p, we should have 1037 // If the upper left of the rectangle was outside the bounds of this SkBitma p, we should have
976 // exited above. 1038 // exited above.
977 SkASSERT(static_cast<unsigned>(r.fLeft) < static_cast<unsigned>(this->width( ))); 1039 SkASSERT(static_cast<unsigned>(r.fLeft) < static_cast<unsigned>(this->width( )));
978 SkASSERT(static_cast<unsigned>(r.fTop) < static_cast<unsigned>(this->height( ))); 1040 SkASSERT(static_cast<unsigned>(r.fTop) < static_cast<unsigned>(this->height( )));
979 1041
980 size_t offset = get_sub_offset(*this, r.fLeft, r.fTop); 1042 size_t offset = get_sub_offset(*this, r.fLeft, r.fTop);
981 if (SUB_OFFSET_FAILURE == offset) { 1043 if (SUB_OFFSET_FAILURE == offset) {
982 return false; // config not supported 1044 return false; // config not supported
983 } 1045 }
984 1046
985 SkBitmap dst; 1047 SkBitmap dst;
986 dst.setConfig(this->config(), r.width(), r.height(), this->rowBytes()); 1048 dst.setConfig(this->config(), r.width(), r.height(), this->rowBytes(),
1049 this->isOpaque() ? kOpaque_SkAlphaType : kPremul_SkAlphaType);
987 dst.setIsVolatile(this->isVolatile()); 1050 dst.setIsVolatile(this->isVolatile());
988 dst.setIsOpaque(this->isOpaque());
989 1051
990 if (fPixelRef) { 1052 if (fPixelRef) {
991 // share the pixelref with a custom offset 1053 // share the pixelref with a custom offset
992 dst.setPixelRef(fPixelRef, fPixelRefOffset + offset); 1054 dst.setPixelRef(fPixelRef, fPixelRefOffset + offset);
993 } 1055 }
994 SkDEBUGCODE(dst.validate();) 1056 SkDEBUGCODE(dst.validate();)
995 1057
996 // we know we're good, so commit to result 1058 // we know we're good, so commit to result
997 result->swap(dst); 1059 result->swap(dst);
998 return true; 1060 return true;
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
1128 tmpDst.eraseColor(SK_ColorTRANSPARENT); 1190 tmpDst.eraseColor(SK_ColorTRANSPARENT);
1129 } 1191 }
1130 1192
1131 SkCanvas canvas(tmpDst); 1193 SkCanvas canvas(tmpDst);
1132 SkPaint paint; 1194 SkPaint paint;
1133 1195
1134 paint.setDither(true); 1196 paint.setDither(true);
1135 canvas.drawBitmap(*src, 0, 0, &paint); 1197 canvas.drawBitmap(*src, 0, 0, &paint);
1136 } 1198 }
1137 1199
1138 tmpDst.setIsOpaque(src->isOpaque()); 1200 tmpDst.setAlphaType(src->isOpaque() ?
1201 kOpaque_SkAlphaType : kPremul_SkAlphaType);
1139 1202
1140 dst->swap(tmpDst); 1203 dst->swap(tmpDst);
1141 return true; 1204 return true;
1142 } 1205 }
1143 1206
1144 bool SkBitmap::deepCopyTo(SkBitmap* dst, Config dstConfig) const { 1207 bool SkBitmap::deepCopyTo(SkBitmap* dst, Config dstConfig) const {
1145 if (!this->canCopyTo(dstConfig)) { 1208 if (!this->canCopyTo(dstConfig)) {
1146 return false; 1209 return false;
1147 } 1210 }
1148 1211
(...skipping 452 matching lines...) Expand 10 before | Expand all | Expand 10 after
1601 } 1664 }
1602 1665
1603 void SkBitmap::unflatten(SkFlattenableReadBuffer& buffer) { 1666 void SkBitmap::unflatten(SkFlattenableReadBuffer& buffer) {
1604 this->reset(); 1667 this->reset();
1605 1668
1606 int width = buffer.readInt(); 1669 int width = buffer.readInt();
1607 int height = buffer.readInt(); 1670 int height = buffer.readInt();
1608 int rowBytes = buffer.readInt(); 1671 int rowBytes = buffer.readInt();
1609 int config = buffer.readInt(); 1672 int config = buffer.readInt();
1610 1673
1611 this->setConfig((Config)config, width, height, rowBytes); 1674 bool isOpaque = buffer.readBool();
1612 this->setIsOpaque(buffer.readBool()); 1675 this->setConfig((Config)config, width, height, rowBytes,
1676 isOpaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType);
1613 1677
1614 int reftype = buffer.readInt(); 1678 int reftype = buffer.readInt();
1615 switch (reftype) { 1679 switch (reftype) {
1616 case SERIALIZE_PIXELTYPE_REF_DATA: { 1680 case SERIALIZE_PIXELTYPE_REF_DATA: {
1617 size_t offset = buffer.readUInt(); 1681 size_t offset = buffer.readUInt();
1618 SkPixelRef* pr = buffer.readFlattenableT<SkPixelRef>(); 1682 SkPixelRef* pr = buffer.readFlattenableT<SkPixelRef>();
1619 SkSafeUnref(this->setPixelRef(pr, offset)); 1683 SkSafeUnref(this->setPixelRef(pr, offset));
1620 break; 1684 break;
1621 } 1685 }
1622 case SERIALIZE_PIXELTYPE_NONE: 1686 case SERIALIZE_PIXELTYPE_NONE:
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
1699 if (NULL != uri) { 1763 if (NULL != uri) {
1700 str->appendf(" uri:\"%s\"", uri); 1764 str->appendf(" uri:\"%s\"", uri);
1701 } else { 1765 } else {
1702 str->appendf(" pixelref:%p", pr); 1766 str->appendf(" pixelref:%p", pr);
1703 } 1767 }
1704 } 1768 }
1705 1769
1706 str->append(")"); 1770 str->append(")");
1707 } 1771 }
1708 #endif 1772 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698