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

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: Multiple bug fixes 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
« no previous file with comments | « dm/DMSrcSink.h ('k') | src/codec/SkBmpRLECodec.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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:
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 if (kRGB_565_SkColorType == canvasColorType) {
337 return false;
338 }
339 #ifdef SK_PMCOLOR_IS_RGBA
340 *decodeInfo = decodeInfo->makeColorType(kBGRA_8888_SkColorType);
341 #else
342 *decodeInfo = decodeInfo->makeColorType(kRGBA_8888_SkColorType);
343 #endif
344 break;
320 default: 345 default:
321 if (kRGB_565_SkColorType == canvasColorType && 346 if (kRGB_565_SkColorType == canvasColorType &&
322 kOpaque_SkAlphaType != decodeInfo->alphaType()) { 347 kOpaque_SkAlphaType != decodeInfo->alphaType()) {
323 return false; 348 return false;
324 } 349 }
325 *decodeInfo = decodeInfo->makeColorType(canvasColorType); 350 *decodeInfo = decodeInfo->makeColorType(canvasColorType);
326 break; 351 break;
327 } 352 }
328 353
329 return true; 354 return true;
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
371 } 396 }
372 397
373 SkBitmap bitmap; 398 SkBitmap bitmap;
374 SkPixelRefFactory* factory = nullptr; 399 SkPixelRefFactory* factory = nullptr;
375 SkMallocPixelRef::ZeroedPRFactory zeroFactory; 400 SkMallocPixelRef::ZeroedPRFactory zeroFactory;
376 SkCodec::Options options; 401 SkCodec::Options options;
377 if (kCodecZeroInit_Mode == fMode) { 402 if (kCodecZeroInit_Mode == fMode) {
378 factory = &zeroFactory; 403 factory = &zeroFactory;
379 options.fZeroInitialized = SkCodec::kYes_ZeroInitialized; 404 options.fZeroInitialized = SkCodec::kYes_ZeroInitialized;
380 } 405 }
381 if (!bitmap.tryAllocPixels(decodeInfo, factory, colorTable.get())) { 406
407 SkImageInfo bitmapInfo = decodeInfo;
408 if (kRGBA_8888_SkColorType == decodeInfo.colorType() ||
409 kBGRA_8888_SkColorType == decodeInfo.colorType()) {
410 bitmapInfo = bitmapInfo.makeColorType(kN32_SkColorType);
411 }
412 if (!bitmap.tryAllocPixels(bitmapInfo, factory, colorTable.get())) {
382 return SkStringPrintf("Image(%s) is too large (%d x %d)", fPath.c_str(), 413 return SkStringPrintf("Image(%s) is too large (%d x %d)", fPath.c_str(),
383 decodeInfo.width(), decodeInfo.height()); 414 decodeInfo.width(), decodeInfo.height());
384 } 415 }
385 416
386 switch (fMode) { 417 switch (fMode) {
387 case kCodecZeroInit_Mode: 418 case kCodecZeroInit_Mode:
388 case kCodec_Mode: { 419 case kCodec_Mode: {
389 switch (codec->getPixels(decodeInfo, bitmap.getPixels(), bitmap.rowB ytes(), &options, 420 switch (codec->getPixels(decodeInfo, bitmap.getPixels(), bitmap.rowB ytes(), &options,
390 colorPtr, colorCountPtr)) { 421 colorPtr, colorCountPtr)) {
391 case SkCodec::kSuccess: 422 case SkCodec::kSuccess:
392 // We consider incomplete to be valid, since we should still decode what is 423 // We consider incomplete to be valid, since we should still decode what is
393 // available. 424 // available.
394 case SkCodec::kIncompleteInput: 425 case SkCodec::kIncompleteInput:
395 break; 426 break;
396 default: 427 default:
397 // Everything else is considered a failure. 428 // Everything else is considered a failure.
398 return SkStringPrintf("Couldn't getPixels %s.", fPath.c_str( )); 429 return SkStringPrintf("Couldn't getPixels %s.", fPath.c_str( ));
399 } 430 }
400 premultiply_if_necessary(bitmap); 431 premultiply_if_necessary(bitmap);
432 swap_rb_if_necessary(bitmap, fDstColorType);
401 canvas->drawBitmap(bitmap, 0, 0); 433 canvas->drawBitmap(bitmap, 0, 0);
402 break; 434 break;
403 } 435 }
404 case kScanline_Mode: { 436 case kScanline_Mode: {
405 if (SkCodec::kSuccess != codec->startScanlineDecode(decodeInfo, NULL , colorPtr, 437 if (SkCodec::kSuccess != codec->startScanlineDecode(decodeInfo, NULL , colorPtr,
406 colorCountPtr)) { 438 colorCountPtr)) {
407 return "Could not start scanline decoder"; 439 return "Could not start scanline decoder";
408 } 440 }
409 441
410 void* dst = bitmap.getAddr(0, 0); 442 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 457 // We complete the loop, even if this call begins to fai l
426 // due to an incomplete image. This ensures any uniniti alized 458 // due to an incomplete image. This ensures any uniniti alized
427 // memory will be filled with the proper value. 459 // memory will be filled with the proper value.
428 codec->getScanlines(dstPtr, 1, bitmap.rowBytes()); 460 codec->getScanlines(dstPtr, 1, bitmap.rowBytes());
429 } 461 }
430 break; 462 break;
431 } 463 }
432 } 464 }
433 465
434 premultiply_if_necessary(bitmap); 466 premultiply_if_necessary(bitmap);
467 swap_rb_if_necessary(bitmap, fDstColorType);
435 canvas->drawBitmap(bitmap, 0, 0); 468 canvas->drawBitmap(bitmap, 0, 0);
436 break; 469 break;
437 } 470 }
438 case kStripe_Mode: { 471 case kStripe_Mode: {
439 const int height = decodeInfo.height(); 472 const int height = decodeInfo.height();
440 // This value is chosen arbitrarily. We exercise more cases by choo sing a value that 473 // This value is chosen arbitrarily. We exercise more cases by choo sing a value that
441 // does not align with image blocks. 474 // does not align with image blocks.
442 const int stripeHeight = 37; 475 const int stripeHeight = 37;
443 const int numStripes = (height + stripeHeight - 1) / stripeHeight; 476 const int numStripes = (height + stripeHeight - 1) / stripeHeight;
444 477
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
480 const int linesToRead = SkTMin(stripeHeight, height - startY); 513 const int linesToRead = SkTMin(stripeHeight, height - startY);
481 codec->getScanlines(bitmap.getAddr(0, startY), linesToRead, bitm ap.rowBytes()); 514 codec->getScanlines(bitmap.getAddr(0, startY), linesToRead, bitm ap.rowBytes());
482 515
483 // Skip a stripe 516 // Skip a stripe
484 const int linesToSkip = SkTMin(stripeHeight, height - (i + 1) * stripeHeight); 517 const int linesToSkip = SkTMin(stripeHeight, height - (i + 1) * stripeHeight);
485 if (linesToSkip > 0) { 518 if (linesToSkip > 0) {
486 codec->skipScanlines(linesToSkip); 519 codec->skipScanlines(linesToSkip);
487 } 520 }
488 } 521 }
489 premultiply_if_necessary(bitmap); 522 premultiply_if_necessary(bitmap);
523 swap_rb_if_necessary(bitmap, fDstColorType);
490 canvas->drawBitmap(bitmap, 0, 0); 524 canvas->drawBitmap(bitmap, 0, 0);
491 break; 525 break;
492 } 526 }
493 case kCroppedScanline_Mode: { 527 case kCroppedScanline_Mode: {
494 const int width = decodeInfo.width(); 528 const int width = decodeInfo.width();
495 const int height = decodeInfo.height(); 529 const int height = decodeInfo.height();
496 // This value is chosen because, as we move across the image, it wil l sometimes 530 // 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 531 // align with the jpeg block sizes and it will sometimes not. This allows us
498 // to test interestingly different code paths in the implementation. 532 // to test interestingly different code paths in the implementation.
499 const int tileSize = 36; 533 const int tileSize = 36;
500 534
501 SkCodec::Options opts; 535 SkCodec::Options opts;
502 SkIRect subset; 536 SkIRect subset;
503 for (int x = 0; x < width; x += tileSize) { 537 for (int x = 0; x < width; x += tileSize) {
504 subset = SkIRect::MakeXYWH(x, 0, SkTMin(tileSize, width - x), he ight); 538 subset = SkIRect::MakeXYWH(x, 0, SkTMin(tileSize, width - x), he ight);
505 opts.fSubset = &subset; 539 opts.fSubset = &subset;
506 if (SkCodec::kSuccess != codec->startScanlineDecode(decodeInfo, &opts, 540 if (SkCodec::kSuccess != codec->startScanlineDecode(decodeInfo, &opts,
507 colorPtr, colorCountPtr)) { 541 colorPtr, colorCountPtr)) {
508 return "Could not start scanline decoder."; 542 return "Could not start scanline decoder.";
509 } 543 }
510 544
511 codec->getScanlines(bitmap.getAddr(x, 0), height, bitmap.rowByte s()); 545 codec->getScanlines(bitmap.getAddr(x, 0), height, bitmap.rowByte s());
512 } 546 }
513 547
514 premultiply_if_necessary(bitmap); 548 premultiply_if_necessary(bitmap);
549 swap_rb_if_necessary(bitmap, fDstColorType);
515 canvas->drawBitmap(bitmap, 0, 0); 550 canvas->drawBitmap(bitmap, 0, 0);
516 break; 551 break;
517 } 552 }
518 case kSubset_Mode: { 553 case kSubset_Mode: {
519 // Arbitrarily choose a divisor. 554 // Arbitrarily choose a divisor.
520 int divisor = 2; 555 int divisor = 2;
521 // Total width/height of the image. 556 // Total width/height of the image.
522 const int W = codec->getInfo().width(); 557 const int W = codec->getInfo().width();
523 const int H = codec->getInfo().height(); 558 const int H = codec->getInfo().height();
524 if (divisor > W || divisor > H) { 559 if (divisor > W || divisor > H) {
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
564 case SkCodec::kSuccess: 599 case SkCodec::kSuccess:
565 case SkCodec::kIncompleteInput: 600 case SkCodec::kIncompleteInput:
566 break; 601 break;
567 default: 602 default:
568 return SkStringPrintf("subset codec failed to decode (%d, %d, %d, %d) " 603 return SkStringPrintf("subset codec failed to decode (%d, %d, %d, %d) "
569 "from %s with dimensions (%d x %d)\t error %d", 604 "from %s with dimensions (%d x %d)\t error %d",
570 x, y, decodeInfo.width(), deco deInfo.height(), 605 x, y, decodeInfo.width(), deco deInfo.height(),
571 fPath.c_str(), W, H, result); 606 fPath.c_str(), W, H, result);
572 } 607 }
573 premultiply_if_necessary(subsetBm); 608 premultiply_if_necessary(subsetBm);
609 swap_rb_if_necessary(bitmap, fDstColorType);
574 canvas->drawBitmap(subsetBm, SkIntToScalar(left), SkIntToSca lar(top)); 610 canvas->drawBitmap(subsetBm, SkIntToScalar(left), SkIntToSca lar(top));
575 // translate by the scaled height. 611 // translate by the scaled height.
576 top += decodeInfo.height(); 612 top += decodeInfo.height();
577 } 613 }
578 // translate by the scaled width. 614 // translate by the scaled width.
579 left += decodeInfo.width(); 615 left += decodeInfo.width();
580 } 616 }
581 return ""; 617 return "";
582 } 618 }
583 default: 619 default:
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
652 int* colorCountPtr = nullptr; 688 int* colorCountPtr = nullptr;
653 int maxColors = 256; 689 int maxColors = 256;
654 if (kIndex_8_SkColorType == decodeInfo.colorType()) { 690 if (kIndex_8_SkColorType == decodeInfo.colorType()) {
655 SkPMColor colors[256]; 691 SkPMColor colors[256];
656 colorTable.reset(new SkColorTable(colors, maxColors)); 692 colorTable.reset(new SkColorTable(colors, maxColors));
657 colorPtr = const_cast<SkPMColor*>(colorTable->readColors()); 693 colorPtr = const_cast<SkPMColor*>(colorTable->readColors());
658 colorCountPtr = &maxColors; 694 colorCountPtr = &maxColors;
659 } 695 }
660 696
661 SkBitmap bitmap; 697 SkBitmap bitmap;
662 if (!bitmap.tryAllocPixels(decodeInfo, nullptr, colorTable.get())) { 698 SkImageInfo bitmapInfo = decodeInfo;
699 if (kRGBA_8888_SkColorType == decodeInfo.colorType() ||
700 kBGRA_8888_SkColorType == decodeInfo.colorType()) {
701 bitmapInfo = bitmapInfo.makeColorType(kN32_SkColorType);
702 }
703 if (!bitmap.tryAllocPixels(bitmapInfo, nullptr, colorTable.get())) {
663 return SkStringPrintf("Image(%s) is too large (%d x %d)", fPath.c_str(), 704 return SkStringPrintf("Image(%s) is too large (%d x %d)", fPath.c_str(),
664 decodeInfo.width(), decodeInfo.height()); 705 decodeInfo.width(), decodeInfo.height());
665 } 706 }
666 707
667 // Create options for the codec. 708 // Create options for the codec.
668 SkAndroidCodec::AndroidOptions options; 709 SkAndroidCodec::AndroidOptions options;
669 options.fColorPtr = colorPtr; 710 options.fColorPtr = colorPtr;
670 options.fColorCount = colorCountPtr; 711 options.fColorCount = colorCountPtr;
671 options.fSampleSize = fSampleSize; 712 options.fSampleSize = fSampleSize;
672 713
673 switch (fMode) { 714 switch (fMode) {
674 case kFullImage_Mode: { 715 case kFullImage_Mode: {
675 switch (codec->getAndroidPixels(decodeInfo, bitmap.getPixels(), bitm ap.rowBytes(), 716 switch (codec->getAndroidPixels(decodeInfo, bitmap.getPixels(), bitm ap.rowBytes(),
676 &options)) { 717 &options)) {
677 case SkCodec::kSuccess: 718 case SkCodec::kSuccess:
678 case SkCodec::kIncompleteInput: 719 case SkCodec::kIncompleteInput:
679 break; 720 break;
680 default: 721 default:
681 return SkStringPrintf("Couldn't getPixels %s.", fPath.c_str( )); 722 return SkStringPrintf("Couldn't getPixels %s.", fPath.c_str( ));
682 } 723 }
683 premultiply_if_necessary(bitmap); 724 premultiply_if_necessary(bitmap);
725 swap_rb_if_necessary(bitmap, fDstColorType);
684 canvas->drawBitmap(bitmap, 0, 0); 726 canvas->drawBitmap(bitmap, 0, 0);
685 return ""; 727 return "";
686 } 728 }
687 case kDivisor_Mode: { 729 case kDivisor_Mode: {
688 const int width = codec->getInfo().width(); 730 const int width = codec->getInfo().width();
689 const int height = codec->getInfo().height(); 731 const int height = codec->getInfo().height();
690 const int divisor = 2; 732 const int divisor = 2;
691 if (width < divisor || height < divisor) { 733 if (width < divisor || height < divisor) {
692 return Error::Nonfatal("Divisor is larger than image dimension." ); 734 return Error::Nonfatal("Divisor is larger than image dimension." );
693 } 735 }
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
732 break; 774 break;
733 default: 775 default:
734 return SkStringPrintf("Couldn't getPixels %s.", fPat h.c_str()); 776 return SkStringPrintf("Couldn't getPixels %s.", fPat h.c_str());
735 } 777 }
736 } 778 }
737 } 779 }
738 780
739 SkRect rect = SkRect::MakeXYWH(0, 0, (SkScalar) finalScaledWidth, 781 SkRect rect = SkRect::MakeXYWH(0, 0, (SkScalar) finalScaledWidth,
740 (SkScalar) finalScaledHeight); 782 (SkScalar) finalScaledHeight);
741 premultiply_if_necessary(bitmap); 783 premultiply_if_necessary(bitmap);
784 swap_rb_if_necessary(bitmap, fDstColorType);
742 canvas->drawBitmapRect(bitmap, rect, rect, nullptr); 785 canvas->drawBitmapRect(bitmap, rect, rect, nullptr);
743 return ""; 786 return "";
744 } 787 }
745 default: 788 default:
746 SkASSERT(false); 789 SkASSERT(false);
747 return "Error: Should not be reached."; 790 return "Error: Should not be reached.";
748 } 791 }
749 } 792 }
750 793
751 SkISize AndroidCodecSrc::size() const { 794 SkISize AndroidCodecSrc::size() const {
(...skipping 703 matching lines...) Expand 10 before | Expand all | Expand 10 after
1455 skr.visit(i, drawsAsSingletonPictures); 1498 skr.visit(i, drawsAsSingletonPictures);
1456 } 1499 }
1457 sk_sp<SkPicture> macroPic(macroRec.finishRecordingAsPicture()); 1500 sk_sp<SkPicture> macroPic(macroRec.finishRecordingAsPicture());
1458 1501
1459 canvas->drawPicture(macroPic); 1502 canvas->drawPicture(macroPic);
1460 return check_against_reference(bitmap, src, fSink); 1503 return check_against_reference(bitmap, src, fSink);
1461 }); 1504 });
1462 } 1505 }
1463 1506
1464 } // namespace DM 1507 } // namespace DM
OLDNEW
« no previous file with comments | « dm/DMSrcSink.h ('k') | src/codec/SkBmpRLECodec.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698