blob: 996dac4150720b4689b5e21d9f1a84e470ed5662 [file] [log] [blame]
[email protected]98af9aca2010-03-14 19:06:301// Copyright (c) 2010 The Chromium Authors. All rights reserved.
license.botbf09a502008-08-24 00:55:552// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
initial.commit09911bf2008-07-26 23:55:294
initial.commit09911bf2008-07-26 23:55:295#include "base/file_util.h"
6#include "base/path_service.h"
[email protected]38658102010-07-30 14:01:597#include "base/scoped_ptr.h"
[email protected]98af9aca2010-03-14 19:06:308#include "gfx/gfx_paths.h"
[email protected]1125d802010-03-13 08:26:329#include "gfx/icon_util.h"
[email protected]e0fc2f12010-03-14 23:30:5910#include "gfx/size.h"
initial.commit09911bf2008-07-26 23:55:2911#include "testing/gtest/include/gtest/gtest.h"
[email protected]38658102010-07-30 14:01:5912#include "third_party/skia/include/core/SkBitmap.h"
initial.commit09911bf2008-07-26 23:55:2913
14namespace {
15
[email protected]38658102010-07-30 14:01:5916static const char kSmallIconName[] = "icon_util/16_X_16_icon.ico";
17static const char kLargeIconName[] = "icon_util/128_X_128_icon.ico";
18static const char kTempIconFilename[] = "temp_test_icon.ico";
initial.commit09911bf2008-07-26 23:55:2919
[email protected]38658102010-07-30 14:01:5920class IconUtilTest : public testing::Test {
21 public:
22 IconUtilTest() {
23 PathService::Get(gfx::DIR_TEST_DATA, &test_data_directory_);
24 }
25 ~IconUtilTest() {}
initial.commit09911bf2008-07-26 23:55:2926
[email protected]38658102010-07-30 14:01:5927 static const int kSmallIconWidth = 16;
28 static const int kSmallIconHeight = 16;
29 static const int kLargeIconWidth = 128;
30 static const int kLargeIconHeight = 128;
initial.commit09911bf2008-07-26 23:55:2931
[email protected]38658102010-07-30 14:01:5932 // Given a file name for an .ico file and an image dimentions, this
33 // function loads the icon and returns an HICON handle.
34 HICON LoadIconFromFile(const FilePath& filename, int width, int height) {
35 HICON icon = static_cast<HICON>(LoadImage(NULL,
36 filename.value().c_str(),
37 IMAGE_ICON,
38 width,
39 height,
40 LR_LOADTRANSPARENT | LR_LOADFROMFILE));
41 return icon;
42 }
initial.commit09911bf2008-07-26 23:55:2943
[email protected]38658102010-07-30 14:01:5944 protected:
45 // The root directory for test files.
46 FilePath test_data_directory_;
initial.commit09911bf2008-07-26 23:55:2947
[email protected]38658102010-07-30 14:01:5948 private:
49 DISALLOW_COPY_AND_ASSIGN(IconUtilTest);
initial.commit09911bf2008-07-26 23:55:2950};
51
[email protected]38658102010-07-30 14:01:5952} // namespace
53
initial.commit09911bf2008-07-26 23:55:2954// The following test case makes sure IconUtil::SkBitmapFromHICON fails
55// gracefully when called with invalid input parameters.
56TEST_F(IconUtilTest, TestIconToBitmapInvalidParameters) {
[email protected]38658102010-07-30 14:01:5957 FilePath icon_filename = test_data_directory_.AppendASCII(kSmallIconName);
initial.commit09911bf2008-07-26 23:55:2958 gfx::Size icon_size(kSmallIconWidth, kSmallIconHeight);
59 HICON icon = LoadIconFromFile(icon_filename,
60 icon_size.width(),
61 icon_size.height());
62 ASSERT_TRUE(icon != NULL);
63
64 // Invalid size parameter.
65 gfx::Size invalid_icon_size(kSmallIconHeight, 0);
66 EXPECT_EQ(IconUtil::CreateSkBitmapFromHICON(icon, invalid_icon_size),
67 static_cast<SkBitmap*>(NULL));
68
69 // Invalid icon.
70 EXPECT_EQ(IconUtil::CreateSkBitmapFromHICON(NULL, icon_size),
71 static_cast<SkBitmap*>(NULL));
72
73 // The following code should succeed.
74 scoped_ptr<SkBitmap> bitmap;
75 bitmap.reset(IconUtil::CreateSkBitmapFromHICON(icon, icon_size));
76 EXPECT_NE(bitmap.get(), static_cast<SkBitmap*>(NULL));
77 ::DestroyIcon(icon);
78}
79
80// The following test case makes sure IconUtil::CreateHICONFromSkBitmap fails
81// gracefully when called with invalid input parameters.
82TEST_F(IconUtilTest, TestBitmapToIconInvalidParameters) {
83 HICON icon = NULL;
84 scoped_ptr<SkBitmap> bitmap;
85
86 // Wrong bitmap format.
87 bitmap.reset(new SkBitmap);
88 ASSERT_NE(bitmap.get(), static_cast<SkBitmap*>(NULL));
89 bitmap->setConfig(SkBitmap::kA8_Config, kSmallIconWidth, kSmallIconHeight);
90 icon = IconUtil::CreateHICONFromSkBitmap(*bitmap);
91 EXPECT_EQ(icon, static_cast<HICON>(NULL));
92
93 // Invalid bitmap size.
94 bitmap.reset(new SkBitmap);
95 ASSERT_NE(bitmap.get(), static_cast<SkBitmap*>(NULL));
96 bitmap->setConfig(SkBitmap::kARGB_8888_Config, 0, 0);
97 icon = IconUtil::CreateHICONFromSkBitmap(*bitmap);
98 EXPECT_EQ(icon, static_cast<HICON>(NULL));
99
100 // Valid bitmap configuration but no pixels allocated.
101 bitmap.reset(new SkBitmap);
102 ASSERT_NE(bitmap.get(), static_cast<SkBitmap*>(NULL));
103 bitmap->setConfig(SkBitmap::kARGB_8888_Config,
104 kSmallIconWidth,
105 kSmallIconHeight);
106 icon = IconUtil::CreateHICONFromSkBitmap(*bitmap);
107 EXPECT_TRUE(icon == NULL);
108}
109
110// The following test case makes sure IconUtil::CreateIconFileFromSkBitmap
111// fails gracefully when called with invalid input parameters.
112TEST_F(IconUtilTest, TestCreateIconFileInvalidParameters) {
113 scoped_ptr<SkBitmap> bitmap;
[email protected]38658102010-07-30 14:01:59114 FilePath valid_icon_filename = test_data_directory_.AppendASCII(
115 kSmallIconName);
initial.commit09911bf2008-07-26 23:55:29116 std::wstring invalid_icon_filename(L"C:\\<>?.ico");
117
118 // Wrong bitmap format.
119 bitmap.reset(new SkBitmap);
120 ASSERT_NE(bitmap.get(), static_cast<SkBitmap*>(NULL));
121 bitmap->setConfig(SkBitmap::kA8_Config, kSmallIconWidth, kSmallIconHeight);
122 EXPECT_FALSE(IconUtil::CreateIconFileFromSkBitmap(*bitmap,
123 valid_icon_filename));
124
125 // Invalid bitmap size.
126 bitmap.reset(new SkBitmap);
127 ASSERT_NE(bitmap.get(), static_cast<SkBitmap*>(NULL));
128 bitmap->setConfig(SkBitmap::kARGB_8888_Config, 0, 0);
129 EXPECT_FALSE(IconUtil::CreateIconFileFromSkBitmap(*bitmap,
130 valid_icon_filename));
131
132 // Bitmap with no allocated pixels.
133 bitmap.reset(new SkBitmap);
134 ASSERT_NE(bitmap.get(), static_cast<SkBitmap*>(NULL));
135 bitmap->setConfig(SkBitmap::kARGB_8888_Config,
136 kSmallIconWidth,
137 kSmallIconHeight);
138 EXPECT_FALSE(IconUtil::CreateIconFileFromSkBitmap(*bitmap,
139 valid_icon_filename));
140
141 // Invalid file name.
142 bitmap->allocPixels();
[email protected]0006be642008-08-27 16:43:19143 // Setting the pixels to black.
144 memset(bitmap->getPixels(), 0, bitmap->width() * bitmap->height() * 4);
initial.commit09911bf2008-07-26 23:55:29145 EXPECT_FALSE(IconUtil::CreateIconFileFromSkBitmap(*bitmap,
146 invalid_icon_filename));
147}
148
149// This test case makes sure that when we load an icon from disk and convert
150// the HICON into a bitmap, the bitmap has the expected format and dimentions.
151TEST_F(IconUtilTest, TestCreateSkBitmapFromHICON) {
152 scoped_ptr<SkBitmap> bitmap;
[email protected]38658102010-07-30 14:01:59153 FilePath small_icon_filename = test_data_directory_.AppendASCII(
154 kSmallIconName);
initial.commit09911bf2008-07-26 23:55:29155 gfx::Size small_icon_size(kSmallIconWidth, kSmallIconHeight);
156 HICON small_icon = LoadIconFromFile(small_icon_filename,
157 small_icon_size.width(),
158 small_icon_size.height());
159 ASSERT_NE(small_icon, static_cast<HICON>(NULL));
160 bitmap.reset(IconUtil::CreateSkBitmapFromHICON(small_icon, small_icon_size));
161 ASSERT_NE(bitmap.get(), static_cast<SkBitmap*>(NULL));
162 EXPECT_EQ(bitmap->width(), small_icon_size.width());
163 EXPECT_EQ(bitmap->height(), small_icon_size.height());
164 EXPECT_EQ(bitmap->config(), SkBitmap::kARGB_8888_Config);
165 ::DestroyIcon(small_icon);
166
[email protected]38658102010-07-30 14:01:59167 FilePath large_icon_filename = test_data_directory_.AppendASCII(
168 kLargeIconName);
initial.commit09911bf2008-07-26 23:55:29169 gfx::Size large_icon_size(kLargeIconWidth, kLargeIconHeight);
170 HICON large_icon = LoadIconFromFile(large_icon_filename,
171 large_icon_size.width(),
172 large_icon_size.height());
173 ASSERT_NE(large_icon, static_cast<HICON>(NULL));
174 bitmap.reset(IconUtil::CreateSkBitmapFromHICON(large_icon, large_icon_size));
175 ASSERT_NE(bitmap.get(), static_cast<SkBitmap*>(NULL));
176 EXPECT_EQ(bitmap->width(), large_icon_size.width());
177 EXPECT_EQ(bitmap->height(), large_icon_size.height());
178 EXPECT_EQ(bitmap->config(), SkBitmap::kARGB_8888_Config);
179 ::DestroyIcon(large_icon);
180}
181
182// This test case makes sure that when an HICON is created from an SkBitmap,
183// the returned handle is valid and refers to an icon with the expected
184// dimentions color depth etc.
185TEST_F(IconUtilTest, TestBasicCreateHICONFromSkBitmap) {
186 scoped_ptr<SkBitmap> bitmap;
187 bitmap.reset(new SkBitmap);
188 ASSERT_NE(bitmap.get(), static_cast<SkBitmap*>(NULL));
189 bitmap->setConfig(SkBitmap::kARGB_8888_Config,
190 kSmallIconWidth,
191 kSmallIconHeight);
192 bitmap->allocPixels();
193 HICON icon = IconUtil::CreateHICONFromSkBitmap(*bitmap);
194 EXPECT_NE(icon, static_cast<HICON>(NULL));
195 ICONINFO icon_info;
196 ASSERT_TRUE(::GetIconInfo(icon, &icon_info));
197 EXPECT_TRUE(icon_info.fIcon);
198
199 // Now that have the icon information, we should obtain the specification of
200 // the icon's bitmap and make sure it matches the specification of the
201 // SkBitmap we started with.
202 //
203 // The bitmap handle contained in the icon information is a handle to a
204 // compatible bitmap so we need to call ::GetDIBits() in order to retrieve
205 // the bitmap's header information.
206 BITMAPINFO bitmap_info;
207 ::ZeroMemory(&bitmap_info, sizeof(BITMAPINFO));
208 bitmap_info.bmiHeader.biSize = sizeof(BITMAPINFO);
209 HDC hdc = ::GetDC(NULL);
210 int result = ::GetDIBits(hdc,
211 icon_info.hbmColor,
212 0,
213 kSmallIconWidth,
214 NULL,
215 &bitmap_info,
216 DIB_RGB_COLORS);
217 ASSERT_GT(result, 0);
218 EXPECT_EQ(bitmap_info.bmiHeader.biWidth, kSmallIconWidth);
219 EXPECT_EQ(bitmap_info.bmiHeader.biHeight, kSmallIconHeight);
220 EXPECT_EQ(bitmap_info.bmiHeader.biPlanes, 1);
221 EXPECT_EQ(bitmap_info.bmiHeader.biBitCount, 32);
222 ::ReleaseDC(NULL, hdc);
223 ::DestroyIcon(icon);
224}
225
226// The following test case makes sure IconUtil::CreateIconFileFromSkBitmap
227// creates a valid .ico file given an SkBitmap.
228TEST_F(IconUtilTest, TestCreateIconFile) {
229 scoped_ptr<SkBitmap> bitmap;
[email protected]38658102010-07-30 14:01:59230 FilePath icon_filename = test_data_directory_.AppendASCII(kTempIconFilename);
initial.commit09911bf2008-07-26 23:55:29231
232 // Allocating the bitmap.
233 bitmap.reset(new SkBitmap);
234 ASSERT_NE(bitmap.get(), static_cast<SkBitmap*>(NULL));
235 bitmap->setConfig(SkBitmap::kARGB_8888_Config,
236 kSmallIconWidth,
237 kSmallIconHeight);
238 bitmap->allocPixels();
239
240 // Setting the pixels to black.
241 memset(bitmap->getPixels(), 0, bitmap->width() * bitmap->height() * 4);
242
243 EXPECT_TRUE(IconUtil::CreateIconFileFromSkBitmap(*bitmap,
244 icon_filename));
245
246 // We are currently only testing that it is possible to load an icon from
247 // the .ico file we just created. We don't really check the additional icon
248 // images created by IconUtil::CreateIconFileFromSkBitmap.
249 HICON icon = LoadIconFromFile(icon_filename,
250 kSmallIconWidth,
251 kSmallIconHeight);
252 EXPECT_NE(icon, static_cast<HICON>(NULL));
253 if (icon != NULL) {
254 ::DestroyIcon(icon);
255 }
256}