1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "third_party/blink/renderer/platform/image-decoders/bmp/bmp_image_decoder.h"
6
7 #include <memory>
8 #include "testing/gtest/include/gtest/gtest.h"
9 #include "third_party/blink/renderer/platform/image-decoders/image_decoder_base_test.h"
10 #include "third_party/blink/renderer/platform/image-decoders/image_decoder_test_helpers.h"
11 #include "third_party/blink/renderer/platform/wtf/shared_buffer.h"
12
13 namespace blink {
14
15 namespace {
16
CreateBMPDecoder()17 std::unique_ptr<ImageDecoder> CreateBMPDecoder() {
18 return std::make_unique<BMPImageDecoder>(
19 ImageDecoder::kAlphaNotPremultiplied, ColorBehavior::TransformToSRGB(),
20 ImageDecoder::kNoDecodedImageByteLimit);
21 }
22
23 } // anonymous namespace
24
TEST(BMPImageDecoderTest,isSizeAvailable)25 TEST(BMPImageDecoderTest, isSizeAvailable) {
26 static constexpr char kBmpFile[] = "/images/resources/lenna.bmp"; // 256x256
27 scoped_refptr<SharedBuffer> data = ReadFile(kBmpFile);
28 ASSERT_TRUE(data.get());
29
30 std::unique_ptr<ImageDecoder> decoder = CreateBMPDecoder();
31 decoder->SetData(data.get(), true);
32 EXPECT_TRUE(decoder->IsSizeAvailable());
33 EXPECT_EQ(256, decoder->Size().Width());
34 EXPECT_EQ(256, decoder->Size().Height());
35 }
36
TEST(BMPImageDecoderTest,parseAndDecode)37 TEST(BMPImageDecoderTest, parseAndDecode) {
38 static constexpr char kBmpFile[] = "/images/resources/lenna.bmp"; // 256x256
39 scoped_refptr<SharedBuffer> data = ReadFile(kBmpFile);
40 ASSERT_TRUE(data.get());
41
42 std::unique_ptr<ImageDecoder> decoder = CreateBMPDecoder();
43 decoder->SetData(data.get(), true);
44
45 ImageFrame* frame = decoder->DecodeFrameBufferAtIndex(0);
46 ASSERT_TRUE(frame);
47 EXPECT_EQ(ImageFrame::kFrameComplete, frame->GetStatus());
48 EXPECT_EQ(256, frame->Bitmap().width());
49 EXPECT_EQ(256, frame->Bitmap().height());
50 EXPECT_FALSE(decoder->Failed());
51 }
52
53 // Test if a BMP decoder returns a proper error while decoding an empty image.
TEST(BMPImageDecoderTest,emptyImage)54 TEST(BMPImageDecoderTest, emptyImage) {
55 static constexpr char kBmpFile[] = "/images/resources/0x0.bmp"; // 0x0
56 scoped_refptr<SharedBuffer> data = ReadFile(kBmpFile);
57 ASSERT_TRUE(data.get());
58
59 std::unique_ptr<ImageDecoder> decoder = CreateBMPDecoder();
60 decoder->SetData(data.get(), true);
61
62 ImageFrame* frame = decoder->DecodeFrameBufferAtIndex(0);
63 ASSERT_TRUE(frame);
64 EXPECT_EQ(ImageFrame::kFrameEmpty, frame->GetStatus());
65 EXPECT_TRUE(decoder->Failed());
66 }
67
TEST(BMPImageDecoderTest,int32MinHeight)68 TEST(BMPImageDecoderTest, int32MinHeight) {
69 static constexpr char kBmpFile[] =
70 "/images/resources/1xint32_min.bmp"; // 0xINT32_MIN
71 scoped_refptr<SharedBuffer> data = ReadFile(kBmpFile);
72 std::unique_ptr<ImageDecoder> decoder = CreateBMPDecoder();
73 // Test when not all data is received.
74 decoder->SetData(data.get(), false);
75 EXPECT_FALSE(decoder->IsSizeAvailable());
76 EXPECT_TRUE(decoder->Failed());
77 }
78
79 // This test verifies that calling SharedBuffer::MergeSegmentsIntoBuffer() does
80 // not break BMP decoding at a critical point: in between a call to decode the
81 // size (when BMPImageDecoder stops while it may still have input data to
82 // read) and a call to do a full decode.
TEST(BMPImageDecoderTest,mergeBuffer)83 TEST(BMPImageDecoderTest, mergeBuffer) {
84 static constexpr char kBmpFile[] = "/images/resources/lenna.bmp";
85 TestMergeBuffer(&CreateBMPDecoder, kBmpFile);
86 }
87
88 // Verify that decoding this image does not crash.
TEST(BMPImageDecoderTest,crbug752898)89 TEST(BMPImageDecoderTest, crbug752898) {
90 static constexpr char kBmpFile[] = "/images/resources/crbug752898.bmp";
91 scoped_refptr<SharedBuffer> data = ReadFile(kBmpFile);
92 ASSERT_TRUE(data.get());
93
94 std::unique_ptr<ImageDecoder> decoder = CreateBMPDecoder();
95 decoder->SetData(data.get(), true);
96 decoder->DecodeFrameBufferAtIndex(0);
97 }
98
99 class BMPImageDecoderCorpusTest : public ImageDecoderBaseTest {
100 public:
BMPImageDecoderCorpusTest()101 BMPImageDecoderCorpusTest() : ImageDecoderBaseTest("bmp") {}
102
103 protected:
CreateImageDecoder() const104 std::unique_ptr<ImageDecoder> CreateImageDecoder() const override {
105 return std::make_unique<BMPImageDecoder>(
106 ImageDecoder::kAlphaPremultiplied, ColorBehavior::TransformToSRGB(),
107 ImageDecoder::kNoDecodedImageByteLimit);
108 }
109
110 // The BMPImageDecoderCorpusTest tests are really slow under Valgrind.
111 // Thus it is split into fast and slow versions. The threshold is
112 // set to 10KB because the fast test can finish under Valgrind in
113 // less than 30 seconds.
114 static const int64_t kThresholdSize = 10240;
115 };
116
TEST_F(BMPImageDecoderCorpusTest,DecodingFast)117 TEST_F(BMPImageDecoderCorpusTest, DecodingFast) {
118 TestDecoding(FileSelection::kSmaller, kThresholdSize);
119 }
120
121 #if defined(THREAD_SANITIZER)
122 // BMPImageDecoderCorpusTest.DecodingSlow always times out under ThreadSanitizer
123 // v2.
124 #define MAYBE_DecodingSlow DISABLED_DecodingSlow
125 #else
126 #define MAYBE_DecodingSlow DecodingSlow
127 #endif
TEST_F(BMPImageDecoderCorpusTest,MAYBE_DecodingSlow)128 TEST_F(BMPImageDecoderCorpusTest, MAYBE_DecodingSlow) {
129 TestDecoding(FileSelection::kBigger, kThresholdSize);
130 }
131
132 } // namespace blink
133