| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2013 Google Inc. | 2 * Copyright 2013 Google Inc. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 #include "SkMipMap.h" | 8 #include "SkMipMap.h" |
| 9 #include "SkBitmap.h" | 9 #include "SkBitmap.h" |
| 10 #include "SkColorPriv.h" | 10 #include "SkColorPriv.h" |
| (...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 176 } | 176 } |
| 177 int64_t size = sk_64_mul(levelCount + 1, sizeof(Level)) + pixelSize; | 177 int64_t size = sk_64_mul(levelCount + 1, sizeof(Level)) + pixelSize; |
| 178 if (!sk_64_isS32(size)) { | 178 if (!sk_64_isS32(size)) { |
| 179 return 0; | 179 return 0; |
| 180 } | 180 } |
| 181 return sk_64_asS32(size); | 181 return sk_64_asS32(size); |
| 182 } | 182 } |
| 183 | 183 |
| 184 typedef void SkDownSampleProc(void*, int x, int y, const void* srcPtr, const SkP
ixmap& srcPM); | 184 typedef void SkDownSampleProc(void*, int x, int y, const void* srcPtr, const SkP
ixmap& srcPM); |
| 185 | 185 |
| 186 SkMipMap* SkMipMap::Build(const SkBitmap& src, SkDiscardableFactoryProc fact) { | 186 SkMipMap* SkMipMap::Build(const SkPixmap& src, SkDiscardableFactoryProc fact) { |
| 187 SkDownSampleProc* proc_nocheck, *proc_check; | 187 SkDownSampleProc* proc_nocheck, *proc_check; |
| 188 | 188 |
| 189 const SkColorType ct = src.colorType(); | 189 const SkColorType ct = src.colorType(); |
| 190 const SkAlphaType at = src.alphaType(); | 190 const SkAlphaType at = src.alphaType(); |
| 191 switch (ct) { | 191 switch (ct) { |
| 192 case kRGBA_8888_SkColorType: | 192 case kRGBA_8888_SkColorType: |
| 193 case kBGRA_8888_SkColorType: | 193 case kBGRA_8888_SkColorType: |
| 194 proc_check = downsample32_check; | 194 proc_check = downsample32_check; |
| 195 proc_nocheck = downsample32_nocheck; | 195 proc_nocheck = downsample32_nocheck; |
| 196 break; | 196 break; |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 229 } | 229 } |
| 230 if (0 == countLevels) { | 230 if (0 == countLevels) { |
| 231 return nullptr; | 231 return nullptr; |
| 232 } | 232 } |
| 233 | 233 |
| 234 size_t storageSize = SkMipMap::AllocLevelsSize(countLevels, size); | 234 size_t storageSize = SkMipMap::AllocLevelsSize(countLevels, size); |
| 235 if (0 == storageSize) { | 235 if (0 == storageSize) { |
| 236 return nullptr; | 236 return nullptr; |
| 237 } | 237 } |
| 238 | 238 |
| 239 SkAutoPixmapUnlock srcUnlocker; | |
| 240 if (!src.requestLock(&srcUnlocker)) { | |
| 241 return nullptr; | |
| 242 } | |
| 243 const SkPixmap& srcPixmap = srcUnlocker.pixmap(); | |
| 244 // Try to catch where we might have returned nullptr for src crbug.com/49281
8 | |
| 245 if (nullptr == srcPixmap.addr()) { | |
| 246 sk_throw(); | |
| 247 } | |
| 248 | |
| 249 SkMipMap* mipmap; | 239 SkMipMap* mipmap; |
| 250 if (fact) { | 240 if (fact) { |
| 251 SkDiscardableMemory* dm = fact(storageSize); | 241 SkDiscardableMemory* dm = fact(storageSize); |
| 252 if (nullptr == dm) { | 242 if (nullptr == dm) { |
| 253 return nullptr; | 243 return nullptr; |
| 254 } | 244 } |
| 255 mipmap = new SkMipMap(storageSize, dm); | 245 mipmap = new SkMipMap(storageSize, dm); |
| 256 } else { | 246 } else { |
| 257 mipmap = new SkMipMap(sk_malloc_throw(storageSize), storageSize); | 247 mipmap = new SkMipMap(sk_malloc_throw(storageSize), storageSize); |
| 258 } | 248 } |
| 259 | 249 |
| 260 // init | 250 // init |
| 261 mipmap->fCount = countLevels; | 251 mipmap->fCount = countLevels; |
| 262 mipmap->fLevels = (Level*)mipmap->writable_data(); | 252 mipmap->fLevels = (Level*)mipmap->writable_data(); |
| 263 | 253 |
| 264 Level* levels = mipmap->fLevels; | 254 Level* levels = mipmap->fLevels; |
| 265 uint8_t* baseAddr = (uint8_t*)&levels[countLevels]; | 255 uint8_t* baseAddr = (uint8_t*)&levels[countLevels]; |
| 266 uint8_t* addr = baseAddr; | 256 uint8_t* addr = baseAddr; |
| 267 int width = src.width(); | 257 int width = src.width(); |
| 268 int height = src.height(); | 258 int height = src.height(); |
| 269 uint32_t rowBytes; | 259 uint32_t rowBytes; |
| 270 SkPixmap srcPM(srcPixmap); | 260 SkPixmap srcPM(src); |
| 271 | 261 |
| 272 for (int i = 0; i < countLevels; ++i) { | 262 for (int i = 0; i < countLevels; ++i) { |
| 273 width >>= 1; | 263 width >>= 1; |
| 274 height >>= 1; | 264 height >>= 1; |
| 275 rowBytes = SkToU32(SkColorTypeMinRowBytes(ct, width)); | 265 rowBytes = SkToU32(SkColorTypeMinRowBytes(ct, width)); |
| 276 | 266 |
| 277 levels[i].fPixels = addr; | 267 levels[i].fPixmap = SkPixmap(SkImageInfo::Make(width, height, ct, at), a
ddr, rowBytes); |
| 278 levels[i].fWidth = width; | |
| 279 levels[i].fHeight = height; | |
| 280 levels[i].fRowBytes = rowBytes; | |
| 281 levels[i].fScale = (float)width / src.width(); | 268 levels[i].fScale = (float)width / src.width(); |
| 282 | 269 |
| 283 SkPixmap dstPM(SkImageInfo::Make(width, height, ct, at), addr, rowBytes)
; | 270 SkPixmap dstPM(SkImageInfo::Make(width, height, ct, at), addr, rowBytes)
; |
| 284 | 271 |
| 285 const int widthEven = width & ~1; | 272 const int widthEven = width & ~1; |
| 286 const int heightEven = height & ~1; | 273 const int heightEven = height & ~1; |
| 287 const size_t pixelSize = srcPM.info().bytesPerPixel(); | 274 const size_t pixelSize = srcPM.info().bytesPerPixel(); |
| 288 | 275 |
| 289 const void* srcBasePtr = srcPM.addr(); | 276 const void* srcBasePtr = srcPM.addr(); |
| 290 void* dstBasePtr = dstPM.writable_addr(); | 277 void* dstBasePtr = dstPM.writable_addr(); |
| (...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 480 if (levelCount < 0) { | 467 if (levelCount < 0) { |
| 481 return 0; | 468 return 0; |
| 482 } | 469 } |
| 483 int64_t size = sk_64_mul(levelCount + 1, sizeof(Level)) + pixelSize; | 470 int64_t size = sk_64_mul(levelCount + 1, sizeof(Level)) + pixelSize; |
| 484 if (!sk_64_isS32(size)) { | 471 if (!sk_64_isS32(size)) { |
| 485 return 0; | 472 return 0; |
| 486 } | 473 } |
| 487 return sk_64_asS32(size); | 474 return sk_64_asS32(size); |
| 488 } | 475 } |
| 489 | 476 |
| 490 SkMipMap* SkMipMap::Build(const SkBitmap& src, SkDiscardableFactoryProc fact) { | 477 SkMipMap* SkMipMap::Build(const SkPixmap& src, SkDiscardableFactoryProc fact) { |
| 491 typedef void FilterProc(void*, const void* srcPtr, size_t srcRB, int count); | 478 typedef void FilterProc(void*, const void* srcPtr, size_t srcRB, int count); |
| 492 | 479 |
| 493 FilterProc* proc_2_2 = nullptr; | 480 FilterProc* proc_2_2 = nullptr; |
| 494 FilterProc* proc_2_3 = nullptr; | 481 FilterProc* proc_2_3 = nullptr; |
| 495 FilterProc* proc_3_2 = nullptr; | 482 FilterProc* proc_3_2 = nullptr; |
| 496 FilterProc* proc_3_3 = nullptr; | 483 FilterProc* proc_3_3 = nullptr; |
| 497 | 484 |
| 498 const SkColorType ct = src.colorType(); | 485 const SkColorType ct = src.colorType(); |
| 499 const SkAlphaType at = src.alphaType(); | 486 const SkAlphaType at = src.alphaType(); |
| 500 switch (ct) { | 487 switch (ct) { |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 548 } | 535 } |
| 549 if (0 == countLevels) { | 536 if (0 == countLevels) { |
| 550 return nullptr; | 537 return nullptr; |
| 551 } | 538 } |
| 552 | 539 |
| 553 size_t storageSize = SkMipMap::AllocLevelsSize(countLevels, size); | 540 size_t storageSize = SkMipMap::AllocLevelsSize(countLevels, size); |
| 554 if (0 == storageSize) { | 541 if (0 == storageSize) { |
| 555 return nullptr; | 542 return nullptr; |
| 556 } | 543 } |
| 557 | 544 |
| 558 SkAutoPixmapUnlock srcUnlocker; | |
| 559 if (!src.requestLock(&srcUnlocker)) { | |
| 560 return nullptr; | |
| 561 } | |
| 562 const SkPixmap& srcPixmap = srcUnlocker.pixmap(); | |
| 563 // Try to catch where we might have returned nullptr for src crbug.com/49281
8 | |
| 564 if (nullptr == srcPixmap.addr()) { | |
| 565 sk_throw(); | |
| 566 } | |
| 567 | |
| 568 SkMipMap* mipmap; | 545 SkMipMap* mipmap; |
| 569 if (fact) { | 546 if (fact) { |
| 570 SkDiscardableMemory* dm = fact(storageSize); | 547 SkDiscardableMemory* dm = fact(storageSize); |
| 571 if (nullptr == dm) { | 548 if (nullptr == dm) { |
| 572 return nullptr; | 549 return nullptr; |
| 573 } | 550 } |
| 574 mipmap = new SkMipMap(storageSize, dm); | 551 mipmap = new SkMipMap(storageSize, dm); |
| 575 } else { | 552 } else { |
| 576 mipmap = new SkMipMap(sk_malloc_throw(storageSize), storageSize); | 553 mipmap = new SkMipMap(sk_malloc_throw(storageSize), storageSize); |
| 577 } | 554 } |
| 578 | 555 |
| 579 // init | 556 // init |
| 580 mipmap->fCount = countLevels; | 557 mipmap->fCount = countLevels; |
| 581 mipmap->fLevels = (Level*)mipmap->writable_data(); | 558 mipmap->fLevels = (Level*)mipmap->writable_data(); |
| 582 | 559 |
| 583 Level* levels = mipmap->fLevels; | 560 Level* levels = mipmap->fLevels; |
| 584 uint8_t* baseAddr = (uint8_t*)&levels[countLevels]; | 561 uint8_t* baseAddr = (uint8_t*)&levels[countLevels]; |
| 585 uint8_t* addr = baseAddr; | 562 uint8_t* addr = baseAddr; |
| 586 int width = src.width(); | 563 int width = src.width(); |
| 587 int height = src.height(); | 564 int height = src.height(); |
| 588 uint32_t rowBytes; | 565 uint32_t rowBytes; |
| 589 SkPixmap srcPM(srcPixmap); | 566 SkPixmap srcPM(src); |
| 590 | 567 |
| 591 for (int i = 0; i < countLevels; ++i) { | 568 for (int i = 0; i < countLevels; ++i) { |
| 592 FilterProc* proc; | 569 FilterProc* proc; |
| 593 if (height & 1) { // src-height is 3 | 570 if (height & 1) { // src-height is 3 |
| 594 if (width & 1) { // src-width is 3 | 571 if (width & 1) { // src-width is 3 |
| 595 proc = proc_3_3; | 572 proc = proc_3_3; |
| 596 } else { // src-width is 2 | 573 } else { // src-width is 2 |
| 597 proc = proc_2_3; | 574 proc = proc_2_3; |
| 598 } | 575 } |
| 599 } else { // src-height is 2 | 576 } else { // src-height is 2 |
| 600 if (width & 1) { // src-width is 3 | 577 if (width & 1) { // src-width is 3 |
| 601 proc = proc_3_2; | 578 proc = proc_3_2; |
| 602 } else { // src-width is 2 | 579 } else { // src-width is 2 |
| 603 proc = proc_2_2; | 580 proc = proc_2_2; |
| 604 } | 581 } |
| 605 } | 582 } |
| 606 width >>= 1; | 583 width >>= 1; |
| 607 height >>= 1; | 584 height >>= 1; |
| 608 rowBytes = SkToU32(SkColorTypeMinRowBytes(ct, width)); | 585 rowBytes = SkToU32(SkColorTypeMinRowBytes(ct, width)); |
| 609 | 586 |
| 610 levels[i].fPixels = addr; | 587 levels[i].fPixmap = SkPixmap(SkImageInfo::Make(width, height, ct, at), a
ddr, rowBytes); |
| 611 levels[i].fWidth = width; | 588 levels[i].fScale = (float)width / src.width(); |
| 612 levels[i].fHeight = height; | |
| 613 levels[i].fRowBytes = rowBytes; | |
| 614 levels[i].fScale = (float)width / src.width(); | |
| 615 | 589 |
| 616 SkPixmap dstPM(SkImageInfo::Make(width, height, ct, at), addr, rowBytes)
; | 590 const SkPixmap& dstPM = levels[i].fPixmap; |
| 617 | |
| 618 const void* srcBasePtr = srcPM.addr(); | 591 const void* srcBasePtr = srcPM.addr(); |
| 619 void* dstBasePtr = dstPM.writable_addr(); | 592 void* dstBasePtr = dstPM.writable_addr(); |
| 620 | 593 |
| 621 const size_t srcRB = srcPM.rowBytes(); | 594 const size_t srcRB = srcPM.rowBytes(); |
| 622 for (int y = 0; y < height; y++) { | 595 for (int y = 0; y < height; y++) { |
| 623 proc(dstBasePtr, srcBasePtr, srcRB, width); | 596 proc(dstBasePtr, srcBasePtr, srcRB, width); |
| 624 srcBasePtr = (char*)srcBasePtr + srcRB * 2; // jump two rows | 597 srcBasePtr = (char*)srcBasePtr + srcRB * 2; // jump two rows |
| 625 dstBasePtr = (char*)dstBasePtr + dstPM.rowBytes(); | 598 dstBasePtr = (char*)dstBasePtr + dstPM.rowBytes(); |
| 626 } | 599 } |
| 627 srcPM = dstPM; | 600 srcPM = dstPM; |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 659 } | 632 } |
| 660 | 633 |
| 661 if (level > fCount) { | 634 if (level > fCount) { |
| 662 level = fCount; | 635 level = fCount; |
| 663 } | 636 } |
| 664 if (levelPtr) { | 637 if (levelPtr) { |
| 665 *levelPtr = fLevels[level - 1]; | 638 *levelPtr = fLevels[level - 1]; |
| 666 } | 639 } |
| 667 return true; | 640 return true; |
| 668 } | 641 } |
| 642 |
| 643 // Helper which extacts a pixmap from the src bitmap |
| 644 // |
| 645 SkMipMap* SkMipMap::Build(const SkBitmap& src, SkDiscardableFactoryProc fact) { |
| 646 SkAutoPixmapUnlock srcUnlocker; |
| 647 if (!src.requestLock(&srcUnlocker)) { |
| 648 return nullptr; |
| 649 } |
| 650 const SkPixmap& srcPixmap = srcUnlocker.pixmap(); |
| 651 // Try to catch where we might have returned nullptr for src crbug.com/49281
8 |
| 652 if (nullptr == srcPixmap.addr()) { |
| 653 sk_throw(); |
| 654 } |
| 655 return Build(srcPixmap, fact); |
| 656 } |
| 657 |
| OLD | NEW |