OLD | NEW |
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 "SamplePipeControllers.h" | 9 #include "SamplePipeControllers.h" |
10 #include "SkAndroidCodec.h" | 10 #include "SkAndroidCodec.h" |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
106 colorType = kGray_8_SkColorType; | 106 colorType = kGray_8_SkColorType; |
107 break; | 107 break; |
108 } | 108 } |
109 | 109 |
110 SkAutoTDelete<SkBitmapRegionDecoder> brd(create_brd(fPath, fStrategy)); | 110 SkAutoTDelete<SkBitmapRegionDecoder> brd(create_brd(fPath, fStrategy)); |
111 if (nullptr == brd.get()) { | 111 if (nullptr == brd.get()) { |
112 return Error::Nonfatal(SkStringPrintf("Could not create brd for %s.", fP
ath.c_str())); | 112 return Error::Nonfatal(SkStringPrintf("Could not create brd for %s.", fP
ath.c_str())); |
113 } | 113 } |
114 | 114 |
115 if (!brd->conversionSupported(colorType)) { | 115 if (!brd->conversionSupported(colorType)) { |
116 return Error::Nonfatal("Cannot convert to color type.\n"); | 116 return Error::Nonfatal("Cannot convert to color type."); |
117 } | 117 } |
118 | 118 |
119 const uint32_t width = brd->width(); | 119 const uint32_t width = brd->width(); |
120 const uint32_t height = brd->height(); | 120 const uint32_t height = brd->height(); |
121 // Visually inspecting very small output images is not necessary. | 121 // Visually inspecting very small output images is not necessary. |
122 if ((width / fSampleSize <= 10 || height / fSampleSize <= 10) && 1 != fSampl
eSize) { | 122 if ((width / fSampleSize <= 10 || height / fSampleSize <= 10) && 1 != fSampl
eSize) { |
123 return Error::Nonfatal("Scaling very small images is uninteresting."); | 123 return Error::Nonfatal("Scaling very small images is uninteresting."); |
124 } | 124 } |
125 switch (fMode) { | 125 switch (fMode) { |
126 case kFullImage_Mode: { | 126 case kFullImage_Mode: { |
127 SkBitmap bitmap; | 127 SkBitmap bitmap; |
128 if (!brd->decodeRegion(&bitmap, nullptr, SkIRect::MakeXYWH(0, 0, wid
th, height), | 128 if (!brd->decodeRegion(&bitmap, nullptr, SkIRect::MakeXYWH(0, 0, wid
th, height), |
129 fSampleSize, colorType, false)) { | 129 fSampleSize, colorType, false)) { |
130 return "Cannot decode (full) region.\n"; | 130 return "Cannot decode (full) region."; |
131 } | 131 } |
132 if (colorType != bitmap.colorType()) { | 132 if (colorType != bitmap.colorType()) { |
133 return Error::Nonfatal("Cannot convert to color type.\n"); | 133 return Error::Nonfatal("Cannot convert to color type."); |
134 } | 134 } |
135 canvas->drawBitmap(bitmap, 0, 0); | 135 canvas->drawBitmap(bitmap, 0, 0); |
136 return ""; | 136 return ""; |
137 } | 137 } |
138 case kDivisor_Mode: { | 138 case kDivisor_Mode: { |
139 const uint32_t divisor = 2; | 139 const uint32_t divisor = 2; |
140 if (width < divisor || height < divisor) { | 140 if (width < divisor || height < divisor) { |
141 return Error::Nonfatal("Divisor is larger than image dimension.\
n"); | 141 return Error::Nonfatal("Divisor is larger than image dimension."
); |
142 } | 142 } |
143 | 143 |
144 // Use a border to test subsets that extend outside the image. | 144 // Use a border to test subsets that extend outside the image. |
145 // We will not allow the border to be larger than the image dimensio
ns. Allowing | 145 // We will not allow the border to be larger than the image dimensio
ns. Allowing |
146 // these large borders causes off by one errors that indicate a prob
lem with the | 146 // these large borders causes off by one errors that indicate a prob
lem with the |
147 // test suite, not a problem with the implementation. | 147 // test suite, not a problem with the implementation. |
148 const uint32_t maxBorder = SkTMin(width, height) / (fSampleSize * di
visor); | 148 const uint32_t maxBorder = SkTMin(width, height) / (fSampleSize * di
visor); |
149 const uint32_t scaledBorder = SkTMin(5u, maxBorder); | 149 const uint32_t scaledBorder = SkTMin(5u, maxBorder); |
150 const uint32_t unscaledBorder = scaledBorder * fSampleSize; | 150 const uint32_t unscaledBorder = scaledBorder * fSampleSize; |
151 | 151 |
(...skipping 24 matching lines...) Expand all Loading... |
176 subsetHeight += (y + 1 == divisor) ? (height % divisor) : 0; | 176 subsetHeight += (y + 1 == divisor) ? (height % divisor) : 0; |
177 | 177 |
178 // Increase the size of the subset in order to have a border
on each side | 178 // Increase the size of the subset in order to have a border
on each side |
179 const int decodeLeft = left - unscaledBorder; | 179 const int decodeLeft = left - unscaledBorder; |
180 const int decodeTop = top - unscaledBorder; | 180 const int decodeTop = top - unscaledBorder; |
181 const uint32_t decodeWidth = subsetWidth + unscaledBorder *
2; | 181 const uint32_t decodeWidth = subsetWidth + unscaledBorder *
2; |
182 const uint32_t decodeHeight = subsetHeight + unscaledBorder
* 2; | 182 const uint32_t decodeHeight = subsetHeight + unscaledBorder
* 2; |
183 SkBitmap bitmap; | 183 SkBitmap bitmap; |
184 if (!brd->decodeRegion(&bitmap, nullptr, SkIRect::MakeXYWH(d
ecodeLeft, | 184 if (!brd->decodeRegion(&bitmap, nullptr, SkIRect::MakeXYWH(d
ecodeLeft, |
185 decodeTop, decodeWidth, decodeHeight), fSampleSize,
colorType, false)) { | 185 decodeTop, decodeWidth, decodeHeight), fSampleSize,
colorType, false)) { |
186 return "Cannot decode region.\n"; | 186 return "Cannot decode region."; |
187 } | 187 } |
188 if (colorType != bitmap.colorType()) { | 188 if (colorType != bitmap.colorType()) { |
189 return Error::Nonfatal("Cannot convert to color type.\n"
); | 189 return Error::Nonfatal("Cannot convert to color type."); |
190 } | 190 } |
191 | 191 |
192 canvas->drawBitmapRect(bitmap, | 192 canvas->drawBitmapRect(bitmap, |
193 SkRect::MakeXYWH((SkScalar) scaledBorder, (SkScalar)
scaledBorder, | 193 SkRect::MakeXYWH((SkScalar) scaledBorder, (SkScalar)
scaledBorder, |
194 (SkScalar) (subsetWidth / fSampleSize), | 194 (SkScalar) (subsetWidth / fSampleSize), |
195 (SkScalar) (subsetHeight / fSampleSize)), | 195 (SkScalar) (subsetHeight / fSampleSize)), |
196 SkRect::MakeXYWH((SkScalar) (left / fSampleSize), | 196 SkRect::MakeXYWH((SkScalar) (left / fSampleSize), |
197 (SkScalar) (top / fSampleSize), | 197 (SkScalar) (top / fSampleSize), |
198 (SkScalar) (subsetWidth / fSampleSize), | 198 (SkScalar) (subsetWidth / fSampleSize), |
199 (SkScalar) (subsetHeight / fSampleSize)), | 199 (SkScalar) (subsetHeight / fSampleSize)), |
200 nullptr); | 200 nullptr); |
201 } | 201 } |
202 } | 202 } |
203 return ""; | 203 return ""; |
204 } | 204 } |
205 default: | 205 default: |
206 SkASSERT(false); | 206 SkASSERT(false); |
207 return "Error: Should not be reached.\n"; | 207 return "Error: Should not be reached."; |
208 } | 208 } |
209 } | 209 } |
210 | 210 |
211 SkISize BRDSrc::size() const { | 211 SkISize BRDSrc::size() const { |
212 SkAutoTDelete<SkBitmapRegionDecoder> brd(create_brd(fPath, fStrategy)); | 212 SkAutoTDelete<SkBitmapRegionDecoder> brd(create_brd(fPath, fStrategy)); |
213 if (brd) { | 213 if (brd) { |
214 return SkISize::Make(SkTMax(1, brd->width() / (int) fSampleSize), | 214 return SkISize::Make(SkTMax(1, brd->width() / (int) fSampleSize), |
215 SkTMax(1, brd->height() / (int) fSampleSize)); | 215 SkTMax(1, brd->height() / (int) fSampleSize)); |
216 } | 216 } |
217 return SkISize::Make(0, 0); | 217 return SkISize::Make(0, 0); |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
310 int maxColors = 256; | 310 int maxColors = 256; |
311 if (kIndex_8_SkColorType == decodeInfo.colorType()) { | 311 if (kIndex_8_SkColorType == decodeInfo.colorType()) { |
312 SkPMColor colors[256]; | 312 SkPMColor colors[256]; |
313 colorTable.reset(new SkColorTable(colors, maxColors)); | 313 colorTable.reset(new SkColorTable(colors, maxColors)); |
314 colorPtr = const_cast<SkPMColor*>(colorTable->readColors()); | 314 colorPtr = const_cast<SkPMColor*>(colorTable->readColors()); |
315 colorCountPtr = &maxColors; | 315 colorCountPtr = &maxColors; |
316 } | 316 } |
317 | 317 |
318 SkBitmap bitmap; | 318 SkBitmap bitmap; |
319 if (!bitmap.tryAllocPixels(decodeInfo, nullptr, colorTable.get())) { | 319 if (!bitmap.tryAllocPixels(decodeInfo, nullptr, colorTable.get())) { |
320 return SkStringPrintf("Image(%s) is too large (%d x %d)\n", fPath.c_str(
), | 320 return SkStringPrintf("Image(%s) is too large (%d x %d)", fPath.c_str(), |
321 decodeInfo.width(), decodeInfo.height()); | 321 decodeInfo.width(), decodeInfo.height()); |
322 } | 322 } |
323 | 323 |
324 switch (fMode) { | 324 switch (fMode) { |
325 case kCodec_Mode: { | 325 case kCodec_Mode: { |
326 switch (codec->getPixels(decodeInfo, bitmap.getPixels(), bitmap.rowB
ytes(), nullptr, | 326 switch (codec->getPixels(decodeInfo, bitmap.getPixels(), bitmap.rowB
ytes(), nullptr, |
327 colorPtr, colorCountPtr)) { | 327 colorPtr, colorCountPtr)) { |
328 case SkCodec::kSuccess: | 328 case SkCodec::kSuccess: |
329 // We consider incomplete to be valid, since we should still
decode what is | 329 // We consider incomplete to be valid, since we should still
decode what is |
330 // available. | 330 // available. |
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
572 int maxColors = 256; | 572 int maxColors = 256; |
573 if (kIndex_8_SkColorType == decodeInfo.colorType()) { | 573 if (kIndex_8_SkColorType == decodeInfo.colorType()) { |
574 SkPMColor colors[256]; | 574 SkPMColor colors[256]; |
575 colorTable.reset(new SkColorTable(colors, maxColors)); | 575 colorTable.reset(new SkColorTable(colors, maxColors)); |
576 colorPtr = const_cast<SkPMColor*>(colorTable->readColors()); | 576 colorPtr = const_cast<SkPMColor*>(colorTable->readColors()); |
577 colorCountPtr = &maxColors; | 577 colorCountPtr = &maxColors; |
578 } | 578 } |
579 | 579 |
580 SkBitmap bitmap; | 580 SkBitmap bitmap; |
581 if (!bitmap.tryAllocPixels(decodeInfo, nullptr, colorTable.get())) { | 581 if (!bitmap.tryAllocPixels(decodeInfo, nullptr, colorTable.get())) { |
582 return SkStringPrintf("Image(%s) is too large (%d x %d)\n", fPath.c_str(
), | 582 return SkStringPrintf("Image(%s) is too large (%d x %d)", fPath.c_str(), |
583 decodeInfo.width(), decodeInfo.height()); | 583 decodeInfo.width(), decodeInfo.height()); |
584 } | 584 } |
585 | 585 |
586 // Create options for the codec. | 586 // Create options for the codec. |
587 SkAndroidCodec::AndroidOptions options; | 587 SkAndroidCodec::AndroidOptions options; |
588 options.fColorPtr = colorPtr; | 588 options.fColorPtr = colorPtr; |
589 options.fColorCount = colorCountPtr; | 589 options.fColorCount = colorCountPtr; |
590 options.fSampleSize = fSampleSize; | 590 options.fSampleSize = fSampleSize; |
591 | 591 |
592 switch (fMode) { | 592 switch (fMode) { |
593 case kFullImage_Mode: { | 593 case kFullImage_Mode: { |
594 switch (codec->getAndroidPixels(decodeInfo, bitmap.getPixels(), bitm
ap.rowBytes(), | 594 switch (codec->getAndroidPixels(decodeInfo, bitmap.getPixels(), bitm
ap.rowBytes(), |
595 &options)) { | 595 &options)) { |
596 case SkCodec::kSuccess: | 596 case SkCodec::kSuccess: |
597 case SkCodec::kIncompleteInput: | 597 case SkCodec::kIncompleteInput: |
598 break; | 598 break; |
599 case SkCodec::kInvalidConversion: | 599 case SkCodec::kInvalidConversion: |
600 return Error::Nonfatal("Cannot convert to requested color ty
pe.\n"); | 600 return Error::Nonfatal("Cannot convert to requested color ty
pe."); |
601 default: | 601 default: |
602 return SkStringPrintf("Couldn't getPixels %s.", fPath.c_str(
)); | 602 return SkStringPrintf("Couldn't getPixels %s.", fPath.c_str(
)); |
603 } | 603 } |
604 canvas->drawBitmap(bitmap, 0, 0); | 604 canvas->drawBitmap(bitmap, 0, 0); |
605 return ""; | 605 return ""; |
606 } | 606 } |
607 case kDivisor_Mode: { | 607 case kDivisor_Mode: { |
608 const int width = codec->getInfo().width(); | 608 const int width = codec->getInfo().width(); |
609 const int height = codec->getInfo().height(); | 609 const int height = codec->getInfo().height(); |
610 const int divisor = 2; | 610 const int divisor = 2; |
611 if (width < divisor || height < divisor) { | 611 if (width < divisor || height < divisor) { |
612 return Error::Nonfatal("Divisor is larger than image dimension.\
n"); | 612 return Error::Nonfatal("Divisor is larger than image dimension."
); |
613 } | 613 } |
614 | 614 |
615 // Keep track of the final decoded dimensions. | 615 // Keep track of the final decoded dimensions. |
616 int finalScaledWidth = 0; | 616 int finalScaledWidth = 0; |
617 int finalScaledHeight = 0; | 617 int finalScaledHeight = 0; |
618 for (int x = 0; x < divisor; x++) { | 618 for (int x = 0; x < divisor; x++) { |
619 for (int y = 0; y < divisor; y++) { | 619 for (int y = 0; y < divisor; y++) { |
620 // Calculate the subset dimensions | 620 // Calculate the subset dimensions |
621 int subsetWidth = width / divisor; | 621 int subsetWidth = width / divisor; |
622 int subsetHeight = height / divisor; | 622 int subsetHeight = height / divisor; |
623 const int left = x * subsetWidth; | 623 const int left = x * subsetWidth; |
624 const int top = y * subsetHeight; | 624 const int top = y * subsetHeight; |
625 | 625 |
626 // Increase the size of the last subset in each row or colum
n, when the | 626 // Increase the size of the last subset in each row or colum
n, when the |
627 // divisor does not divide evenly into the image dimensions | 627 // divisor does not divide evenly into the image dimensions |
628 subsetWidth += (x + 1 == divisor) ? (width % divisor) : 0; | 628 subsetWidth += (x + 1 == divisor) ? (width % divisor) : 0; |
629 subsetHeight += (y + 1 == divisor) ? (height % divisor) : 0; | 629 subsetHeight += (y + 1 == divisor) ? (height % divisor) : 0; |
630 SkIRect subset = SkIRect::MakeXYWH(left, top, subsetWidth, s
ubsetHeight); | 630 SkIRect subset = SkIRect::MakeXYWH(left, top, subsetWidth, s
ubsetHeight); |
631 if (!codec->getSupportedSubset(&subset)) { | 631 if (!codec->getSupportedSubset(&subset)) { |
632 return "Could not get supported subset to decode.\n"; | 632 return "Could not get supported subset to decode."; |
633 } | 633 } |
634 options.fSubset = ⊂ | 634 options.fSubset = ⊂ |
635 const int scaledWidthOffset = subset.left() / fSampleSize; | 635 const int scaledWidthOffset = subset.left() / fSampleSize; |
636 const int scaledHeightOffset = subset.top() / fSampleSize; | 636 const int scaledHeightOffset = subset.top() / fSampleSize; |
637 void* pixels = bitmap.getAddr(scaledWidthOffset, scaledHeigh
tOffset); | 637 void* pixels = bitmap.getAddr(scaledWidthOffset, scaledHeigh
tOffset); |
638 SkISize scaledSubsetSize = codec->getSampledSubsetDimensions
(fSampleSize, | 638 SkISize scaledSubsetSize = codec->getSampledSubsetDimensions
(fSampleSize, |
639 subset); | 639 subset); |
640 SkImageInfo subsetDecodeInfo = decodeInfo.makeWH(scaledSubse
tSize.width(), | 640 SkImageInfo subsetDecodeInfo = decodeInfo.makeWH(scaledSubse
tSize.width(), |
641 scaledSubsetSize.height()); | 641 scaledSubsetSize.height()); |
642 | 642 |
643 if (x + 1 == divisor && y + 1 == divisor) { | 643 if (x + 1 == divisor && y + 1 == divisor) { |
644 finalScaledWidth = scaledWidthOffset + scaledSubsetSize.
width(); | 644 finalScaledWidth = scaledWidthOffset + scaledSubsetSize.
width(); |
645 finalScaledHeight = scaledHeightOffset + scaledSubsetSiz
e.height(); | 645 finalScaledHeight = scaledHeightOffset + scaledSubsetSiz
e.height(); |
646 } | 646 } |
647 | 647 |
648 switch (codec->getAndroidPixels(subsetDecodeInfo, pixels, bi
tmap.rowBytes(), | 648 switch (codec->getAndroidPixels(subsetDecodeInfo, pixels, bi
tmap.rowBytes(), |
649 &options)) { | 649 &options)) { |
650 case SkCodec::kSuccess: | 650 case SkCodec::kSuccess: |
651 case SkCodec::kIncompleteInput: | 651 case SkCodec::kIncompleteInput: |
652 break; | 652 break; |
653 case SkCodec::kInvalidConversion: | 653 case SkCodec::kInvalidConversion: |
654 return Error::Nonfatal("Cannot convert to requested
color type.\n"); | 654 return Error::Nonfatal("Cannot convert to requested
color type."); |
655 default: | 655 default: |
656 return SkStringPrintf("Couldn't getPixels %s.", fPat
h.c_str()); | 656 return SkStringPrintf("Couldn't getPixels %s.", fPat
h.c_str()); |
657 } | 657 } |
658 } | 658 } |
659 } | 659 } |
660 | 660 |
661 SkRect rect = SkRect::MakeXYWH(0, 0, (SkScalar) finalScaledWidth, | 661 SkRect rect = SkRect::MakeXYWH(0, 0, (SkScalar) finalScaledWidth, |
662 (SkScalar) finalScaledHeight); | 662 (SkScalar) finalScaledHeight); |
663 canvas->drawBitmapRect(bitmap, rect, rect, nullptr); | 663 canvas->drawBitmapRect(bitmap, rect, rect, nullptr); |
664 return ""; | 664 return ""; |
665 } | 665 } |
666 default: | 666 default: |
667 SkASSERT(false); | 667 SkASSERT(false); |
668 return "Error: Should not be reached.\n"; | 668 return "Error: Should not be reached."; |
669 } | 669 } |
670 } | 670 } |
671 | 671 |
672 SkISize AndroidCodecSrc::size() const { | 672 SkISize AndroidCodecSrc::size() const { |
673 SkAutoTUnref<SkData> encoded(SkData::NewFromFileName(fPath.c_str())); | 673 SkAutoTUnref<SkData> encoded(SkData::NewFromFileName(fPath.c_str())); |
674 SkAutoTDelete<SkAndroidCodec> codec(SkAndroidCodec::NewFromData(encoded)); | 674 SkAutoTDelete<SkAndroidCodec> codec(SkAndroidCodec::NewFromData(encoded)); |
675 if (nullptr == codec) { | 675 if (nullptr == codec) { |
676 return SkISize::Make(0, 0); | 676 return SkISize::Make(0, 0); |
677 } | 677 } |
678 return codec->getSampledDimensions(fSampleSize); | 678 return codec->getSampledDimensions(fSampleSize); |
(...skipping 585 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1264 skr.visit<void>(i, drawsAsSingletonPictures); | 1264 skr.visit<void>(i, drawsAsSingletonPictures); |
1265 } | 1265 } |
1266 SkAutoTUnref<SkPicture> macroPic(macroRec.endRecordingAsPicture()); | 1266 SkAutoTUnref<SkPicture> macroPic(macroRec.endRecordingAsPicture()); |
1267 | 1267 |
1268 canvas->drawPicture(macroPic); | 1268 canvas->drawPicture(macroPic); |
1269 return ""; | 1269 return ""; |
1270 }); | 1270 }); |
1271 } | 1271 } |
1272 | 1272 |
1273 } // namespace DM | 1273 } // namespace DM |
OLD | NEW |