Support wbmp that are supported by SkImageDecoder
The wbmp version of SkImageDecoder will support decoding an image where the second byte can be masked away with 0x9F. Prior to this CL, SkCodec checked that the entire byte was zero. The SkCodec implementation appears to be more correct (at least according to Wikipedia [1]), but it also means we could regress if someone was using an image that did not quite fit the specification. [1] https://en.wikipedia.org/wiki/Wireless_Application_Protocol_Bitmap_Format BUG=skia:3257 Review URL: https://codereview.chromium.org/1473673005
This commit is contained in:
parent
0e7029eaef
commit
b9a1e34362
@ -29,6 +29,11 @@ static inline void setup_color_table(SkColorType colorType,
|
||||
}
|
||||
}
|
||||
|
||||
static bool read_byte(SkStream* stream, uint8_t* data)
|
||||
{
|
||||
return stream->read(data, 1) == 1;
|
||||
}
|
||||
|
||||
// http://en.wikipedia.org/wiki/Variable-length_quantity
|
||||
static bool read_mbf(SkStream* stream, uint64_t* value) {
|
||||
uint64_t n = 0;
|
||||
@ -49,11 +54,17 @@ static bool read_mbf(SkStream* stream, uint64_t* value) {
|
||||
}
|
||||
|
||||
static bool read_header(SkStream* stream, SkISize* size) {
|
||||
uint64_t width, height;
|
||||
uint16_t data;
|
||||
if (stream->read(&data, 2) != 2 || data != 0) {
|
||||
return false;
|
||||
{
|
||||
uint8_t data;
|
||||
if (!read_byte(stream, &data) || data != 0) { // unknown type
|
||||
return false;
|
||||
}
|
||||
if (!read_byte(stream, &data) || (data & 0x9F)) { // skip fixed header
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t width, height;
|
||||
if (!read_mbf(stream, &width) || width > 0xFFFF || !width) {
|
||||
return false;
|
||||
}
|
||||
|
@ -10,9 +10,11 @@
|
||||
#include "SkBitmap.h"
|
||||
#include "SkCodec.h"
|
||||
#include "SkData.h"
|
||||
#include "SkImageDecoder.h"
|
||||
#include "SkMD5.h"
|
||||
#include "SkRandom.h"
|
||||
#include "SkStream.h"
|
||||
#include "SkStreamPriv.h"
|
||||
#include "SkPngChunkReader.h"
|
||||
#include "Test.h"
|
||||
|
||||
@ -845,3 +847,33 @@ DEF_TEST(Codec_pngChunkReader, r) {
|
||||
REPORTER_ASSERT(r, chunkReader.allHaveBeenSeen());
|
||||
}
|
||||
#endif // PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
|
||||
|
||||
// SkCodec's wbmp decoder was initially more restrictive than SkImageDecoder.
|
||||
// It required the second byte to be zero. But SkImageDecoder allowed a couple
|
||||
// of bits to be 1 (so long as they do not overlap with 0x9F). Test that
|
||||
// SkCodec now supports an image with these bits set.
|
||||
DEF_TEST(Codec_wbmp, r) {
|
||||
const char* path = "mandrill.wbmp";
|
||||
SkAutoTDelete<SkStream> stream(resource(path));
|
||||
if (!stream) {
|
||||
SkDebugf("Missing resource '%s'\n", path);
|
||||
return;
|
||||
}
|
||||
|
||||
// Modify the stream to contain a second byte with some bits set.
|
||||
SkAutoTUnref<SkData> data(SkCopyStreamToData(stream));
|
||||
uint8_t* writeableData = static_cast<uint8_t*>(data->writable_data());
|
||||
writeableData[1] = static_cast<uint8_t>(~0x9F);
|
||||
|
||||
// SkImageDecoder supports this.
|
||||
SkBitmap bitmap;
|
||||
REPORTER_ASSERT(r, SkImageDecoder::DecodeMemory(data->data(), data->size(), &bitmap));
|
||||
|
||||
// So SkCodec should, too.
|
||||
SkAutoTDelete<SkCodec> codec(SkCodec::NewFromData(data));
|
||||
REPORTER_ASSERT(r, codec);
|
||||
if (!codec) {
|
||||
return;
|
||||
}
|
||||
test_info(r, codec, codec->getInfo(), SkCodec::kSuccess, nullptr);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user