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 395 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |