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

Side by Side Diff: dm/DMSrcSink.cpp

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

Powered by Google App Engine
This is Rietveld 408576698