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

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

Issue 317053003: Fixes for SkAlphaTypes. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Rename info parameter to requestedInfo. Created 6 years, 6 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 395 matching lines...) Expand 10 before | Expand all | Expand 10 after
406 HeapAllocator stdalloc; 406 HeapAllocator stdalloc;
407 407
408 if (NULL == allocator) { 408 if (NULL == allocator) {
409 allocator = &stdalloc; 409 allocator = &stdalloc;
410 } 410 }
411 return allocator->allocPixelRef(this, ctable); 411 return allocator->allocPixelRef(this, ctable);
412 } 412 }
413 413
414 /////////////////////////////////////////////////////////////////////////////// 414 ///////////////////////////////////////////////////////////////////////////////
415 415
416 bool SkBitmap::allocPixels(const SkImageInfo& info, SkPixelRefFactory* factory, 416 bool SkBitmap::allocPixels(const SkImageInfo& requestedInfo, SkPixelRefFactory* factory,
417 SkColorTable* ctable) { 417 SkColorTable* ctable) {
418 if (kIndex_8_SkColorType == info.fColorType && NULL == ctable) { 418 if (kIndex_8_SkColorType == requestedInfo.fColorType && NULL == ctable) {
419 return reset_return_false(this); 419 return reset_return_false(this);
420 } 420 }
421 if (!this->setInfo(info)) { 421 if (!this->setInfo(requestedInfo)) {
422 return reset_return_false(this); 422 return reset_return_false(this);
423 } 423 }
424 424
425 // setInfo may have corrected info (e.g. 565 is always opaque).
426 const SkImageInfo& correctedInfo = this->info();
427
425 SkMallocPixelRef::PRFactory defaultFactory; 428 SkMallocPixelRef::PRFactory defaultFactory;
426 if (NULL == factory) { 429 if (NULL == factory) {
427 factory = &defaultFactory; 430 factory = &defaultFactory;
428 } 431 }
429 432
430 SkPixelRef* pr = factory->create(info, ctable); 433 SkPixelRef* pr = factory->create(correctedInfo, ctable);
431 if (NULL == pr) { 434 if (NULL == pr) {
432 return reset_return_false(this); 435 return reset_return_false(this);
433 } 436 }
434 this->setPixelRef(pr)->unref(); 437 this->setPixelRef(pr)->unref();
435 438
436 // TODO: lockPixels could/should return bool or void*/NULL 439 // TODO: lockPixels could/should return bool or void*/NULL
437 this->lockPixels(); 440 this->lockPixels();
438 if (NULL == this->getPixels()) { 441 if (NULL == this->getPixels()) {
439 return reset_return_false(this); 442 return reset_return_false(this);
440 } 443 }
441 return true; 444 return true;
442 } 445 }
443 446
444 bool SkBitmap::installPixels(const SkImageInfo& info, void* pixels, size_t rb, S kColorTable* ct, 447 bool SkBitmap::installPixels(const SkImageInfo& requestedInfo, void* pixels, siz e_t rb,
445 void (*releaseProc)(void* addr, void* context), voi d* context) { 448 SkColorTable* ct, void (*releaseProc)(void* addr, v oid* context),
446 if (!this->setInfo(info, rb)) { 449 void* context) {
450 if (!this->setInfo(requestedInfo, rb)) {
447 this->reset(); 451 this->reset();
448 return false; 452 return false;
449 } 453 }
450 454
451 SkPixelRef* pr = SkMallocPixelRef::NewWithProc(info, rb, ct, pixels, release Proc, context); 455 // setInfo may have corrected info (e.g. 565 is always opaque).
456 const SkImageInfo& correctedInfo = this->info();
457
458 SkPixelRef* pr = SkMallocPixelRef::NewWithProc(correctedInfo, rb, ct, pixels , releaseProc,
459 context);
452 if (!pr) { 460 if (!pr) {
453 this->reset(); 461 this->reset();
454 return false; 462 return false;
455 } 463 }
456 464
457 this->setPixelRef(pr)->unref(); 465 this->setPixelRef(pr)->unref();
458 466
459 // since we're already allocated, we lockPixels right away 467 // since we're already allocated, we lockPixels right away
460 this->lockPixels(); 468 this->lockPixels();
461 SkDEBUGCODE(this->validate();) 469 SkDEBUGCODE(this->validate();)
(...skipping 493 matching lines...) Expand 10 before | Expand all | Expand 10 after
955 963
956 // if we have a texture, first get those pixels 964 // if we have a texture, first get those pixels
957 SkBitmap tmpSrc; 965 SkBitmap tmpSrc;
958 const SkBitmap* src = this; 966 const SkBitmap* src = this;
959 967
960 if (fPixelRef) { 968 if (fPixelRef) {
961 SkIRect subset; 969 SkIRect subset;
962 subset.setXYWH(fPixelRefOrigin.fX, fPixelRefOrigin.fY, 970 subset.setXYWH(fPixelRefOrigin.fX, fPixelRefOrigin.fY,
963 fInfo.width(), fInfo.height()); 971 fInfo.width(), fInfo.height());
964 if (fPixelRef->readPixels(&tmpSrc, &subset)) { 972 if (fPixelRef->readPixels(&tmpSrc, &subset)) {
973 if (fPixelRef->info().alphaType() == kUnpremul_SkAlphaType) {
974 // FIXME: The only meaningful implementation of readPixels
975 // (GrPixelRef) assumes premultiplied pixels.
976 return false;
977 }
965 SkASSERT(tmpSrc.width() == this->width()); 978 SkASSERT(tmpSrc.width() == this->width());
966 SkASSERT(tmpSrc.height() == this->height()); 979 SkASSERT(tmpSrc.height() == this->height());
967 980
968 // did we get lucky and we can just return tmpSrc? 981 // did we get lucky and we can just return tmpSrc?
969 if (tmpSrc.colorType() == dstColorType && NULL == alloc) { 982 if (tmpSrc.colorType() == dstColorType && NULL == alloc) {
970 dst->swap(tmpSrc); 983 dst->swap(tmpSrc);
971 // If the result is an exact copy, clone the gen ID. 984 // If the result is an exact copy, clone the gen ID.
972 if (dst->pixelRef() && dst->pixelRef()->info() == fPixelRef->inf o()) { 985 if (dst->pixelRef() && dst->pixelRef()->info() == fPixelRef->inf o()) {
973 dst->pixelRef()->cloneGenID(*fPixelRef); 986 dst->pixelRef()->cloneGenID(*fPixelRef);
974 } 987 }
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
1014 1027
1015 // pixelRef must be non NULL or tmpDst.readyToDraw() would have 1028 // pixelRef must be non NULL or tmpDst.readyToDraw() would have
1016 // returned false. 1029 // returned false.
1017 SkASSERT(tmpDst.pixelRef() != NULL); 1030 SkASSERT(tmpDst.pixelRef() != NULL);
1018 1031
1019 /* do memcpy for the same configs cases, else use drawing 1032 /* do memcpy for the same configs cases, else use drawing
1020 */ 1033 */
1021 if (src->colorType() == dstColorType) { 1034 if (src->colorType() == dstColorType) {
1022 if (tmpDst.getSize() == src->getSize()) { 1035 if (tmpDst.getSize() == src->getSize()) {
1023 memcpy(tmpDst.getPixels(), src->getPixels(), src->getSafeSize()); 1036 memcpy(tmpDst.getPixels(), src->getPixels(), src->getSafeSize());
1024 SkPixelRef* pixelRef = tmpDst.pixelRef();
1025 1037
1026 // In order to reach this point, we know that the width, config and 1038 SkPixelRef* dstPixelRef = tmpDst.pixelRef();
1027 // rowbytes of the SkPixelRefs are the same, but it is possible for 1039 if (dstPixelRef->info() == fPixelRef->info()) {
1028 // the heights to differ, if this SkBitmap's height is a subset of 1040 dstPixelRef->cloneGenID(*fPixelRef);
1029 // fPixelRef. Only if the SkPixelRefs' heights match are we
1030 // guaranteed that this is an exact copy, meaning we should clone
1031 // the genID.
1032 if (pixelRef->info().fHeight == fPixelRef->info().fHeight) {
1033 // TODO: what to do if the two infos match, BUT
1034 // fPixelRef is premul and pixelRef is opaque?
1035 // skipping assert for now
1036 // https://code.google.com/p/skia/issues/detail?id=2012
1037 // SkASSERT(pixelRef->info() == fPixelRef->info());
1038 SkASSERT(pixelRef->info().fWidth == fPixelRef->info().fWidth);
1039 SkASSERT(pixelRef->info().fColorType == fPixelRef->info().fColor Type);
1040 pixelRef->cloneGenID(*fPixelRef);
1041 } 1041 }
1042 } else { 1042 } else {
1043 const char* srcP = reinterpret_cast<const char*>(src->getPixels()); 1043 const char* srcP = reinterpret_cast<const char*>(src->getPixels());
1044 char* dstP = reinterpret_cast<char*>(tmpDst.getPixels()); 1044 char* dstP = reinterpret_cast<char*>(tmpDst.getPixels());
1045 // to be sure we don't read too much, only copy our logical pixels 1045 // to be sure we don't read too much, only copy our logical pixels
1046 size_t bytesToCopy = tmpDst.width() * tmpDst.bytesPerPixel(); 1046 size_t bytesToCopy = tmpDst.width() * tmpDst.bytesPerPixel();
1047 for (int y = 0; y < tmpDst.height(); y++) { 1047 for (int y = 0; y < tmpDst.height(); y++) {
1048 memcpy(dstP, srcP, bytesToCopy); 1048 memcpy(dstP, srcP, bytesToCopy);
1049 srcP += src->rowBytes(); 1049 srcP += src->rowBytes();
1050 dstP += tmpDst.rowBytes(); 1050 dstP += tmpDst.rowBytes();
1051 } 1051 }
1052 } 1052 }
1053 } else if (kARGB_4444_SkColorType == dstColorType 1053 } else if (kARGB_4444_SkColorType == dstColorType
1054 && kN32_SkColorType == src->colorType()) { 1054 && kN32_SkColorType == src->colorType()) {
1055 if (src->alphaType() == kUnpremul_SkAlphaType) {
1056 // Our method for converting to 4444 assumes premultiplied.
1057 return false;
1058 }
1055 SkASSERT(src->height() == tmpDst.height()); 1059 SkASSERT(src->height() == tmpDst.height());
1056 SkASSERT(src->width() == tmpDst.width()); 1060 SkASSERT(src->width() == tmpDst.width());
1057 for (int y = 0; y < src->height(); ++y) { 1061 for (int y = 0; y < src->height(); ++y) {
1058 SkPMColor16* SK_RESTRICT dstRow = (SkPMColor16*) tmpDst.getAddr16(0, y); 1062 SkPMColor16* SK_RESTRICT dstRow = (SkPMColor16*) tmpDst.getAddr16(0, y);
1059 SkPMColor* SK_RESTRICT srcRow = (SkPMColor*) src->getAddr32(0, y); 1063 SkPMColor* SK_RESTRICT srcRow = (SkPMColor*) src->getAddr32(0, y);
1060 DITHER_4444_SCAN(y); 1064 DITHER_4444_SCAN(y);
1061 for (int x = 0; x < src->width(); ++x) { 1065 for (int x = 0; x < src->width(); ++x) {
1062 dstRow[x] = SkDitherARGB32To4444(srcRow[x], 1066 dstRow[x] = SkDitherARGB32To4444(srcRow[x],
1063 DITHER_VALUE(x)); 1067 DITHER_VALUE(x));
1064 } 1068 }
1065 } 1069 }
1066 } else { 1070 } else {
1071 if (tmpDst.alphaType() == kUnpremul_SkAlphaType) {
1072 // We do not support drawing to unpremultiplied bitmaps.
1073 return false;
1074 }
1075
1067 // Always clear the dest in case one of the blitters accesses it 1076 // Always clear the dest in case one of the blitters accesses it
1068 // TODO: switch the allocation of tmpDst to call sk_calloc_throw 1077 // TODO: switch the allocation of tmpDst to call sk_calloc_throw
1069 tmpDst.eraseColor(SK_ColorTRANSPARENT); 1078 tmpDst.eraseColor(SK_ColorTRANSPARENT);
1070 1079
1071 SkCanvas canvas(tmpDst); 1080 SkCanvas canvas(tmpDst);
1072 SkPaint paint; 1081 SkPaint paint;
1073 1082
1074 paint.setDither(true); 1083 paint.setDither(true);
1075 canvas.drawBitmap(*src, 0, 0, &paint); 1084 canvas.drawBitmap(*src, 0, 0, &paint);
1076 } 1085 }
(...skipping 399 matching lines...) Expand 10 before | Expand all | Expand 10 after
1476 /////////////////////////////////////////////////////////////////////////////// 1485 ///////////////////////////////////////////////////////////////////////////////
1477 1486
1478 #ifdef SK_DEBUG 1487 #ifdef SK_DEBUG
1479 void SkImageInfo::validate() const { 1488 void SkImageInfo::validate() const {
1480 SkASSERT(fWidth >= 0); 1489 SkASSERT(fWidth >= 0);
1481 SkASSERT(fHeight >= 0); 1490 SkASSERT(fHeight >= 0);
1482 SkASSERT(SkColorTypeIsValid(fColorType)); 1491 SkASSERT(SkColorTypeIsValid(fColorType));
1483 SkASSERT(SkAlphaTypeIsValid(fAlphaType)); 1492 SkASSERT(SkAlphaTypeIsValid(fAlphaType));
1484 } 1493 }
1485 #endif 1494 #endif
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698