DM testing for skipping and scaling
BUG=skia: Review URL: https://codereview.chromium.org/1175993005
This commit is contained in:
parent
8f086023bf
commit
0a24297be4
78
dm/DM.cpp
78
dm/DM.cpp
@ -205,38 +205,54 @@ static void push_codec_srcs(Path path) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Build additional test cases for images that decode natively to non-canvas types
|
||||
switch(codec->getInfo().colorType()) {
|
||||
case kGray_8_SkColorType:
|
||||
push_src("image", "codec_kGray8", new CodecSrc(path, CodecSrc::kNormal_Mode,
|
||||
CodecSrc::kGrayscale_Always_DstColorType));
|
||||
push_src("image", "scanline_kGray8", new CodecSrc(path, CodecSrc::kScanline_Mode,
|
||||
CodecSrc::kGrayscale_Always_DstColorType));
|
||||
push_src("image", "scanline_subset_kGray8", new CodecSrc(path,
|
||||
CodecSrc::kScanline_Subset_Mode, CodecSrc::kGrayscale_Always_DstColorType));
|
||||
// Intentional fall through
|
||||
// FIXME: Is this a long term solution for testing wbmps decodes to kIndex8?
|
||||
// Further discussion on this topic is at skbug.com/3683
|
||||
case kIndex_8_SkColorType:
|
||||
push_src("image", "codec_kIndex8", new CodecSrc(path, CodecSrc::kNormal_Mode,
|
||||
CodecSrc::kIndex8_Always_DstColorType));
|
||||
push_src("image", "scanline_kIndex8", new CodecSrc(path, CodecSrc::kScanline_Mode,
|
||||
CodecSrc::kIndex8_Always_DstColorType));
|
||||
push_src("image", "scanline_subset_kIndex8", new CodecSrc(path,
|
||||
CodecSrc::kScanline_Subset_Mode, CodecSrc::kIndex8_Always_DstColorType));
|
||||
break;
|
||||
default:
|
||||
// Do nothing
|
||||
break;
|
||||
}
|
||||
// Choose scales for scaling tests.
|
||||
// TODO (msarett): Add more scaling tests as we implement more flexible scaling.
|
||||
// TODO (msarett): Implement scaling tests for SkImageDecoder in order to compare with these
|
||||
// tests. SkImageDecoder supports downscales by integer factors.
|
||||
const float scales[] = { 0.125f, 0.25f, 0.5f, 1.0f };
|
||||
|
||||
// Decode all images to the canvas color type
|
||||
push_src("image", "codec", new CodecSrc(path, CodecSrc::kNormal_Mode,
|
||||
CodecSrc::kGetFromCanvas_DstColorType));
|
||||
push_src("image", "scanline", new CodecSrc(path, CodecSrc::kScanline_Mode,
|
||||
CodecSrc::kGetFromCanvas_DstColorType));
|
||||
push_src("image", "scanline_subset", new CodecSrc(path, CodecSrc::kScanline_Subset_Mode,
|
||||
CodecSrc::kGetFromCanvas_DstColorType));
|
||||
for (float scale : scales) {
|
||||
// Build additional test cases for images that decode natively to non-canvas types
|
||||
switch(codec->getInfo().colorType()) {
|
||||
case kGray_8_SkColorType:
|
||||
push_src("image", "codec_kGray8", new CodecSrc(path, CodecSrc::kNormal_Mode,
|
||||
CodecSrc::kGrayscale_Always_DstColorType, scale));
|
||||
push_src("image", "scanline_kGray8", new CodecSrc(path, CodecSrc::kScanline_Mode,
|
||||
CodecSrc::kGrayscale_Always_DstColorType, scale));
|
||||
push_src("image", "scanline_subset_kGray8", new CodecSrc(path,
|
||||
CodecSrc::kScanline_Subset_Mode, CodecSrc::kGrayscale_Always_DstColorType,
|
||||
scale));
|
||||
push_src("image", "stripe_kGray8", new CodecSrc(path, CodecSrc::kStripe_Mode,
|
||||
CodecSrc::kGrayscale_Always_DstColorType, scale));
|
||||
// Intentional fall through
|
||||
// FIXME: Is this a long term solution for testing wbmps decodes to kIndex8?
|
||||
// Further discussion on this topic is at skbug.com/3683
|
||||
case kIndex_8_SkColorType:
|
||||
push_src("image", "codec_kIndex8", new CodecSrc(path, CodecSrc::kNormal_Mode,
|
||||
CodecSrc::kIndex8_Always_DstColorType, scale));
|
||||
push_src("image", "scanline_kIndex8", new CodecSrc(path, CodecSrc::kScanline_Mode,
|
||||
CodecSrc::kIndex8_Always_DstColorType, scale));
|
||||
push_src("image", "scanline_subset_kIndex8", new CodecSrc(path,
|
||||
CodecSrc::kScanline_Subset_Mode, CodecSrc::kIndex8_Always_DstColorType,
|
||||
scale));
|
||||
push_src("image", "stripe_kIndex8", new CodecSrc(path, CodecSrc::kStripe_Mode,
|
||||
CodecSrc::kIndex8_Always_DstColorType, scale));
|
||||
break;
|
||||
default:
|
||||
// Do nothing
|
||||
break;
|
||||
}
|
||||
|
||||
// Decode all images to the canvas color type
|
||||
push_src("image", "codec", new CodecSrc(path, CodecSrc::kNormal_Mode,
|
||||
CodecSrc::kGetFromCanvas_DstColorType, scale));
|
||||
push_src("image", "scanline", new CodecSrc(path, CodecSrc::kScanline_Mode,
|
||||
CodecSrc::kGetFromCanvas_DstColorType, scale));
|
||||
push_src("image", "scanline_subset", new CodecSrc(path, CodecSrc::kScanline_Subset_Mode,
|
||||
CodecSrc::kGetFromCanvas_DstColorType, scale));
|
||||
push_src("image", "stripe", new CodecSrc(path, CodecSrc::kStripe_Mode,
|
||||
CodecSrc::kGetFromCanvas_DstColorType, scale));
|
||||
}
|
||||
}
|
||||
|
||||
static bool codec_supported(const char* ext) {
|
||||
|
@ -64,10 +64,11 @@ void GMSrc::modifyGrContextOptions(GrContextOptions* options) const {
|
||||
|
||||
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
||||
|
||||
CodecSrc::CodecSrc(Path path, Mode mode, DstColorType dstColorType)
|
||||
CodecSrc::CodecSrc(Path path, Mode mode, DstColorType dstColorType, float scale)
|
||||
: fPath(path)
|
||||
, fMode(mode)
|
||||
, fDstColorType(dstColorType)
|
||||
, fScale(scale)
|
||||
{}
|
||||
|
||||
Error CodecSrc::draw(SkCanvas* canvas) const {
|
||||
@ -108,6 +109,13 @@ Error CodecSrc::draw(SkCanvas* canvas) const {
|
||||
break;
|
||||
}
|
||||
|
||||
// Try to scale the image if it is desired
|
||||
SkISize size = codec->getScaledDimensions(fScale);
|
||||
if (size == decodeInfo.dimensions() && 1.0f != fScale) {
|
||||
return Error::Nonfatal("Test without scaling is uninteresting.");
|
||||
}
|
||||
decodeInfo = decodeInfo.makeWH(size.width(), size.height());
|
||||
|
||||
// Construct a color table for the decode if necessary
|
||||
SkAutoTUnref<SkColorTable> colorTable(NULL);
|
||||
SkPMColor* colorPtr = NULL;
|
||||
@ -195,7 +203,7 @@ Error CodecSrc::draw(SkCanvas* canvas) const {
|
||||
* subsetBm's size is determined based on the current subset and may be larger for end
|
||||
* subsets.
|
||||
*/
|
||||
SkImageInfo largestSubsetDecodeInfo =
|
||||
SkImageInfo largestSubsetDecodeInfo =
|
||||
decodeInfo.makeWH(subsetWidth + extraX, subsetHeight + extraY);
|
||||
SkBitmap largestSubsetBm;
|
||||
if (!largestSubsetBm.tryAllocPixels(largestSubsetDecodeInfo, NULL, colorTable.get())) {
|
||||
@ -226,7 +234,7 @@ Error CodecSrc::draw(SkCanvas* canvas) const {
|
||||
}
|
||||
}
|
||||
//skip to first line of subset
|
||||
const SkImageGenerator::Result skipResult =
|
||||
const SkImageGenerator::Result skipResult =
|
||||
subsetScanlineDecoder->skipScanlines(y);
|
||||
switch (skipResult) {
|
||||
case SkImageGenerator::kSuccess:
|
||||
@ -262,6 +270,80 @@ Error CodecSrc::draw(SkCanvas* canvas) const {
|
||||
}
|
||||
break;
|
||||
}
|
||||
case kStripe_Mode: {
|
||||
const int height = decodeInfo.height();
|
||||
// This value is chosen arbitrarily. We exercise more cases by choosing a value that
|
||||
// does not align with image blocks.
|
||||
const int stripeHeight = 37;
|
||||
const int numStripes = (height + stripeHeight - 1) / stripeHeight;
|
||||
|
||||
// Decode odd stripes
|
||||
SkScanlineDecoder* decoder = codec->getScanlineDecoder(decodeInfo, NULL, colorPtr,
|
||||
colorCountPtr);
|
||||
if (NULL == decoder) {
|
||||
return Error::Nonfatal("Cannot use scanline decoder for all images");
|
||||
}
|
||||
for (int i = 0; i < numStripes; i += 2) {
|
||||
// Skip a stripe
|
||||
const int linesToSkip = SkTMin(stripeHeight, height - i * stripeHeight);
|
||||
SkImageGenerator::Result result = decoder->skipScanlines(linesToSkip);
|
||||
switch (result) {
|
||||
case SkImageGenerator::kSuccess:
|
||||
case SkImageGenerator::kIncompleteInput:
|
||||
break;
|
||||
default:
|
||||
return SkStringPrintf("Cannot skip scanlines for %s.", fPath.c_str());
|
||||
}
|
||||
|
||||
// Read a stripe
|
||||
const int startY = (i + 1) * stripeHeight;
|
||||
const int linesToRead = SkTMin(stripeHeight, height - startY);
|
||||
if (linesToRead > 0) {
|
||||
result = decoder->getScanlines(bitmap.getAddr(0, startY),
|
||||
linesToRead, bitmap.rowBytes());
|
||||
switch (result) {
|
||||
case SkImageGenerator::kSuccess:
|
||||
case SkImageGenerator::kIncompleteInput:
|
||||
break;
|
||||
default:
|
||||
return SkStringPrintf("Cannot get scanlines for %s.", fPath.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Decode even stripes
|
||||
decoder = codec->getScanlineDecoder(decodeInfo, NULL, colorPtr, colorCountPtr);
|
||||
if (NULL == decoder) {
|
||||
return "Failed to create second scanline decoder.";
|
||||
}
|
||||
for (int i = 0; i < numStripes; i += 2) {
|
||||
// Read a stripe
|
||||
const int startY = i * stripeHeight;
|
||||
const int linesToRead = SkTMin(stripeHeight, height - startY);
|
||||
SkImageGenerator::Result result = decoder->getScanlines(bitmap.getAddr(0, startY),
|
||||
linesToRead, bitmap.rowBytes());
|
||||
switch (result) {
|
||||
case SkImageGenerator::kSuccess:
|
||||
case SkImageGenerator::kIncompleteInput:
|
||||
break;
|
||||
default:
|
||||
return SkStringPrintf("Cannot get scanlines for %s.", fPath.c_str());
|
||||
}
|
||||
|
||||
// Skip a stripe
|
||||
const int linesToSkip = SkTMax(0, SkTMin(stripeHeight,
|
||||
height - (i + 1) * stripeHeight));
|
||||
result = decoder->skipScanlines(linesToSkip);
|
||||
switch (result) {
|
||||
case SkImageGenerator::kSuccess:
|
||||
case SkImageGenerator::kIncompleteInput:
|
||||
break;
|
||||
default:
|
||||
return SkStringPrintf("Cannot skip scanlines for %s.", fPath.c_str());
|
||||
}
|
||||
}
|
||||
canvas->drawBitmap(bitmap, 0, 0);
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
@ -270,14 +352,19 @@ SkISize CodecSrc::size() const {
|
||||
SkAutoTUnref<SkData> encoded(SkData::NewFromFileName(fPath.c_str()));
|
||||
SkAutoTDelete<SkCodec> codec(SkCodec::NewFromData(encoded));
|
||||
if (NULL != codec) {
|
||||
return codec->getInfo().dimensions();
|
||||
SkISize size = codec->getScaledDimensions(fScale);
|
||||
return size;
|
||||
} else {
|
||||
return SkISize::Make(0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
Name CodecSrc::name() const {
|
||||
return SkOSPath::Basename(fPath.c_str());
|
||||
if (1.0f == fScale) {
|
||||
return SkOSPath::Basename(fPath.c_str());
|
||||
} else {
|
||||
return SkStringPrintf("%s_%.3f", SkOSPath::Basename(fPath.c_str()).c_str(), fScale);
|
||||
}
|
||||
}
|
||||
|
||||
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
||||
|
@ -98,13 +98,14 @@ public:
|
||||
kNormal_Mode,
|
||||
kScanline_Mode,
|
||||
kScanline_Subset_Mode,
|
||||
kStripe_Mode, // Tests the skipping of scanlines
|
||||
};
|
||||
enum DstColorType {
|
||||
kGetFromCanvas_DstColorType,
|
||||
kIndex8_Always_DstColorType,
|
||||
kGrayscale_Always_DstColorType,
|
||||
};
|
||||
CodecSrc(Path, Mode, DstColorType);
|
||||
CodecSrc(Path, Mode, DstColorType, float);
|
||||
|
||||
Error draw(SkCanvas*) const override;
|
||||
SkISize size() const override;
|
||||
@ -113,6 +114,7 @@ private:
|
||||
Path fPath;
|
||||
Mode fMode;
|
||||
DstColorType fDstColorType;
|
||||
float fScale;
|
||||
};
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user