OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "components/favicon_base/favicon_util.h" | 5 #include "components/favicon_base/favicon_util.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 | 8 |
9 #include <algorithm> | 9 #include <algorithm> |
10 #include <cmath> | 10 #include <cmath> |
11 | 11 |
| 12 #include "base/trace_event/trace_event.h" |
12 #include "build/build_config.h" | 13 #include "build/build_config.h" |
13 #include "components/favicon_base/favicon_types.h" | 14 #include "components/favicon_base/favicon_types.h" |
14 #include "components/favicon_base/select_favicon_frames.h" | 15 #include "components/favicon_base/select_favicon_frames.h" |
15 #include "skia/ext/image_operations.h" | 16 #include "skia/ext/image_operations.h" |
16 #include "third_party/skia/include/core/SkBitmap.h" | 17 #include "third_party/skia/include/core/SkBitmap.h" |
17 #include "third_party/skia/include/core/SkCanvas.h" | 18 #include "third_party/skia/include/core/SkCanvas.h" |
18 #include "ui/base/layout.h" | 19 #include "ui/base/layout.h" |
19 #include "ui/gfx/codec/png_codec.h" | 20 #include "ui/gfx/codec/png_codec.h" |
20 #include "ui/gfx/favicon_size.h" | 21 #include "ui/gfx/favicon_size.h" |
21 #include "ui/gfx/geometry/size.h" | 22 #include "ui/gfx/geometry/size.h" |
22 #include "ui/gfx/image/image_png_rep.h" | 23 #include "ui/gfx/image/image_png_rep.h" |
23 #include "ui/gfx/image/image_skia.h" | 24 #include "ui/gfx/image/image_skia.h" |
24 | 25 |
25 #if defined(OS_MACOSX) && !defined(OS_IOS) | 26 #if defined(OS_MACOSX) && !defined(OS_IOS) |
26 #include "base/mac/mac_util.h" | 27 #include "base/mac/mac_util.h" |
27 #endif // defined(OS_MACOSX) && !defined(OS_IOS) | 28 #endif // defined(OS_MACOSX) && !defined(OS_IOS) |
28 | 29 |
29 namespace favicon_base { | 30 namespace favicon_base { |
30 namespace { | 31 namespace { |
31 | 32 |
32 // Creates image reps of DIP size |favicon_size| for the subset of | 33 // Creates image reps of DIP size |favicon_size| for the subset of |
33 // |favicon_scales| for which the image reps can be created without resizing | 34 // |favicon_scales| for which the image reps can be created without resizing |
34 // or decoding the bitmap data. | 35 // or decoding the bitmap data. |
35 std::vector<gfx::ImagePNGRep> SelectFaviconFramesFromPNGsWithoutResizing( | 36 std::vector<gfx::ImagePNGRep> SelectFaviconFramesFromPNGsWithoutResizing( |
36 const std::vector<favicon_base::FaviconRawBitmapResult>& png_data, | 37 const std::vector<favicon_base::FaviconRawBitmapResult>& png_data, |
37 const std::vector<float>& favicon_scales, | 38 const std::vector<float>& favicon_scales, |
38 int favicon_size) { | 39 int favicon_size) { |
| 40 TRACE_EVENT0("browser", |
| 41 "FaviconUtil::SelectFaviconFramesFromPNGsWithoutResizing"); |
39 std::vector<gfx::ImagePNGRep> png_reps; | 42 std::vector<gfx::ImagePNGRep> png_reps; |
40 if (png_data.empty()) | 43 if (png_data.empty()) |
41 return png_reps; | 44 return png_reps; |
42 | 45 |
43 // A |favicon_size| of 0 indicates that the largest frame is desired. | 46 // A |favicon_size| of 0 indicates that the largest frame is desired. |
44 if (favicon_size == 0) { | 47 if (favicon_size == 0) { |
45 int maximum_area = 0; | 48 int maximum_area = 0; |
46 scoped_refptr<base::RefCountedMemory> best_candidate; | 49 scoped_refptr<base::RefCountedMemory> best_candidate; |
47 for (size_t i = 0; i < png_data.size(); ++i) { | 50 for (size_t i = 0; i < png_data.size(); ++i) { |
48 int area = png_data[i].pixel_size.GetArea(); | 51 int area = png_data[i].pixel_size.GetArea(); |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
159 void SetFaviconColorSpace(gfx::Image* image) { | 162 void SetFaviconColorSpace(gfx::Image* image) { |
160 #if defined(OS_MACOSX) && !defined(OS_IOS) | 163 #if defined(OS_MACOSX) && !defined(OS_IOS) |
161 image->SetSourceColorSpace(base::mac::GetSystemColorSpace()); | 164 image->SetSourceColorSpace(base::mac::GetSystemColorSpace()); |
162 #endif // defined(OS_MACOSX) && !defined(OS_IOS) | 165 #endif // defined(OS_MACOSX) && !defined(OS_IOS) |
163 } | 166 } |
164 | 167 |
165 gfx::Image SelectFaviconFramesFromPNGs( | 168 gfx::Image SelectFaviconFramesFromPNGs( |
166 const std::vector<favicon_base::FaviconRawBitmapResult>& png_data, | 169 const std::vector<favicon_base::FaviconRawBitmapResult>& png_data, |
167 const std::vector<float>& favicon_scales, | 170 const std::vector<float>& favicon_scales, |
168 int favicon_size) { | 171 int favicon_size) { |
| 172 TRACE_EVENT0("browser", "FaviconUtil::SelectFaviconFramesFromPNGs"); |
| 173 |
169 // Create image reps for as many scales as possible without resizing | 174 // Create image reps for as many scales as possible without resizing |
170 // the bitmap data or decoding it. FaviconHandler stores already resized | 175 // the bitmap data or decoding it. FaviconHandler stores already resized |
171 // favicons into history so no additional resizing should be needed in the | 176 // favicons into history so no additional resizing should be needed in the |
172 // common case. | 177 // common case. |
173 // Creating the gfx::Image from |png_data| without resizing or decoding if | 178 // Creating the gfx::Image from |png_data| without resizing or decoding if |
174 // possible is important because: | 179 // possible is important because: |
175 // - Sync does a byte-to-byte comparison of gfx::Image::As1xPNGBytes() to | 180 // - Sync does a byte-to-byte comparison of gfx::Image::As1xPNGBytes() to |
176 // the data it put into the database in order to determine whether any | 181 // the data it put into the database in order to determine whether any |
177 // updates should be pushed to sync. | 182 // updates should be pushed to sync. |
178 // - The decoding occurs on the UI thread and the decoding can be a | 183 // - The decoding occurs on the UI thread and the decoding can be a |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
238 false, | 243 false, |
239 &png_bytes->data())) { | 244 &png_bytes->data())) { |
240 png_reps.push_back( | 245 png_reps.push_back( |
241 gfx::ImagePNGRep(png_bytes, resized_image_skia_reps[i].scale())); | 246 gfx::ImagePNGRep(png_bytes, resized_image_skia_reps[i].scale())); |
242 } | 247 } |
243 } | 248 } |
244 | 249 |
245 return gfx::Image(png_reps); | 250 return gfx::Image(png_reps); |
246 } | 251 } |
247 | 252 |
| 253 favicon_base::FaviconRawBitmapResult ResizeFaviconBitmapResult( |
| 254 const std::vector<favicon_base::FaviconRawBitmapResult>& |
| 255 favicon_bitmap_results, |
| 256 int desired_size_in_pixel) { |
| 257 TRACE_EVENT0("browser", "FaviconUtil::ResizeFaviconBitmapResult"); |
| 258 |
| 259 if (favicon_bitmap_results.empty() || !favicon_bitmap_results[0].is_valid()) |
| 260 return favicon_base::FaviconRawBitmapResult(); |
| 261 |
| 262 favicon_base::FaviconRawBitmapResult bitmap_result = |
| 263 favicon_bitmap_results[0]; |
| 264 |
| 265 // If the desired size is 0, SelectFaviconFrames() will return the largest |
| 266 // bitmap without doing any resizing. As |favicon_bitmap_results| has bitmap |
| 267 // data for a single bitmap, return it and avoid an unnecessary decode. |
| 268 if (desired_size_in_pixel == 0) |
| 269 return bitmap_result; |
| 270 |
| 271 // If history bitmap is already desired pixel size, return early. |
| 272 if (bitmap_result.pixel_size.width() == desired_size_in_pixel && |
| 273 bitmap_result.pixel_size.height() == desired_size_in_pixel) |
| 274 return bitmap_result; |
| 275 |
| 276 // Convert raw bytes to SkBitmap, resize via SelectFaviconFrames(), then |
| 277 // convert back. |
| 278 std::vector<float> desired_favicon_scales; |
| 279 desired_favicon_scales.push_back(1.0f); |
| 280 |
| 281 gfx::Image resized_image = favicon_base::SelectFaviconFramesFromPNGs( |
| 282 favicon_bitmap_results, desired_favicon_scales, desired_size_in_pixel); |
| 283 |
| 284 std::vector<unsigned char> resized_bitmap_data; |
| 285 if (!gfx::PNGCodec::EncodeBGRASkBitmap(resized_image.AsBitmap(), false, |
| 286 &resized_bitmap_data)) { |
| 287 return favicon_base::FaviconRawBitmapResult(); |
| 288 } |
| 289 |
| 290 bitmap_result.bitmap_data = base::RefCountedBytes::TakeVector( |
| 291 &resized_bitmap_data); |
| 292 bitmap_result.pixel_size = |
| 293 gfx::Size(desired_size_in_pixel, desired_size_in_pixel); |
| 294 |
| 295 return bitmap_result; |
| 296 } |
| 297 |
248 } // namespace favicon_base | 298 } // namespace favicon_base |
OLD | NEW |