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 |