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

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: 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& info, SkPixelRefFactory* factory,
reed1 2014/06/05 12:38:45 perhaps rename this to origInfo or requestedInfo,
scroggo 2014/06/05 15:33:29 Done.
417 SkColorTable* ctable) { 417 SkColorTable* ctable) {
418 if (kIndex_8_SkColorType == info.fColorType && NULL == ctable) { 418 if (kIndex_8_SkColorType == info.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(info)) {
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& info, void* pixels, size_t rb, S kColorTable* ct,
reed1 2014/06/05 12:38:45 ditto about renaming this too.
scroggo 2014/06/05 15:33:29 Done.
445 void (*releaseProc)(void* addr, void* context), voi d* context) { 448 void (*releaseProc)(void* addr, void* context), voi d* context) {
446 if (!this->setInfo(info, rb)) { 449 if (!this->setInfo(info, rb)) {
447 this->reset(); 450 this->reset();
448 return false; 451 return false;
449 } 452 }
450 453
451 SkPixelRef* pr = SkMallocPixelRef::NewWithProc(info, rb, ct, pixels, release Proc, context); 454 // setInfo may have corrected info (e.g. 565 is always opaque).
455 const SkImageInfo& correctedInfo = this->info();
456
457 SkPixelRef* pr = SkMallocPixelRef::NewWithProc(correctedInfo, rb, ct, pixels , releaseProc,
458 context);
452 if (!pr) { 459 if (!pr) {
453 this->reset(); 460 this->reset();
454 return false; 461 return false;
455 } 462 }
456 463
457 this->setPixelRef(pr)->unref(); 464 this->setPixelRef(pr)->unref();
458 465
459 // since we're already allocated, we lockPixels right away 466 // since we're already allocated, we lockPixels right away
460 this->lockPixels(); 467 this->lockPixels();
461 SkDEBUGCODE(this->validate();) 468 SkDEBUGCODE(this->validate();)
(...skipping 493 matching lines...) Expand 10 before | Expand all | Expand 10 after
955 962
956 // if we have a texture, first get those pixels 963 // if we have a texture, first get those pixels
957 SkBitmap tmpSrc; 964 SkBitmap tmpSrc;
958 const SkBitmap* src = this; 965 const SkBitmap* src = this;
959 966
960 if (fPixelRef) { 967 if (fPixelRef) {
961 SkIRect subset; 968 SkIRect subset;
962 subset.setXYWH(fPixelRefOrigin.fX, fPixelRefOrigin.fY, 969 subset.setXYWH(fPixelRefOrigin.fX, fPixelRefOrigin.fY,
963 fInfo.width(), fInfo.height()); 970 fInfo.width(), fInfo.height());
964 if (fPixelRef->readPixels(&tmpSrc, &subset)) { 971 if (fPixelRef->readPixels(&tmpSrc, &subset)) {
972 if (fPixelRef->info().alphaType() == kUnpremul_SkAlphaType) {
scroggo 2014/06/04 20:28:27 Brian, I've cc'ed you mainly to make sure I'm doi
bsalomon 2014/06/04 20:39:32 I suppose... I can't think of any better way to ha
reed1 2014/06/05 12:38:45 Is this because pixelref::readPixels is poorly def
scroggo 2014/06/05 15:33:29 I suppose the former. readPixels was written befor
973 // FIXME: The only meaningful implementation of readPixels
974 // (GrPixelRef) assumes premultiplied pixels.
975 return false;
976 }
965 SkASSERT(tmpSrc.width() == this->width()); 977 SkASSERT(tmpSrc.width() == this->width());
966 SkASSERT(tmpSrc.height() == this->height()); 978 SkASSERT(tmpSrc.height() == this->height());
967 979
968 // did we get lucky and we can just return tmpSrc? 980 // did we get lucky and we can just return tmpSrc?
969 if (tmpSrc.colorType() == dstColorType && NULL == alloc) { 981 if (tmpSrc.colorType() == dstColorType && NULL == alloc) {
970 dst->swap(tmpSrc); 982 dst->swap(tmpSrc);
971 // If the result is an exact copy, clone the gen ID. 983 // If the result is an exact copy, clone the gen ID.
972 if (dst->pixelRef() && dst->pixelRef()->info() == fPixelRef->inf o()) { 984 if (dst->pixelRef() && dst->pixelRef()->info() == fPixelRef->inf o()) {
973 dst->pixelRef()->cloneGenID(*fPixelRef); 985 dst->pixelRef()->cloneGenID(*fPixelRef);
974 } 986 }
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
1014 1026
1015 // pixelRef must be non NULL or tmpDst.readyToDraw() would have 1027 // pixelRef must be non NULL or tmpDst.readyToDraw() would have
1016 // returned false. 1028 // returned false.
1017 SkASSERT(tmpDst.pixelRef() != NULL); 1029 SkASSERT(tmpDst.pixelRef() != NULL);
1018 1030
1019 /* do memcpy for the same configs cases, else use drawing 1031 /* do memcpy for the same configs cases, else use drawing
1020 */ 1032 */
1021 if (src->colorType() == dstColorType) { 1033 if (src->colorType() == dstColorType) {
1022 if (tmpDst.getSize() == src->getSize()) { 1034 if (tmpDst.getSize() == src->getSize()) {
1023 memcpy(tmpDst.getPixels(), src->getPixels(), src->getSafeSize()); 1035 memcpy(tmpDst.getPixels(), src->getPixels(), src->getSafeSize());
1024 SkPixelRef* pixelRef = tmpDst.pixelRef();
1025 1036
1026 // In order to reach this point, we know that the width, config and 1037 SkPixelRef* dstPixelRef = tmpDst.pixelRef();
1027 // rowbytes of the SkPixelRefs are the same, but it is possible for 1038 if (dstPixelRef->info() == fPixelRef->info()) {
1028 // the heights to differ, if this SkBitmap's height is a subset of 1039 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 } 1040 }
1042 } else { 1041 } else {
1043 const char* srcP = reinterpret_cast<const char*>(src->getPixels()); 1042 const char* srcP = reinterpret_cast<const char*>(src->getPixels());
1044 char* dstP = reinterpret_cast<char*>(tmpDst.getPixels()); 1043 char* dstP = reinterpret_cast<char*>(tmpDst.getPixels());
1045 // to be sure we don't read too much, only copy our logical pixels 1044 // to be sure we don't read too much, only copy our logical pixels
1046 size_t bytesToCopy = tmpDst.width() * tmpDst.bytesPerPixel(); 1045 size_t bytesToCopy = tmpDst.width() * tmpDst.bytesPerPixel();
1047 for (int y = 0; y < tmpDst.height(); y++) { 1046 for (int y = 0; y < tmpDst.height(); y++) {
1048 memcpy(dstP, srcP, bytesToCopy); 1047 memcpy(dstP, srcP, bytesToCopy);
1049 srcP += src->rowBytes(); 1048 srcP += src->rowBytes();
1050 dstP += tmpDst.rowBytes(); 1049 dstP += tmpDst.rowBytes();
1051 } 1050 }
1052 } 1051 }
1053 } else if (kARGB_4444_SkColorType == dstColorType 1052 } else if (kARGB_4444_SkColorType == dstColorType
1054 && kN32_SkColorType == src->colorType()) { 1053 && kN32_SkColorType == src->colorType()) {
1054 if (src->alphaType() == kUnpremul_SkAlphaType) {
1055 // Our method for converting to 4444 assumes premultiplied.
1056 return false;
1057 }
1055 SkASSERT(src->height() == tmpDst.height()); 1058 SkASSERT(src->height() == tmpDst.height());
1056 SkASSERT(src->width() == tmpDst.width()); 1059 SkASSERT(src->width() == tmpDst.width());
1057 for (int y = 0; y < src->height(); ++y) { 1060 for (int y = 0; y < src->height(); ++y) {
1058 SkPMColor16* SK_RESTRICT dstRow = (SkPMColor16*) tmpDst.getAddr16(0, y); 1061 SkPMColor16* SK_RESTRICT dstRow = (SkPMColor16*) tmpDst.getAddr16(0, y);
1059 SkPMColor* SK_RESTRICT srcRow = (SkPMColor*) src->getAddr32(0, y); 1062 SkPMColor* SK_RESTRICT srcRow = (SkPMColor*) src->getAddr32(0, y);
1060 DITHER_4444_SCAN(y); 1063 DITHER_4444_SCAN(y);
1061 for (int x = 0; x < src->width(); ++x) { 1064 for (int x = 0; x < src->width(); ++x) {
1062 dstRow[x] = SkDitherARGB32To4444(srcRow[x], 1065 dstRow[x] = SkDitherARGB32To4444(srcRow[x],
1063 DITHER_VALUE(x)); 1066 DITHER_VALUE(x));
1064 } 1067 }
1065 } 1068 }
1066 } else { 1069 } else {
1070 if (tmpDst.alphaType() == kUnpremul_SkAlphaType) {
1071 // We do not support drawing to unpremultiplied bitmaps.
1072 return false;
1073 }
1074
1067 // Always clear the dest in case one of the blitters accesses it 1075 // Always clear the dest in case one of the blitters accesses it
1068 // TODO: switch the allocation of tmpDst to call sk_calloc_throw 1076 // TODO: switch the allocation of tmpDst to call sk_calloc_throw
1069 tmpDst.eraseColor(SK_ColorTRANSPARENT); 1077 tmpDst.eraseColor(SK_ColorTRANSPARENT);
1070 1078
1071 SkCanvas canvas(tmpDst); 1079 SkCanvas canvas(tmpDst);
1072 SkPaint paint; 1080 SkPaint paint;
1073 1081
1074 paint.setDither(true); 1082 paint.setDither(true);
1075 canvas.drawBitmap(*src, 0, 0, &paint); 1083 canvas.drawBitmap(*src, 0, 0, &paint);
1076 } 1084 }
(...skipping 399 matching lines...) Expand 10 before | Expand all | Expand 10 after
1476 /////////////////////////////////////////////////////////////////////////////// 1484 ///////////////////////////////////////////////////////////////////////////////
1477 1485
1478 #ifdef SK_DEBUG 1486 #ifdef SK_DEBUG
1479 void SkImageInfo::validate() const { 1487 void SkImageInfo::validate() const {
1480 SkASSERT(fWidth >= 0); 1488 SkASSERT(fWidth >= 0);
1481 SkASSERT(fHeight >= 0); 1489 SkASSERT(fHeight >= 0);
1482 SkASSERT(SkColorTypeIsValid(fColorType)); 1490 SkASSERT(SkColorTypeIsValid(fColorType));
1483 SkASSERT(SkAlphaTypeIsValid(fAlphaType)); 1491 SkASSERT(SkAlphaTypeIsValid(fAlphaType));
1484 } 1492 }
1485 #endif 1493 #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