blob: 8f898c1b065e5ce20724d39e0060207ee069bb03 [file] [log] [blame]
thestigc5eeb9f362015-04-22 18:42:321// 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 "chrome/browser/image_decoder.h"
6
avi6846aef2015-12-26 01:09:387#include "base/macros.h"
8#include "build/build_config.h"
thestig3d8ebe3a2015-05-08 03:25:329#include "chrome/grit/generated_resources.h"
thestigc5eeb9f362015-04-22 18:42:3210#include "chrome/test/base/in_process_browser_test.h"
amistryd59fe6b2015-04-30 23:50:3011#include "content/public/browser/browser_child_process_observer.h"
thestigc5eeb9f362015-04-22 18:42:3212#include "content/public/browser/browser_thread.h"
amistryd59fe6b2015-04-30 23:50:3013#include "content/public/browser/child_process_data.h"
thestigc5eeb9f362015-04-22 18:42:3214#include "content/public/test/test_utils.h"
thestig3d8ebe3a2015-05-08 03:25:3215#include "ui/base/l10n/l10n_util.h"
thestigc5eeb9f362015-04-22 18:42:3216
17using content::BrowserThread;
18
19namespace {
20
nya601d9702016-07-26 18:39:2121std::vector<uint8_t> GetValidPngData() {
thestig3d8ebe3a2015-05-08 03:25:3222 // 1x1 PNG. Does not get much smaller than this.
23 static const char kPngData[] =
24 "\x89\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52"
25 "\x00\x00\x00\x01\x00\x00\x00\x01\x08\x02\x00\x00\x00\x90\x77\x53"
26 "\xde\x00\x00\x00\x0c\x49\x44\x41\x54\x08\xd7\x63\xf8\xff\xff\x3f"
27 "\x00\x05\xfe\x02\xfe\xdc\xcc\x59\xe7\x00\x00\x00\x00\x49\x45\x4e"
28 "\x44\xae\x42\x60\x82";
29 // Need to specify the buffer size because it contains NULs.
nya601d9702016-07-26 18:39:2130 return std::vector<uint8_t>(kPngData, kPngData + sizeof(kPngData) - 1);
thestig3d8ebe3a2015-05-08 03:25:3231}
32
satoruxf7e76f02016-03-09 06:30:4533#if defined(OS_CHROMEOS)
34
nya601d9702016-07-26 18:39:2135std::vector<uint8_t> GetValidJpgData() {
satoruxf7e76f02016-03-09 06:30:4536 // 1x1 JPG created from the 1x1 PNG above.
37 static const char kJpgData[] =
38 "\xFF\xD8\xFF\xE0\x00\x10\x4A\x46\x49\x46\x00\x01\x01\x01\x00\x48"
39 "\x00\x48\x00\x00\xFF\xDB\x00\x43\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
40 "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
41 "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
42 "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
43 "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xDB\x00\x43\x01\xFF\xFF"
44 "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
45 "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
46 "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
47 "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0"
48 "\x00\x11\x08\x00\x01\x00\x01\x03\x01\x22\x00\x02\x11\x01\x03\x11"
49 "\x01\xFF\xC4\x00\x15\x00\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00"
50 "\x00\x00\x00\x00\x00\x00\x00\x03\xFF\xC4\x00\x14\x10\x01\x00\x00"
51 "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xC4"
52 "\x00\x14\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
53 "\x00\x00\x00\x00\xFF\xC4\x00\x14\x11\x01\x00\x00\x00\x00\x00\x00"
54 "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xDA\x00\x0C\x03\x01"
55 "\x00\x02\x11\x03\x11\x00\x3F\x00\xA0\x00\xFF\xD9";
56 // Need to specify the buffer size because it contains NULs.
nya601d9702016-07-26 18:39:2157 return std::vector<uint8_t>(kJpgData, kJpgData + sizeof(kJpgData) - 1);
satoruxf7e76f02016-03-09 06:30:4558}
59
60#endif // defined(OS_CHROMEOS)
61
thestigc5eeb9f362015-04-22 18:42:3262class TestImageRequest : public ImageDecoder::ImageRequest {
63 public:
64 explicit TestImageRequest(const base::Closure& quit_closure)
thestig3d8ebe3a2015-05-08 03:25:3265 : decode_succeeded_(false),
66 quit_closure_(quit_closure),
thestigc5eeb9f362015-04-22 18:42:3267 quit_called_(false) {
68 }
69
70 ~TestImageRequest() override {
71 if (!quit_called_) {
72 quit_closure_.Run();
73 }
74 }
75
thestig3d8ebe3a2015-05-08 03:25:3276 bool decode_succeeded() const { return decode_succeeded_; }
77
thestigc5eeb9f362015-04-22 18:42:3278 private:
79 void OnImageDecoded(const SkBitmap& decoded_image) override {
thestig3d8ebe3a2015-05-08 03:25:3280 decode_succeeded_ = true;
thestigc5eeb9f362015-04-22 18:42:3281 Quit();
82 }
83
84 void OnDecodeImageFailed() override {
85 Quit();
86 }
87
88 void Quit() {
89 EXPECT_FALSE(quit_called_);
90 quit_called_ = true;
91 quit_closure_.Run();
92 }
93
thestig3d8ebe3a2015-05-08 03:25:3294 bool decode_succeeded_;
95
thestigc5eeb9f362015-04-22 18:42:3296 base::Closure quit_closure_;
97 bool quit_called_;
98
99 DISALLOW_COPY_AND_ASSIGN(TestImageRequest);
100};
101
102} // namespace
103
104class ImageDecoderBrowserTest : public InProcessBrowserTest {
105};
106
107IN_PROC_BROWSER_TEST_F(ImageDecoderBrowserTest, Basic) {
108 scoped_refptr<content::MessageLoopRunner> runner =
109 new content::MessageLoopRunner;
110 TestImageRequest test_request(runner->QuitClosure());
nya601d9702016-07-26 18:39:21111 ImageDecoder::Start(&test_request, std::vector<uint8_t>());
thestigc5eeb9f362015-04-22 18:42:32112 runner->Run();
thestig3d8ebe3a2015-05-08 03:25:32113 EXPECT_FALSE(test_request.decode_succeeded());
114}
115
satoruxf7e76f02016-03-09 06:30:45116#if defined(OS_CHROMEOS)
117
nya601d9702016-07-26 18:39:21118IN_PROC_BROWSER_TEST_F(ImageDecoderBrowserTest, BasicDecodeWithOptionsString) {
119 scoped_refptr<content::MessageLoopRunner> runner =
120 new content::MessageLoopRunner;
121 TestImageRequest test_request(runner->QuitClosure());
122 const std::vector<uint8_t> data = GetValidPngData();
123 ImageDecoder::StartWithOptions(&test_request,
124 std::string(data.begin(), data.end()),
125 ImageDecoder::ROBUST_PNG_CODEC,
tschumann30ee1082017-03-02 19:37:53126 /*shrink_to_fit=*/false);
nya601d9702016-07-26 18:39:21127 runner->Run();
128 EXPECT_TRUE(test_request.decode_succeeded());
129}
130
satoruxf7e76f02016-03-09 06:30:45131IN_PROC_BROWSER_TEST_F(ImageDecoderBrowserTest, RobustJpegCodecWithJpegData) {
132 scoped_refptr<content::MessageLoopRunner> runner =
133 new content::MessageLoopRunner;
134 TestImageRequest test_request(runner->QuitClosure());
tschumann30ee1082017-03-02 19:37:53135 ImageDecoder::StartWithOptions(
136 &test_request, GetValidJpgData(), ImageDecoder::ROBUST_JPEG_CODEC,
137 /*shrink_to_fit=*/false, /*desired_image_frame_size=*/gfx::Size());
satoruxf7e76f02016-03-09 06:30:45138 runner->Run();
139 EXPECT_TRUE(test_request.decode_succeeded());
140}
141
142IN_PROC_BROWSER_TEST_F(ImageDecoderBrowserTest, RobustJpegCodecWithPngData) {
143 scoped_refptr<content::MessageLoopRunner> runner =
144 new content::MessageLoopRunner;
145 TestImageRequest test_request(runner->QuitClosure());
tschumann30ee1082017-03-02 19:37:53146 ImageDecoder::StartWithOptions(
147 &test_request, GetValidPngData(), ImageDecoder::ROBUST_JPEG_CODEC,
148 /*shrink_to_fit=*/false, /*desired_image_frame_size=*/gfx::Size());
satoruxf7e76f02016-03-09 06:30:45149 runner->Run();
150 // Should fail with PNG data because only JPEG data is allowed.
151 EXPECT_FALSE(test_request.decode_succeeded());
152}
153
154IN_PROC_BROWSER_TEST_F(ImageDecoderBrowserTest, RobustPngCodecWithPngData) {
155 scoped_refptr<content::MessageLoopRunner> runner =
156 new content::MessageLoopRunner;
157 TestImageRequest test_request(runner->QuitClosure());
tschumann30ee1082017-03-02 19:37:53158 ImageDecoder::StartWithOptions(
159 &test_request, GetValidPngData(), ImageDecoder::ROBUST_PNG_CODEC,
160 /*shrink_to_fit=*/false, /*desired_image_frame_size=*/gfx::Size());
satoruxf7e76f02016-03-09 06:30:45161 runner->Run();
162 EXPECT_TRUE(test_request.decode_succeeded());
163}
164
165IN_PROC_BROWSER_TEST_F(ImageDecoderBrowserTest, RobustPngCodecWithJpegData) {
166 scoped_refptr<content::MessageLoopRunner> runner =
167 new content::MessageLoopRunner;
168 TestImageRequest test_request(runner->QuitClosure());
tschumann30ee1082017-03-02 19:37:53169 ImageDecoder::StartWithOptions(
170 &test_request, GetValidJpgData(), ImageDecoder::ROBUST_PNG_CODEC,
171 /*shrink_to_fit=*/false, /*desired_image_frame_size=*/gfx::Size());
satoruxf7e76f02016-03-09 06:30:45172 runner->Run();
173 // Should fail with JPEG data because only PNG data is allowed.
174 EXPECT_FALSE(test_request.decode_succeeded());
175}
176
177#endif // defined(OS_CHROMEOS)
178
thestig3d8ebe3a2015-05-08 03:25:32179IN_PROC_BROWSER_TEST_F(ImageDecoderBrowserTest, BasicDecode) {
180 scoped_refptr<content::MessageLoopRunner> runner =
181 new content::MessageLoopRunner;
182 TestImageRequest test_request(runner->QuitClosure());
nya601d9702016-07-26 18:39:21183 ImageDecoder::Start(&test_request, GetValidPngData());
184 runner->Run();
185 EXPECT_TRUE(test_request.decode_succeeded());
186}
187
188IN_PROC_BROWSER_TEST_F(ImageDecoderBrowserTest, BasicDecodeString) {
189 scoped_refptr<content::MessageLoopRunner> runner =
190 new content::MessageLoopRunner;
191 TestImageRequest test_request(runner->QuitClosure());
192 const std::vector<uint8_t> data = GetValidPngData();
193 ImageDecoder::Start(&test_request, std::string(data.begin(), data.end()));
thestig3d8ebe3a2015-05-08 03:25:32194 runner->Run();
195 EXPECT_TRUE(test_request.decode_succeeded());
thestigc5eeb9f362015-04-22 18:42:32196}
197
198IN_PROC_BROWSER_TEST_F(ImageDecoderBrowserTest, StartAndDestroy) {
199 scoped_refptr<content::MessageLoopRunner> runner =
200 new content::MessageLoopRunner;
dcheng4af48582016-04-19 00:29:35201 std::unique_ptr<TestImageRequest> test_request(
thestigc5eeb9f362015-04-22 18:42:32202 new TestImageRequest(runner->QuitClosure()));
nya601d9702016-07-26 18:39:21203 ImageDecoder::Start(test_request.get(), std::vector<uint8_t>());
thestigc5eeb9f362015-04-22 18:42:32204 test_request.reset();
205 runner->Run();
206}