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

Side by Side Diff: dm/DMSrcSink.cpp

Issue 1907593004: Support the non-native (RGBA/BGRA) swizzle (Closed) Base URL: https://skia.googlesource.com/skia.git@tryagain
Patch Set: Rebase Created 4 years, 8 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
OLDNEW
1 /* 1 /*
2 * Copyright 2015 Google Inc. 2 * Copyright 2015 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 "DMSrcSink.h" 8 #include "DMSrcSink.h"
9 #include "SkAndroidCodec.h" 9 #include "SkAndroidCodec.h"
10 #include "SkCodec.h" 10 #include "SkCodec.h"
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
103 } 103 }
104 switch (fDstColorType) { 104 switch (fDstColorType) {
105 case CodecSrc::kGetFromCanvas_DstColorType: 105 case CodecSrc::kGetFromCanvas_DstColorType:
106 break; 106 break;
107 case CodecSrc::kIndex8_Always_DstColorType: 107 case CodecSrc::kIndex8_Always_DstColorType:
108 colorType = kIndex_8_SkColorType; 108 colorType = kIndex_8_SkColorType;
109 break; 109 break;
110 case CodecSrc::kGrayscale_Always_DstColorType: 110 case CodecSrc::kGrayscale_Always_DstColorType:
111 colorType = kGray_8_SkColorType; 111 colorType = kGray_8_SkColorType;
112 break; 112 break;
113 default:
scroggo 2016/04/22 20:12:32 Why is this necessary?
msarett 2016/04/22 20:25:23 We're not testing kNonNative mode for BRD, but now
114 SkASSERT(false);
115 break;
113 } 116 }
114 117
115 SkAutoTDelete<SkBitmapRegionDecoder> brd(create_brd(fPath, fStrategy)); 118 SkAutoTDelete<SkBitmapRegionDecoder> brd(create_brd(fPath, fStrategy));
116 if (nullptr == brd.get()) { 119 if (nullptr == brd.get()) {
117 return Error::Nonfatal(SkStringPrintf("Could not create brd for %s.", fP ath.c_str())); 120 return Error::Nonfatal(SkStringPrintf("Could not create brd for %s.", fP ath.c_str()));
118 } 121 }
119 122
120 if (!brd->conversionSupported(colorType)) { 123 if (!brd->conversionSupported(colorType)) {
121 return Error::Nonfatal("Cannot convert to color type."); 124 return Error::Nonfatal("Cannot convert to color type.");
122 } 125 }
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
264 , fDstAlphaType(dstAlphaType) 267 , fDstAlphaType(dstAlphaType)
265 , fScale(scale) 268 , fScale(scale)
266 , fRunSerially(serial_from_path_name(path)) 269 , fRunSerially(serial_from_path_name(path))
267 {} 270 {}
268 271
269 bool CodecSrc::veto(SinkFlags flags) const { 272 bool CodecSrc::veto(SinkFlags flags) const {
270 // Test to direct raster backends (8888 and 565). 273 // Test to direct raster backends (8888 and 565).
271 return flags.type != SinkFlags::kRaster || flags.approach != SinkFlags::kDir ect; 274 return flags.type != SinkFlags::kRaster || flags.approach != SinkFlags::kDir ect;
272 } 275 }
273 276
277 // Allows us to test decodes to non-native 8888.
278 void swap_rb_if_necessary(SkBitmap& bitmap, CodecSrc::DstColorType dstColorType) {
279 if (CodecSrc::kNonNative8888_Always_DstColorType != dstColorType) {
280 return;
281 }
282
283 for (int y = 0; y < bitmap.height(); y++) {
284 uint32_t* row = (uint32_t*) bitmap.getAddr(0, y);
285 SkOpts::RGBA_to_BGRA(row, row, bitmap.width());
286 }
287 }
288
274 // FIXME: Currently we cannot draw unpremultiplied sources. skbug.com/3338 and s kbug.com/3339. 289 // FIXME: Currently we cannot draw unpremultiplied sources. skbug.com/3338 and s kbug.com/3339.
275 // This allows us to still test unpremultiplied decodes. 290 // This allows us to still test unpremultiplied decodes.
276 void premultiply_if_necessary(SkBitmap& bitmap) { 291 void premultiply_if_necessary(SkBitmap& bitmap) {
277 if (kUnpremul_SkAlphaType != bitmap.alphaType()) { 292 if (kUnpremul_SkAlphaType != bitmap.alphaType()) {
278 return; 293 return;
279 } 294 }
280 295
281 switch (bitmap.colorType()) { 296 switch (bitmap.colorType()) {
282 case kN32_SkColorType: 297 case kN32_SkColorType:
283 for (int y = 0; y < bitmap.height(); y++) { 298 for (int y = 0; y < bitmap.height(); y++) {
(...skipping 26 matching lines...) Expand all
310 } 325 }
311 *decodeInfo = decodeInfo->makeColorType(kIndex_8_SkColorType); 326 *decodeInfo = decodeInfo->makeColorType(kIndex_8_SkColorType);
312 break; 327 break;
313 case CodecSrc::kGrayscale_Always_DstColorType: 328 case CodecSrc::kGrayscale_Always_DstColorType:
314 if (kRGB_565_SkColorType == canvasColorType || 329 if (kRGB_565_SkColorType == canvasColorType ||
315 kOpaque_SkAlphaType != decodeInfo->alphaType()) { 330 kOpaque_SkAlphaType != decodeInfo->alphaType()) {
316 return false; 331 return false;
317 } 332 }
318 *decodeInfo = decodeInfo->makeColorType(kGray_8_SkColorType); 333 *decodeInfo = decodeInfo->makeColorType(kGray_8_SkColorType);
319 break; 334 break;
335 case CodecSrc::kNonNative8888_Always_DstColorType:
336 #ifdef SK_PMCOLOR_IS_RGBA
337 *decodeInfo = decodeInfo->makeColorType(kBGRA_8888_SkColorType);
338 #else
339 *decodeInfo = decodeInfo->makeColorType(kRGBA_8888_SkColorType);
340 #endif
341 break;
320 default: 342 default:
321 if (kRGB_565_SkColorType == canvasColorType && 343 if (kRGB_565_SkColorType == canvasColorType &&
322 kOpaque_SkAlphaType != decodeInfo->alphaType()) { 344 kOpaque_SkAlphaType != decodeInfo->alphaType()) {
323 return false; 345 return false;
324 } 346 }
325 *decodeInfo = decodeInfo->makeColorType(canvasColorType); 347 *decodeInfo = decodeInfo->makeColorType(canvasColorType);
326 break; 348 break;
327 } 349 }
328 350
329 return true; 351 return true;
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
371 } 393 }
372 394
373 SkBitmap bitmap; 395 SkBitmap bitmap;
374 SkPixelRefFactory* factory = nullptr; 396 SkPixelRefFactory* factory = nullptr;
375 SkMallocPixelRef::ZeroedPRFactory zeroFactory; 397 SkMallocPixelRef::ZeroedPRFactory zeroFactory;
376 SkCodec::Options options; 398 SkCodec::Options options;
377 if (kCodecZeroInit_Mode == fMode) { 399 if (kCodecZeroInit_Mode == fMode) {
378 factory = &zeroFactory; 400 factory = &zeroFactory;
379 options.fZeroInitialized = SkCodec::kYes_ZeroInitialized; 401 options.fZeroInitialized = SkCodec::kYes_ZeroInitialized;
380 } 402 }
381 if (!bitmap.tryAllocPixels(decodeInfo, factory, colorTable.get())) { 403
404 SkImageInfo bitmapInfo = decodeInfo;
405 if (kRGBA_8888_SkColorType == decodeInfo.colorType() ||
406 kBGRA_8888_SkColorType == decodeInfo.colorType()) {
407 bitmapInfo = bitmapInfo.makeColorType(kN32_SkColorType);
408 }
409 if (!bitmap.tryAllocPixels(bitmapInfo, factory, colorTable.get())) {
382 return SkStringPrintf("Image(%s) is too large (%d x %d)", fPath.c_str(), 410 return SkStringPrintf("Image(%s) is too large (%d x %d)", fPath.c_str(),
383 decodeInfo.width(), decodeInfo.height()); 411 decodeInfo.width(), decodeInfo.height());
384 } 412 }
385 413
386 switch (fMode) { 414 switch (fMode) {
387 case kCodecZeroInit_Mode: 415 case kCodecZeroInit_Mode:
388 case kCodec_Mode: { 416 case kCodec_Mode: {
389 switch (codec->getPixels(decodeInfo, bitmap.getPixels(), bitmap.rowB ytes(), &options, 417 switch (codec->getPixels(decodeInfo, bitmap.getPixels(), bitmap.rowB ytes(), &options,
390 colorPtr, colorCountPtr)) { 418 colorPtr, colorCountPtr)) {
391 case SkCodec::kSuccess: 419 case SkCodec::kSuccess:
392 // We consider incomplete to be valid, since we should still decode what is 420 // We consider incomplete to be valid, since we should still decode what is
393 // available. 421 // available.
394 case SkCodec::kIncompleteInput: 422 case SkCodec::kIncompleteInput:
395 break; 423 break;
396 default: 424 default:
397 // Everything else is considered a failure. 425 // Everything else is considered a failure.
398 return SkStringPrintf("Couldn't getPixels %s.", fPath.c_str( )); 426 return SkStringPrintf("Couldn't getPixels %s.", fPath.c_str( ));
399 } 427 }
400 premultiply_if_necessary(bitmap); 428 premultiply_if_necessary(bitmap);
429 swap_rb_if_necessary(bitmap, fDstColorType);
401 canvas->drawBitmap(bitmap, 0, 0); 430 canvas->drawBitmap(bitmap, 0, 0);
402 break; 431 break;
403 } 432 }
404 case kScanline_Mode: { 433 case kScanline_Mode: {
405 if (SkCodec::kSuccess != codec->startScanlineDecode(decodeInfo, NULL , colorPtr, 434 if (SkCodec::kSuccess != codec->startScanlineDecode(decodeInfo, NULL , colorPtr,
406 colorCountPtr)) { 435 colorCountPtr)) {
407 return "Could not start scanline decoder"; 436 return "Could not start scanline decoder";
408 } 437 }
409 438
410 void* dst = bitmap.getAddr(0, 0); 439 void* dst = bitmap.getAddr(0, 0);
(...skipping 14 matching lines...) Expand all
425 // We complete the loop, even if this call begins to fai l 454 // We complete the loop, even if this call begins to fai l
426 // due to an incomplete image. This ensures any uniniti alized 455 // due to an incomplete image. This ensures any uniniti alized
427 // memory will be filled with the proper value. 456 // memory will be filled with the proper value.
428 codec->getScanlines(dstPtr, 1, bitmap.rowBytes()); 457 codec->getScanlines(dstPtr, 1, bitmap.rowBytes());
429 } 458 }
430 break; 459 break;
431 } 460 }
432 } 461 }
433 462
434 premultiply_if_necessary(bitmap); 463 premultiply_if_necessary(bitmap);
464 swap_rb_if_necessary(bitmap, fDstColorType);
435 canvas->drawBitmap(bitmap, 0, 0); 465 canvas->drawBitmap(bitmap, 0, 0);
436 break; 466 break;
437 } 467 }
438 case kStripe_Mode: { 468 case kStripe_Mode: {
439 const int height = decodeInfo.height(); 469 const int height = decodeInfo.height();
440 // This value is chosen arbitrarily. We exercise more cases by choo sing a value that 470 // This value is chosen arbitrarily. We exercise more cases by choo sing a value that
441 // does not align with image blocks. 471 // does not align with image blocks.
442 const int stripeHeight = 37; 472 const int stripeHeight = 37;
443 const int numStripes = (height + stripeHeight - 1) / stripeHeight; 473 const int numStripes = (height + stripeHeight - 1) / stripeHeight;
444 474
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
480 const int linesToRead = SkTMin(stripeHeight, height - startY); 510 const int linesToRead = SkTMin(stripeHeight, height - startY);
481 codec->getScanlines(bitmap.getAddr(0, startY), linesToRead, bitm ap.rowBytes()); 511 codec->getScanlines(bitmap.getAddr(0, startY), linesToRead, bitm ap.rowBytes());
482 512
483 // Skip a stripe 513 // Skip a stripe
484 const int linesToSkip = SkTMin(stripeHeight, height - (i + 1) * stripeHeight); 514 const int linesToSkip = SkTMin(stripeHeight, height - (i + 1) * stripeHeight);
485 if (linesToSkip > 0) { 515 if (linesToSkip > 0) {
486 codec->skipScanlines(linesToSkip); 516 codec->skipScanlines(linesToSkip);
487 } 517 }
488 } 518 }
489 premultiply_if_necessary(bitmap); 519 premultiply_if_necessary(bitmap);
520 swap_rb_if_necessary(bitmap, fDstColorType);
490 canvas->drawBitmap(bitmap, 0, 0); 521 canvas->drawBitmap(bitmap, 0, 0);
491 break; 522 break;
492 } 523 }
493 case kCroppedScanline_Mode: { 524 case kCroppedScanline_Mode: {
494 const int width = decodeInfo.width(); 525 const int width = decodeInfo.width();
495 const int height = decodeInfo.height(); 526 const int height = decodeInfo.height();
496 // This value is chosen because, as we move across the image, it wil l sometimes 527 // This value is chosen because, as we move across the image, it wil l sometimes
497 // align with the jpeg block sizes and it will sometimes not. This allows us 528 // align with the jpeg block sizes and it will sometimes not. This allows us
498 // to test interestingly different code paths in the implementation. 529 // to test interestingly different code paths in the implementation.
499 const int tileSize = 36; 530 const int tileSize = 36;
500 531
501 SkCodec::Options opts; 532 SkCodec::Options opts;
502 SkIRect subset; 533 SkIRect subset;
503 for (int x = 0; x < width; x += tileSize) { 534 for (int x = 0; x < width; x += tileSize) {
504 subset = SkIRect::MakeXYWH(x, 0, SkTMin(tileSize, width - x), he ight); 535 subset = SkIRect::MakeXYWH(x, 0, SkTMin(tileSize, width - x), he ight);
505 opts.fSubset = &subset; 536 opts.fSubset = &subset;
506 if (SkCodec::kSuccess != codec->startScanlineDecode(decodeInfo, &opts, 537 if (SkCodec::kSuccess != codec->startScanlineDecode(decodeInfo, &opts,
507 colorPtr, colorCountPtr)) { 538 colorPtr, colorCountPtr)) {
508 return "Could not start scanline decoder."; 539 return "Could not start scanline decoder.";
509 } 540 }
510 541
511 codec->getScanlines(bitmap.getAddr(x, 0), height, bitmap.rowByte s()); 542 codec->getScanlines(bitmap.getAddr(x, 0), height, bitmap.rowByte s());
512 } 543 }
513 544
514 premultiply_if_necessary(bitmap); 545 premultiply_if_necessary(bitmap);
546 swap_rb_if_necessary(bitmap, fDstColorType);
515 canvas->drawBitmap(bitmap, 0, 0); 547 canvas->drawBitmap(bitmap, 0, 0);
516 break; 548 break;
517 } 549 }
518 case kSubset_Mode: { 550 case kSubset_Mode: {
519 // Arbitrarily choose a divisor. 551 // Arbitrarily choose a divisor.
520 int divisor = 2; 552 int divisor = 2;
521 // Total width/height of the image. 553 // Total width/height of the image.
522 const int W = codec->getInfo().width(); 554 const int W = codec->getInfo().width();
523 const int H = codec->getInfo().height(); 555 const int H = codec->getInfo().height();
524 if (divisor > W || divisor > H) { 556 if (divisor > W || divisor > H) {
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
564 case SkCodec::kSuccess: 596 case SkCodec::kSuccess:
565 case SkCodec::kIncompleteInput: 597 case SkCodec::kIncompleteInput:
566 break; 598 break;
567 default: 599 default:
568 return SkStringPrintf("subset codec failed to decode (%d, %d, %d, %d) " 600 return SkStringPrintf("subset codec failed to decode (%d, %d, %d, %d) "
569 "from %s with dimensions (%d x %d)\t error %d", 601 "from %s with dimensions (%d x %d)\t error %d",
570 x, y, decodeInfo.width(), deco deInfo.height(), 602 x, y, decodeInfo.width(), deco deInfo.height(),
571 fPath.c_str(), W, H, result); 603 fPath.c_str(), W, H, result);
572 } 604 }
573 premultiply_if_necessary(subsetBm); 605 premultiply_if_necessary(subsetBm);
606 swap_rb_if_necessary(bitmap, fDstColorType);
574 canvas->drawBitmap(subsetBm, SkIntToScalar(left), SkIntToSca lar(top)); 607 canvas->drawBitmap(subsetBm, SkIntToScalar(left), SkIntToSca lar(top));
575 // translate by the scaled height. 608 // translate by the scaled height.
576 top += decodeInfo.height(); 609 top += decodeInfo.height();
577 } 610 }
578 // translate by the scaled width. 611 // translate by the scaled width.
579 left += decodeInfo.width(); 612 left += decodeInfo.width();
580 } 613 }
581 return ""; 614 return "";
582 } 615 }
583 default: 616 default:
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
652 int* colorCountPtr = nullptr; 685 int* colorCountPtr = nullptr;
653 int maxColors = 256; 686 int maxColors = 256;
654 if (kIndex_8_SkColorType == decodeInfo.colorType()) { 687 if (kIndex_8_SkColorType == decodeInfo.colorType()) {
655 SkPMColor colors[256]; 688 SkPMColor colors[256];
656 colorTable.reset(new SkColorTable(colors, maxColors)); 689 colorTable.reset(new SkColorTable(colors, maxColors));
657 colorPtr = const_cast<SkPMColor*>(colorTable->readColors()); 690 colorPtr = const_cast<SkPMColor*>(colorTable->readColors());
658 colorCountPtr = &maxColors; 691 colorCountPtr = &maxColors;
659 } 692 }
660 693
661 SkBitmap bitmap; 694 SkBitmap bitmap;
662 if (!bitmap.tryAllocPixels(decodeInfo, nullptr, colorTable.get())) { 695 SkImageInfo bitmapInfo = decodeInfo;
696 if (kRGBA_8888_SkColorType == decodeInfo.colorType() ||
697 kBGRA_8888_SkColorType == decodeInfo.colorType()) {
698 bitmapInfo = bitmapInfo.makeColorType(kN32_SkColorType);
699 }
700 if (!bitmap.tryAllocPixels(bitmapInfo, nullptr, colorTable.get())) {
663 return SkStringPrintf("Image(%s) is too large (%d x %d)", fPath.c_str(), 701 return SkStringPrintf("Image(%s) is too large (%d x %d)", fPath.c_str(),
664 decodeInfo.width(), decodeInfo.height()); 702 decodeInfo.width(), decodeInfo.height());
665 } 703 }
666 704
667 // Create options for the codec. 705 // Create options for the codec.
668 SkAndroidCodec::AndroidOptions options; 706 SkAndroidCodec::AndroidOptions options;
669 options.fColorPtr = colorPtr; 707 options.fColorPtr = colorPtr;
670 options.fColorCount = colorCountPtr; 708 options.fColorCount = colorCountPtr;
671 options.fSampleSize = fSampleSize; 709 options.fSampleSize = fSampleSize;
672 710
673 switch (fMode) { 711 switch (fMode) {
674 case kFullImage_Mode: { 712 case kFullImage_Mode: {
675 switch (codec->getAndroidPixels(decodeInfo, bitmap.getPixels(), bitm ap.rowBytes(), 713 switch (codec->getAndroidPixels(decodeInfo, bitmap.getPixels(), bitm ap.rowBytes(),
676 &options)) { 714 &options)) {
677 case SkCodec::kSuccess: 715 case SkCodec::kSuccess:
678 case SkCodec::kIncompleteInput: 716 case SkCodec::kIncompleteInput:
679 break; 717 break;
680 default: 718 default:
681 return SkStringPrintf("Couldn't getPixels %s.", fPath.c_str( )); 719 return SkStringPrintf("Couldn't getPixels %s.", fPath.c_str( ));
682 } 720 }
683 premultiply_if_necessary(bitmap); 721 premultiply_if_necessary(bitmap);
722 swap_rb_if_necessary(bitmap, fDstColorType);
684 canvas->drawBitmap(bitmap, 0, 0); 723 canvas->drawBitmap(bitmap, 0, 0);
685 return ""; 724 return "";
686 } 725 }
687 case kDivisor_Mode: { 726 case kDivisor_Mode: {
688 const int width = codec->getInfo().width(); 727 const int width = codec->getInfo().width();
689 const int height = codec->getInfo().height(); 728 const int height = codec->getInfo().height();
690 const int divisor = 2; 729 const int divisor = 2;
691 if (width < divisor || height < divisor) { 730 if (width < divisor || height < divisor) {
692 return Error::Nonfatal("Divisor is larger than image dimension." ); 731 return Error::Nonfatal("Divisor is larger than image dimension." );
693 } 732 }
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
732 break; 771 break;
733 default: 772 default:
734 return SkStringPrintf("Couldn't getPixels %s.", fPat h.c_str()); 773 return SkStringPrintf("Couldn't getPixels %s.", fPat h.c_str());
735 } 774 }
736 } 775 }
737 } 776 }
738 777
739 SkRect rect = SkRect::MakeXYWH(0, 0, (SkScalar) finalScaledWidth, 778 SkRect rect = SkRect::MakeXYWH(0, 0, (SkScalar) finalScaledWidth,
740 (SkScalar) finalScaledHeight); 779 (SkScalar) finalScaledHeight);
741 premultiply_if_necessary(bitmap); 780 premultiply_if_necessary(bitmap);
781 swap_rb_if_necessary(bitmap, fDstColorType);
742 canvas->drawBitmapRect(bitmap, rect, rect, nullptr); 782 canvas->drawBitmapRect(bitmap, rect, rect, nullptr);
743 return ""; 783 return "";
744 } 784 }
745 default: 785 default:
746 SkASSERT(false); 786 SkASSERT(false);
747 return "Error: Should not be reached."; 787 return "Error: Should not be reached.";
748 } 788 }
749 } 789 }
750 790
751 SkISize AndroidCodecSrc::size() const { 791 SkISize AndroidCodecSrc::size() const {
(...skipping 703 matching lines...) Expand 10 before | Expand all | Expand 10 after
1455 skr.visit(i, drawsAsSingletonPictures); 1495 skr.visit(i, drawsAsSingletonPictures);
1456 } 1496 }
1457 sk_sp<SkPicture> macroPic(macroRec.finishRecordingAsPicture()); 1497 sk_sp<SkPicture> macroPic(macroRec.finishRecordingAsPicture());
1458 1498
1459 canvas->drawPicture(macroPic); 1499 canvas->drawPicture(macroPic);
1460 return check_against_reference(bitmap, src, fSink); 1500 return check_against_reference(bitmap, src, fSink);
1461 }); 1501 });
1462 } 1502 }
1463 1503
1464 } // namespace DM 1504 } // namespace DM
OLDNEW
« no previous file with comments | « dm/DMSrcSink.h ('k') | src/codec/SkBmpRLECodec.h » ('j') | src/codec/SkBmpStandardCodec.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698