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 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
122 } | 122 } |
123 } | 123 } |
124 | 124 |
125 SkDEBUGCODE(this->validate();) | 125 SkDEBUGCODE(this->validate();) |
126 return *this; | 126 return *this; |
127 } | 127 } |
128 | 128 |
129 void SkBitmap::swap(SkBitmap& other) { | 129 void SkBitmap::swap(SkBitmap& other) { |
130 SkTSwap(fColorTable, other.fColorTable); | 130 SkTSwap(fColorTable, other.fColorTable); |
131 SkTSwap(fPixelRef, other.fPixelRef); | 131 SkTSwap(fPixelRef, other.fPixelRef); |
132 SkTSwap(fPixelRefOffset, other.fPixelRefOffset); | 132 SkTSwap(fPixelRefOrigin, other.fPixelRefOrigin); |
133 SkTSwap(fPixelLockCount, other.fPixelLockCount); | 133 SkTSwap(fPixelLockCount, other.fPixelLockCount); |
134 SkTSwap(fMipMap, other.fMipMap); | 134 SkTSwap(fMipMap, other.fMipMap); |
135 SkTSwap(fPixels, other.fPixels); | 135 SkTSwap(fPixels, other.fPixels); |
136 SkTSwap(fRowBytes, other.fRowBytes); | 136 SkTSwap(fRowBytes, other.fRowBytes); |
137 SkTSwap(fWidth, other.fWidth); | 137 SkTSwap(fWidth, other.fWidth); |
138 SkTSwap(fHeight, other.fHeight); | 138 SkTSwap(fHeight, other.fHeight); |
139 SkTSwap(fConfig, other.fConfig); | 139 SkTSwap(fConfig, other.fConfig); |
140 SkTSwap(fAlphaType, other.fAlphaType); | 140 SkTSwap(fAlphaType, other.fAlphaType); |
141 SkTSwap(fFlags, other.fFlags); | 141 SkTSwap(fFlags, other.fFlags); |
142 SkTSwap(fBytesPerPixel, other.fBytesPerPixel); | 142 SkTSwap(fBytesPerPixel, other.fBytesPerPixel); |
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
333 return true; | 333 return true; |
334 } | 334 } |
335 | 335 |
336 void SkBitmap::updatePixelsFromRef() const { | 336 void SkBitmap::updatePixelsFromRef() const { |
337 if (NULL != fPixelRef) { | 337 if (NULL != fPixelRef) { |
338 if (fPixelLockCount > 0) { | 338 if (fPixelLockCount > 0) { |
339 SkASSERT(fPixelRef->isLocked()); | 339 SkASSERT(fPixelRef->isLocked()); |
340 | 340 |
341 void* p = fPixelRef->pixels(); | 341 void* p = fPixelRef->pixels(); |
342 if (NULL != p) { | 342 if (NULL != p) { |
343 p = (char*)p + fPixelRefOffset; | 343 p = (char*)p |
| 344 + fPixelRef->rowBytes() * fPixelRefOrigin.fY |
| 345 + fPixelRefOrigin.fX * fBytesPerPixel; |
344 } | 346 } |
345 fPixels = p; | 347 fPixels = p; |
346 SkRefCnt_SafeAssign(fColorTable, fPixelRef->colorTable()); | 348 SkRefCnt_SafeAssign(fColorTable, fPixelRef->colorTable()); |
347 } else { | 349 } else { |
348 SkASSERT(0 == fPixelLockCount); | 350 SkASSERT(0 == fPixelLockCount); |
349 fPixels = NULL; | 351 fPixels = NULL; |
350 if (fColorTable) { | 352 if (fColorTable) { |
351 fColorTable->unref(); | 353 fColorTable->unref(); |
352 fColorTable = NULL; | 354 fColorTable = NULL; |
353 } | 355 } |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
390 } | 392 } |
391 if (info) { | 393 if (info) { |
392 info->fWidth = fWidth; | 394 info->fWidth = fWidth; |
393 info->fHeight = fHeight; | 395 info->fHeight = fHeight; |
394 info->fAlphaType = this->alphaType(); | 396 info->fAlphaType = this->alphaType(); |
395 info->fColorType = ct; | 397 info->fColorType = ct; |
396 } | 398 } |
397 return true; | 399 return true; |
398 } | 400 } |
399 | 401 |
400 SkPixelRef* SkBitmap::setPixelRef(SkPixelRef* pr, size_t offset) { | 402 SkPixelRef* SkBitmap::setPixelRef(SkPixelRef* pr, int dx, int dy) { |
401 // do this first, we that we never have a non-zero offset with a null ref | |
402 if (NULL == pr) { | |
403 offset = 0; | |
404 } | |
405 #ifdef SK_DEBUG | 403 #ifdef SK_DEBUG |
406 else { | 404 if (pr) { |
407 SkImageInfo info; | 405 SkImageInfo info; |
408 if (this->asImageInfo(&info)) { | 406 if (this->asImageInfo(&info)) { |
409 const SkImageInfo& prInfo = pr->info(); | 407 const SkImageInfo& prInfo = pr->info(); |
410 SkASSERT(info.fWidth <= prInfo.fWidth); | 408 SkASSERT(info.fWidth <= prInfo.fWidth); |
411 SkASSERT(info.fHeight <= prInfo.fHeight); | 409 SkASSERT(info.fHeight <= prInfo.fHeight); |
412 SkASSERT(info.fColorType == prInfo.fColorType); | 410 SkASSERT(info.fColorType == prInfo.fColorType); |
413 switch (prInfo.fAlphaType) { | 411 switch (prInfo.fAlphaType) { |
414 case kIgnore_SkAlphaType: | 412 case kIgnore_SkAlphaType: |
415 SkASSERT(fAlphaType == kIgnore_SkAlphaType); | 413 SkASSERT(fAlphaType == kIgnore_SkAlphaType); |
416 break; | 414 break; |
417 case kOpaque_SkAlphaType: | 415 case kOpaque_SkAlphaType: |
418 case kPremul_SkAlphaType: | 416 case kPremul_SkAlphaType: |
419 SkASSERT(info.fAlphaType == kOpaque_SkAlphaType || | 417 SkASSERT(info.fAlphaType == kOpaque_SkAlphaType || |
420 info.fAlphaType == kPremul_SkAlphaType); | 418 info.fAlphaType == kPremul_SkAlphaType); |
421 break; | 419 break; |
422 case kUnpremul_SkAlphaType: | 420 case kUnpremul_SkAlphaType: |
423 SkASSERT(info.fAlphaType == kOpaque_SkAlphaType || | 421 SkASSERT(info.fAlphaType == kOpaque_SkAlphaType || |
424 info.fAlphaType == kUnpremul_SkAlphaType); | 422 info.fAlphaType == kUnpremul_SkAlphaType); |
425 break; | 423 break; |
426 } | 424 } |
427 } | 425 } |
428 } | 426 } |
429 #endif | 427 #endif |
430 | 428 |
431 if (fPixelRef != pr || fPixelRefOffset != offset) { | 429 if (pr) { |
| 430 const SkImageInfo& info = pr->info(); |
| 431 fPixelRefOrigin.set(SkPin32(dx, 0, info.fWidth), |
| 432 SkPin32(dy, 0, info.fHeight)); |
| 433 } else { |
| 434 // ignore dx,dy if there is no pixelref |
| 435 fPixelRefOrigin.setZero(); |
| 436 } |
| 437 |
| 438 if (fPixelRef != pr) { |
432 if (fPixelRef != pr) { | 439 if (fPixelRef != pr) { |
433 this->freePixels(); | 440 this->freePixels(); |
434 SkASSERT(NULL == fPixelRef); | 441 SkASSERT(NULL == fPixelRef); |
435 | 442 |
436 SkSafeRef(pr); | 443 SkSafeRef(pr); |
437 fPixelRef = pr; | 444 fPixelRef = pr; |
438 } | 445 } |
439 fPixelRefOffset = offset; | |
440 this->updatePixelsFromRef(); | 446 this->updatePixelsFromRef(); |
441 } | 447 } |
442 | 448 |
443 SkDEBUGCODE(this->validate();) | 449 SkDEBUGCODE(this->validate();) |
444 return pr; | 450 return pr; |
445 } | 451 } |
446 | 452 |
447 void SkBitmap::lockPixels() const { | 453 void SkBitmap::lockPixels() const { |
448 if (NULL != fPixelRef && 0 == sk_atomic_inc(&fPixelLockCount)) { | 454 if (NULL != fPixelRef && 0 == sk_atomic_inc(&fPixelLockCount)) { |
449 fPixelRef->lockPixels(); | 455 fPixelRef->lockPixels(); |
(...skipping 11 matching lines...) Expand all Loading... |
461 } | 467 } |
462 SkDEBUGCODE(this->validate();) | 468 SkDEBUGCODE(this->validate();) |
463 } | 469 } |
464 | 470 |
465 bool SkBitmap::lockPixelsAreWritable() const { | 471 bool SkBitmap::lockPixelsAreWritable() const { |
466 return (fPixelRef) ? fPixelRef->lockPixelsAreWritable() : false; | 472 return (fPixelRef) ? fPixelRef->lockPixelsAreWritable() : false; |
467 } | 473 } |
468 | 474 |
469 void SkBitmap::setPixels(void* p, SkColorTable* ctable) { | 475 void SkBitmap::setPixels(void* p, SkColorTable* ctable) { |
470 if (NULL == p) { | 476 if (NULL == p) { |
471 this->setPixelRef(NULL, 0); | 477 this->setPixelRef(NULL); |
472 return; | 478 return; |
473 } | 479 } |
474 | 480 |
475 SkImageInfo info; | 481 SkImageInfo info; |
476 if (!this->asImageInfo(&info)) { | 482 if (!this->asImageInfo(&info)) { |
477 this->setPixelRef(NULL, 0); | 483 this->setPixelRef(NULL); |
478 return; | 484 return; |
479 } | 485 } |
480 | 486 |
481 SkPixelRef* pr = SkMallocPixelRef::NewDirect(info, p, fRowBytes, ctable); | 487 SkPixelRef* pr = SkMallocPixelRef::NewDirect(info, p, fRowBytes, ctable); |
482 if (NULL == pr) { | 488 if (NULL == pr) { |
483 this->setPixelRef(NULL, 0); | 489 this->setPixelRef(NULL); |
484 return; | 490 return; |
485 } | 491 } |
486 | 492 |
487 this->setPixelRef(pr)->unref(); | 493 this->setPixelRef(pr)->unref(); |
488 | 494 |
489 // since we're already allocated, we lockPixels right away | 495 // since we're already allocated, we lockPixels right away |
490 this->lockPixels(); | 496 this->lockPixels(); |
491 SkDEBUGCODE(this->validate();) | 497 SkDEBUGCODE(this->validate();) |
492 } | 498 } |
493 | 499 |
(...skipping 14 matching lines...) Expand all Loading... |
508 fColorTable->unref(); | 514 fColorTable->unref(); |
509 fColorTable = NULL; | 515 fColorTable = NULL; |
510 } | 516 } |
511 | 517 |
512 if (NULL != fPixelRef) { | 518 if (NULL != fPixelRef) { |
513 if (fPixelLockCount > 0) { | 519 if (fPixelLockCount > 0) { |
514 fPixelRef->unlockPixels(); | 520 fPixelRef->unlockPixels(); |
515 } | 521 } |
516 fPixelRef->unref(); | 522 fPixelRef->unref(); |
517 fPixelRef = NULL; | 523 fPixelRef = NULL; |
518 fPixelRefOffset = 0; | 524 fPixelRefOrigin.setZero(); |
519 } | 525 } |
520 fPixelLockCount = 0; | 526 fPixelLockCount = 0; |
521 fPixels = NULL; | 527 fPixels = NULL; |
522 } | 528 } |
523 | 529 |
524 void SkBitmap::freeMipMap() { | 530 void SkBitmap::freeMipMap() { |
525 if (fMipMap) { | 531 if (fMipMap) { |
526 fMipMap->unref(); | 532 fMipMap->unref(); |
527 fMipMap = NULL; | 533 fMipMap = NULL; |
528 } | 534 } |
(...skipping 26 matching lines...) Expand all Loading... |
555 // SkDebugf("unsupported config for info %d\n", dst->config()); | 561 // SkDebugf("unsupported config for info %d\n", dst->config()); |
556 return false; | 562 return false; |
557 } | 563 } |
558 | 564 |
559 SkPixelRef* pr = SkMallocPixelRef::NewAllocate(info, dst->rowBytes(), | 565 SkPixelRef* pr = SkMallocPixelRef::NewAllocate(info, dst->rowBytes(), |
560 ctable); | 566 ctable); |
561 if (NULL == pr) { | 567 if (NULL == pr) { |
562 return false; | 568 return false; |
563 } | 569 } |
564 | 570 |
565 dst->setPixelRef(pr, 0)->unref(); | 571 dst->setPixelRef(pr)->unref(); |
566 // since we're already allocated, we lockPixels right away | 572 // since we're already allocated, we lockPixels right away |
567 dst->lockPixels(); | 573 dst->lockPixels(); |
568 return true; | 574 return true; |
569 } | 575 } |
570 | 576 |
571 /////////////////////////////////////////////////////////////////////////////// | 577 /////////////////////////////////////////////////////////////////////////////// |
572 | 578 |
573 size_t SkBitmap::getSafeSize() const { | 579 size_t SkBitmap::getSafeSize() const { |
574 // This is intended to be a size_t version of ComputeSafeSize64(), just | 580 // This is intended to be a size_t version of ComputeSafeSize64(), just |
575 // faster. The computation is meant to be identical. | 581 // faster. The computation is meant to be identical. |
(...skipping 304 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
880 SkIRect area = { 0, 0, this->width(), this->height() }; | 886 SkIRect area = { 0, 0, this->width(), this->height() }; |
881 if (area.intersect(rect)) { | 887 if (area.intersect(rect)) { |
882 this->internalErase(area, SkColorGetA(c), SkColorGetR(c), | 888 this->internalErase(area, SkColorGetA(c), SkColorGetR(c), |
883 SkColorGetG(c), SkColorGetB(c)); | 889 SkColorGetG(c), SkColorGetB(c)); |
884 } | 890 } |
885 } | 891 } |
886 | 892 |
887 ////////////////////////////////////////////////////////////////////////////////
////// | 893 ////////////////////////////////////////////////////////////////////////////////
////// |
888 ////////////////////////////////////////////////////////////////////////////////
////// | 894 ////////////////////////////////////////////////////////////////////////////////
////// |
889 | 895 |
890 #define SUB_OFFSET_FAILURE ((size_t)-1) | |
891 | |
892 /** | |
893 * Based on the Config and rowBytes() of bm, return the offset into an SkPixelR
ef of the pixel at | |
894 * (x, y). | |
895 * Note that the SkPixelRef does not need to be set yet. deepCopyTo takes advan
tage of this fact. | |
896 * Also note that (x, y) may be outside the range of (0 - width(), 0 - height()
), so long as it is | |
897 * within the bounds of the SkPixelRef being used. | |
898 */ | |
899 static size_t get_sub_offset(const SkBitmap& bm, int x, int y) { | |
900 switch (bm.config()) { | |
901 case SkBitmap::kA8_Config: | |
902 case SkBitmap:: kIndex8_Config: | |
903 // x is fine as is for the calculation | |
904 break; | |
905 | |
906 case SkBitmap::kRGB_565_Config: | |
907 case SkBitmap::kARGB_4444_Config: | |
908 x <<= 1; | |
909 break; | |
910 | |
911 case SkBitmap::kARGB_8888_Config: | |
912 x <<= 2; | |
913 break; | |
914 | |
915 case SkBitmap::kNo_Config: | |
916 default: | |
917 return SUB_OFFSET_FAILURE; | |
918 } | |
919 return y * bm.rowBytes() + x; | |
920 } | |
921 | |
922 /** | |
923 * Using the pixelRefOffset(), rowBytes(), and Config of bm, determine the (x,
y) coordinate of the | |
924 * upper left corner of bm relative to its SkPixelRef. | |
925 * x and y must be non-NULL. | |
926 */ | |
927 bool get_upper_left_from_offset(SkBitmap::Config config, size_t offset, size_t r
owBytes, | |
928 int32_t* x, int32_t* y); | |
929 bool get_upper_left_from_offset(SkBitmap::Config config, size_t offset, size_t r
owBytes, | |
930 int32_t* x, int32_t* y) { | |
931 SkASSERT(x != NULL && y != NULL); | |
932 if (0 == offset) { | |
933 *x = *y = 0; | |
934 return true; | |
935 } | |
936 // Use integer division to find the correct y position. | |
937 // The remainder will be the x position, after we reverse get_sub_offset. | |
938 SkTDivMod(offset, rowBytes, y, x); | |
939 switch (config) { | |
940 case SkBitmap::kA8_Config: | |
941 // Fall through. | |
942 case SkBitmap::kIndex8_Config: | |
943 // x is unmodified | |
944 break; | |
945 | |
946 case SkBitmap::kRGB_565_Config: | |
947 // Fall through. | |
948 case SkBitmap::kARGB_4444_Config: | |
949 *x >>= 1; | |
950 break; | |
951 | |
952 case SkBitmap::kARGB_8888_Config: | |
953 *x >>= 2; | |
954 break; | |
955 | |
956 case SkBitmap::kNo_Config: | |
957 // Fall through. | |
958 default: | |
959 return false; | |
960 } | |
961 return true; | |
962 } | |
963 | |
964 static bool get_upper_left_from_offset(const SkBitmap& bm, int32_t* x, int32_t*
y) { | |
965 return get_upper_left_from_offset(bm.config(), bm.pixelRefOffset(), bm.rowBy
tes(), x, y); | |
966 } | |
967 | |
968 bool SkBitmap::extractSubset(SkBitmap* result, const SkIRect& subset) const { | 896 bool SkBitmap::extractSubset(SkBitmap* result, const SkIRect& subset) const { |
969 SkDEBUGCODE(this->validate();) | 897 SkDEBUGCODE(this->validate();) |
970 | 898 |
971 if (NULL == result || NULL == fPixelRef) { | 899 if (NULL == result || NULL == fPixelRef) { |
972 return false; // no src pixels | 900 return false; // no src pixels |
973 } | 901 } |
974 | 902 |
975 SkIRect srcRect, r; | 903 SkIRect srcRect, r; |
976 srcRect.set(0, 0, this->width(), this->height()); | 904 srcRect.set(0, 0, this->width(), this->height()); |
977 if (!r.intersect(srcRect, subset)) { | 905 if (!r.intersect(srcRect, subset)) { |
(...skipping 13 matching lines...) Expand all Loading... |
991 result->swap(dst); | 919 result->swap(dst); |
992 return true; | 920 return true; |
993 } | 921 } |
994 } | 922 } |
995 | 923 |
996 // If the upper left of the rectangle was outside the bounds of this SkBitma
p, we should have | 924 // If the upper left of the rectangle was outside the bounds of this SkBitma
p, we should have |
997 // exited above. | 925 // exited above. |
998 SkASSERT(static_cast<unsigned>(r.fLeft) < static_cast<unsigned>(this->width(
))); | 926 SkASSERT(static_cast<unsigned>(r.fLeft) < static_cast<unsigned>(this->width(
))); |
999 SkASSERT(static_cast<unsigned>(r.fTop) < static_cast<unsigned>(this->height(
))); | 927 SkASSERT(static_cast<unsigned>(r.fTop) < static_cast<unsigned>(this->height(
))); |
1000 | 928 |
1001 size_t offset = get_sub_offset(*this, r.fLeft, r.fTop); | |
1002 if (SUB_OFFSET_FAILURE == offset) { | |
1003 return false; // config not supported | |
1004 } | |
1005 | |
1006 SkBitmap dst; | 929 SkBitmap dst; |
1007 dst.setConfig(this->config(), r.width(), r.height(), this->rowBytes(), | 930 dst.setConfig(this->config(), r.width(), r.height(), this->rowBytes(), |
1008 this->alphaType()); | 931 this->alphaType()); |
1009 dst.setIsVolatile(this->isVolatile()); | 932 dst.setIsVolatile(this->isVolatile()); |
1010 | 933 |
1011 if (fPixelRef) { | 934 if (fPixelRef) { |
| 935 SkIPoint origin = fPixelRefOrigin; |
| 936 origin.fX += r.fLeft; |
| 937 origin.fY += r.fTop; |
1012 // share the pixelref with a custom offset | 938 // share the pixelref with a custom offset |
1013 dst.setPixelRef(fPixelRef, fPixelRefOffset + offset); | 939 dst.setPixelRef(fPixelRef, origin); |
1014 } | 940 } |
1015 SkDEBUGCODE(dst.validate();) | 941 SkDEBUGCODE(dst.validate();) |
1016 | 942 |
1017 // we know we're good, so commit to result | 943 // we know we're good, so commit to result |
1018 result->swap(dst); | 944 result->swap(dst); |
1019 return true; | 945 return true; |
1020 } | 946 } |
1021 | 947 |
1022 /////////////////////////////////////////////////////////////////////////////// | 948 /////////////////////////////////////////////////////////////////////////////// |
1023 | 949 |
(...skipping 28 matching lines...) Expand all Loading... |
1052 if (!this->canCopyTo(dstConfig)) { | 978 if (!this->canCopyTo(dstConfig)) { |
1053 return false; | 979 return false; |
1054 } | 980 } |
1055 | 981 |
1056 // if we have a texture, first get those pixels | 982 // if we have a texture, first get those pixels |
1057 SkBitmap tmpSrc; | 983 SkBitmap tmpSrc; |
1058 const SkBitmap* src = this; | 984 const SkBitmap* src = this; |
1059 | 985 |
1060 if (fPixelRef) { | 986 if (fPixelRef) { |
1061 SkIRect subset; | 987 SkIRect subset; |
1062 if (get_upper_left_from_offset(*this, &subset.fLeft, &subset.fTop)) { | 988 subset.setXYWH(fPixelRefOrigin.fX, fPixelRefOrigin.fY, fWidth, fHeight); |
1063 subset.fRight = subset.fLeft + fWidth; | 989 if (fPixelRef->readPixels(&tmpSrc, &subset)) { |
1064 subset.fBottom = subset.fTop + fHeight; | 990 SkASSERT(tmpSrc.width() == this->width()); |
1065 if (fPixelRef->readPixels(&tmpSrc, &subset)) { | 991 SkASSERT(tmpSrc.height() == this->height()); |
1066 SkASSERT(tmpSrc.width() == this->width()); | |
1067 SkASSERT(tmpSrc.height() == this->height()); | |
1068 | 992 |
1069 // did we get lucky and we can just return tmpSrc? | 993 // did we get lucky and we can just return tmpSrc? |
1070 if (tmpSrc.config() == dstConfig && NULL == alloc) { | 994 if (tmpSrc.config() == dstConfig && NULL == alloc) { |
1071 dst->swap(tmpSrc); | 995 dst->swap(tmpSrc); |
1072 if (dst->pixelRef() && this->config() == dstConfig) { | 996 if (dst->pixelRef() && this->config() == dstConfig) { |
1073 // TODO(scroggo): fix issue 1742 | 997 // TODO(scroggo): fix issue 1742 |
1074 dst->pixelRef()->cloneGenID(*fPixelRef); | 998 dst->pixelRef()->cloneGenID(*fPixelRef); |
1075 } | |
1076 return true; | |
1077 } | 999 } |
| 1000 return true; |
| 1001 } |
1078 | 1002 |
1079 // fall through to the raster case | 1003 // fall through to the raster case |
1080 src = &tmpSrc; | 1004 src = &tmpSrc; |
1081 } | |
1082 } | 1005 } |
1083 } | 1006 } |
1084 | 1007 |
1085 // we lock this now, since we may need its colortable | 1008 // we lock this now, since we may need its colortable |
1086 SkAutoLockPixels srclock(*src); | 1009 SkAutoLockPixels srclock(*src); |
1087 if (!src->readyToDraw()) { | 1010 if (!src->readyToDraw()) { |
1088 return false; | 1011 return false; |
1089 } | 1012 } |
1090 | 1013 |
1091 SkBitmap tmpDst; | 1014 SkBitmap tmpDst; |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1169 if (dstConfig == fConfig) { | 1092 if (dstConfig == fConfig) { |
1170 // TODO(scroggo): fix issue 1742 | 1093 // TODO(scroggo): fix issue 1742 |
1171 pixelRef->cloneGenID(*fPixelRef); | 1094 pixelRef->cloneGenID(*fPixelRef); |
1172 // Use the same rowBytes as the original. | 1095 // Use the same rowBytes as the original. |
1173 rowBytes = fRowBytes; | 1096 rowBytes = fRowBytes; |
1174 } else { | 1097 } else { |
1175 // With the new config, an appropriate fRowBytes will be compute
d by setConfig. | 1098 // With the new config, an appropriate fRowBytes will be compute
d by setConfig. |
1176 rowBytes = 0; | 1099 rowBytes = 0; |
1177 } | 1100 } |
1178 dst->setConfig(dstConfig, fWidth, fHeight, rowBytes); | 1101 dst->setConfig(dstConfig, fWidth, fHeight, rowBytes); |
1179 | 1102 dst->setPixelRef(pixelRef, fPixelRefOrigin)->unref(); |
1180 size_t pixelRefOffset; | |
1181 if (0 == fPixelRefOffset || dstConfig == fConfig) { | |
1182 // Use the same offset as the original. | |
1183 pixelRefOffset = fPixelRefOffset; | |
1184 } else { | |
1185 // Find the correct offset in the new config. This needs to be d
one after calling | |
1186 // setConfig so dst's fConfig and fRowBytes have been set proper
ly. | |
1187 int32_t x, y; | |
1188 if (!get_upper_left_from_offset(*this, &x, &y)) { | |
1189 return false; | |
1190 } | |
1191 pixelRefOffset = get_sub_offset(*dst, x, y); | |
1192 if (SUB_OFFSET_FAILURE == pixelRefOffset) { | |
1193 return false; | |
1194 } | |
1195 } | |
1196 dst->setPixelRef(pixelRef, pixelRefOffset)->unref(); | |
1197 return true; | 1103 return true; |
1198 } | 1104 } |
1199 } | 1105 } |
1200 | 1106 |
1201 if (this->getTexture()) { | 1107 if (this->getTexture()) { |
1202 return false; | 1108 return false; |
1203 } else { | 1109 } else { |
1204 return this->copyTo(dst, dstConfig, NULL); | 1110 return this->copyTo(dst, dstConfig, NULL); |
1205 } | 1111 } |
1206 } | 1112 } |
(...skipping 390 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1597 void SkBitmap::flatten(SkFlattenableWriteBuffer& buffer) const { | 1503 void SkBitmap::flatten(SkFlattenableWriteBuffer& buffer) const { |
1598 buffer.writeInt(fWidth); | 1504 buffer.writeInt(fWidth); |
1599 buffer.writeInt(fHeight); | 1505 buffer.writeInt(fHeight); |
1600 buffer.writeInt(fRowBytes); | 1506 buffer.writeInt(fRowBytes); |
1601 buffer.writeInt(fConfig); | 1507 buffer.writeInt(fConfig); |
1602 buffer.writeInt(fAlphaType); | 1508 buffer.writeInt(fAlphaType); |
1603 | 1509 |
1604 if (fPixelRef) { | 1510 if (fPixelRef) { |
1605 if (fPixelRef->getFactory()) { | 1511 if (fPixelRef->getFactory()) { |
1606 buffer.writeInt(SERIALIZE_PIXELTYPE_REF_DATA); | 1512 buffer.writeInt(SERIALIZE_PIXELTYPE_REF_DATA); |
1607 buffer.writeUInt(SkToU32(fPixelRefOffset)); | 1513 buffer.writeInt(fPixelRefOrigin.fX); |
| 1514 buffer.writeInt(fPixelRefOrigin.fY); |
1608 buffer.writeFlattenable(fPixelRef); | 1515 buffer.writeFlattenable(fPixelRef); |
1609 return; | 1516 return; |
1610 } | 1517 } |
1611 // if we get here, we can't record the pixels | 1518 // if we get here, we can't record the pixels |
1612 buffer.writeInt(SERIALIZE_PIXELTYPE_NONE); | 1519 buffer.writeInt(SERIALIZE_PIXELTYPE_NONE); |
1613 } else { | 1520 } else { |
1614 buffer.writeInt(SERIALIZE_PIXELTYPE_NONE); | 1521 buffer.writeInt(SERIALIZE_PIXELTYPE_NONE); |
1615 } | 1522 } |
1616 } | 1523 } |
1617 | 1524 |
(...skipping 12 matching lines...) Expand all Loading... |
1630 // Note : Using (fRowBytes >= (fWidth * fBytesPerPixel)) in the following te
st can create false | 1537 // Note : Using (fRowBytes >= (fWidth * fBytesPerPixel)) in the following te
st can create false |
1631 // positives if the multiplication causes an integer overflow. Use th
e division instead. | 1538 // positives if the multiplication causes an integer overflow. Use th
e division instead. |
1632 buffer.validate(configIsValid && (fBytesPerPixel > 0) && | 1539 buffer.validate(configIsValid && (fBytesPerPixel > 0) && |
1633 ((fRowBytes / fBytesPerPixel) >= fWidth)); | 1540 ((fRowBytes / fBytesPerPixel) >= fWidth)); |
1634 | 1541 |
1635 int reftype = buffer.readInt(); | 1542 int reftype = buffer.readInt(); |
1636 if (buffer.validate((SERIALIZE_PIXELTYPE_REF_DATA == reftype) || | 1543 if (buffer.validate((SERIALIZE_PIXELTYPE_REF_DATA == reftype) || |
1637 (SERIALIZE_PIXELTYPE_NONE == reftype))) { | 1544 (SERIALIZE_PIXELTYPE_NONE == reftype))) { |
1638 switch (reftype) { | 1545 switch (reftype) { |
1639 case SERIALIZE_PIXELTYPE_REF_DATA: { | 1546 case SERIALIZE_PIXELTYPE_REF_DATA: { |
1640 size_t offset = buffer.readUInt(); | 1547 SkIPoint origin; |
| 1548 origin.fX = buffer.readInt(); |
| 1549 origin.fY = buffer.readInt(); |
| 1550 size_t offset = origin.fY * rowBytes + origin.fX * fBytesPerPixe
l; |
1641 SkPixelRef* pr = buffer.readPixelRef(); | 1551 SkPixelRef* pr = buffer.readPixelRef(); |
1642 if (!buffer.validate((NULL == pr) || | 1552 if (!buffer.validate((NULL == pr) || |
1643 (pr->getAllocatedSizeInBytes() >= (offset + this->getSafe
Size())))) { | 1553 (pr->getAllocatedSizeInBytes() >= (offset + this->getSafe
Size())))) { |
1644 offset = 0; | 1554 origin.setZero(); |
1645 } | 1555 } |
1646 SkSafeUnref(this->setPixelRef(pr, offset)); | 1556 SkSafeUnref(this->setPixelRef(pr, origin)); |
1647 break; | 1557 break; |
1648 } | 1558 } |
1649 case SERIALIZE_PIXELTYPE_NONE: | 1559 case SERIALIZE_PIXELTYPE_NONE: |
1650 break; | 1560 break; |
1651 default: | 1561 default: |
1652 SkDEBUGFAIL("unrecognized pixeltype in serialized data"); | 1562 SkDEBUGFAIL("unrecognized pixeltype in serialized data"); |
1653 sk_throw(); | 1563 sk_throw(); |
1654 } | 1564 } |
1655 } | 1565 } |
1656 } | 1566 } |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1726 if (NULL != uri) { | 1636 if (NULL != uri) { |
1727 str->appendf(" uri:\"%s\"", uri); | 1637 str->appendf(" uri:\"%s\"", uri); |
1728 } else { | 1638 } else { |
1729 str->appendf(" pixelref:%p", pr); | 1639 str->appendf(" pixelref:%p", pr); |
1730 } | 1640 } |
1731 } | 1641 } |
1732 | 1642 |
1733 str->append(")"); | 1643 str->append(")"); |
1734 } | 1644 } |
1735 #endif | 1645 #endif |
OLD | NEW |