Have SkWuffsCodec speak kRGB_565_SkColorType
This takes the "one pass" code path more often, using less memory, as it does not have to allocate an intermediate width*height pixel buffer. Wuffs v0.2 did not support RGB 565 color but Wuffs v0.3 does. The Codec_AnimatedTransparentGif test passes with skia_use_wuffs true or false. Change-Id: Id569fc0bf62e614fa881cb235a9a6a1ca340dcb0 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/329916 Commit-Queue: Leon Scroggins <scroggo@google.com> Reviewed-by: Leon Scroggins <scroggo@google.com>
This commit is contained in:
parent
5c53ae5a72
commit
f933e4fb56
@ -461,9 +461,6 @@ SkCodec::Result SkWuffsCodec::onStartIncrementalDecode(const SkImageInfo& d
|
||||
if (options.fSubset) {
|
||||
return SkCodec::kUnimplemented;
|
||||
}
|
||||
if (options.fFrameIndex > 0 && SkColorTypeIsAlwaysOpaque(dstInfo.colorType())) {
|
||||
return SkCodec::kInvalidConversion;
|
||||
}
|
||||
SkCodec::Result result = this->seekFrame(WhichDecoder::kIncrDecode, options.fFrameIndex);
|
||||
if (result != SkCodec::kSuccess) {
|
||||
return result;
|
||||
@ -481,6 +478,10 @@ SkCodec::Result SkWuffsCodec::onStartIncrementalDecode(const SkImageInfo& d
|
||||
size_t bytesPerPixel = 0;
|
||||
|
||||
switch (dstInfo.colorType()) {
|
||||
case kRGB_565_SkColorType:
|
||||
pixelFormat = WUFFS_BASE__PIXEL_FORMAT__BGR_565;
|
||||
bytesPerPixel = 2;
|
||||
break;
|
||||
case kBGRA_8888_SkColorType:
|
||||
pixelFormat = WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL;
|
||||
bytesPerPixel = 4;
|
||||
|
@ -535,32 +535,68 @@ DEF_TEST(Codec_AnimatedTransparentGif, r) {
|
||||
ERRORF(r, "Unexpected image info");
|
||||
return;
|
||||
}
|
||||
SkBitmap bm;
|
||||
bm.allocPixels(info);
|
||||
|
||||
for (int i = 0; i < 2; i++) {
|
||||
SkColor expectedPixels[2][4] = {
|
||||
{ 0xFF800000, 0xFF900000, 0xFFA00000, 0xFFB00000 },
|
||||
{ 0xFFC00000, 0xFFD00000, 0xFFE00000, 0xFFF00000 },
|
||||
};
|
||||
if (i > 0) {
|
||||
expectedPixels[1][1] = 0xFF0000FF;
|
||||
expectedPixels[1][3] = 0xFF000055;
|
||||
}
|
||||
for (bool use565 : { false, true }) {
|
||||
SkBitmap bm;
|
||||
bm.allocPixels(use565 ? info.makeColorType(kRGB_565_SkColorType) : info);
|
||||
|
||||
SkCodec::Options options;
|
||||
options.fFrameIndex = i;
|
||||
options.fPriorFrame = (i > 0) ? (i - 1) : SkCodec::kNoFrame;
|
||||
auto result = codec->getPixels(bm.pixmap(), &options);
|
||||
REPORTER_ASSERT(r, result == SkCodec::kSuccess, "Failed to decode frame %i", i);
|
||||
for (int i = 0; i < 2; i++) {
|
||||
SkCodec::Options options;
|
||||
options.fFrameIndex = i;
|
||||
options.fPriorFrame = (i > 0) ? (i - 1) : SkCodec::kNoFrame;
|
||||
auto result = codec->getPixels(bm.pixmap(), &options);
|
||||
#ifdef SK_HAS_WUFFS_LIBRARY
|
||||
// No-op. Wuffs' GIF decoder supports animated 565.
|
||||
#else
|
||||
if (use565 && i > 0) {
|
||||
// Unsupported. Quoting libgifcodec/SkLibGifCodec.cpp:
|
||||
//
|
||||
// In theory, we might be able to support this, but it's not
|
||||
// clear that it is necessary (Chromium does not decode to 565,
|
||||
// and Android does not decode frames beyond the first).
|
||||
REPORTER_ASSERT(r, result != SkCodec::kSuccess,
|
||||
"Unexpected success to decode frame %i", i);
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
REPORTER_ASSERT(r, result == SkCodec::kSuccess, "Failed to decode frame %i", i);
|
||||
|
||||
for (int y = 0; y < 2; y++) {
|
||||
for (int x = 0; x < 4; x++) {
|
||||
auto expected = expectedPixels[y][x];
|
||||
auto actual = bm.getColor(x, y);
|
||||
REPORTER_ASSERT(r, actual == expected,
|
||||
"frame %i, pixel (%i,%i) mismatch! expected: %x actual: %x",
|
||||
i, x, y, expected, actual);
|
||||
// Per above: the first frame is full of various red pixels.
|
||||
SkColor expectedPixels[2][4] = {
|
||||
{ 0xFF800000, 0xFF900000, 0xFFA00000, 0xFFB00000 },
|
||||
{ 0xFFC00000, 0xFFD00000, 0xFFE00000, 0xFFF00000 },
|
||||
};
|
||||
if (use565) {
|
||||
// For kRGB_565_SkColorType, copy the red channel's high 3 bits
|
||||
// to its low 3 bits.
|
||||
expectedPixels[0][0] = 0xFF840000;
|
||||
expectedPixels[0][1] = 0xFF940000;
|
||||
expectedPixels[0][2] = 0xFFA50000;
|
||||
expectedPixels[0][3] = 0xFFB50000;
|
||||
expectedPixels[1][0] = 0xFFC60000;
|
||||
expectedPixels[1][1] = 0xFFD60000;
|
||||
expectedPixels[1][2] = 0xFFE70000;
|
||||
expectedPixels[1][3] = 0xFFF70000;
|
||||
}
|
||||
if (i > 0) {
|
||||
// Per above: the second frame overlays a 3x1 rectangle at (1,
|
||||
// 1): light blue, transparent, dark blue.
|
||||
//
|
||||
// Again, for kRGB_565_SkColorType, copy the blue channel's
|
||||
// high 3 bits to its low 3 bits.
|
||||
expectedPixels[1][1] = use565 ? 0xFF0000FF : 0xFF0000FF;
|
||||
expectedPixels[1][3] = use565 ? 0xFF000052 : 0xFF000055;
|
||||
}
|
||||
|
||||
for (int y = 0; y < 2; y++) {
|
||||
for (int x = 0; x < 4; x++) {
|
||||
auto expected = expectedPixels[y][x];
|
||||
auto actual = bm.getColor(x, y);
|
||||
REPORTER_ASSERT(r, actual == expected,
|
||||
"use565 %i, frame %i, pixel (%i,%i) "
|
||||
"mismatch! expected: %x actual: %x",
|
||||
(int)use565, i, x, y, expected, actual);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user