Chromium Code Reviews| 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 <cmath> | 7 #include <cmath> |
| 8 | 8 |
| 9 #include "components/favicon_base/favicon_types.h" | 9 #include "components/favicon_base/favicon_types.h" |
| 10 #include "components/favicon_base/select_favicon_frames.h" | 10 #include "components/favicon_base/select_favicon_frames.h" |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 48 } | 48 } |
| 49 } | 49 } |
| 50 png_reps.push_back(gfx::ImagePNGRep(best_candidate, 1.0f)); | 50 png_reps.push_back(gfx::ImagePNGRep(best_candidate, 1.0f)); |
| 51 return png_reps; | 51 return png_reps; |
| 52 } | 52 } |
| 53 | 53 |
| 54 // Build a map which will be used to determine the scale used to | 54 // Build a map which will be used to determine the scale used to |
| 55 // create a bitmap with given pixel size. | 55 // create a bitmap with given pixel size. |
| 56 std::map<int, float> desired_pixel_sizes; | 56 std::map<int, float> desired_pixel_sizes; |
| 57 for (size_t i = 0; i < favicon_scales.size(); ++i) { | 57 for (size_t i = 0; i < favicon_scales.size(); ++i) { |
| 58 int pixel_size = std::ceil(favicon_size * favicon_scales[i]); | 58 int pixel_size = |
| 59 static_cast<int>(std::ceil(favicon_size * favicon_scales[i])); | |
| 59 desired_pixel_sizes[pixel_size] = favicon_scales[i]; | 60 desired_pixel_sizes[pixel_size] = favicon_scales[i]; |
| 60 } | 61 } |
| 61 | 62 |
| 62 for (size_t i = 0; i < png_data.size(); ++i) { | 63 for (size_t i = 0; i < png_data.size(); ++i) { |
| 63 if (!png_data[i].is_valid()) | 64 if (!png_data[i].is_valid()) |
| 64 continue; | 65 continue; |
| 65 | 66 |
| 66 const gfx::Size& pixel_size = png_data[i].pixel_size; | 67 const gfx::Size& pixel_size = png_data[i].pixel_size; |
| 67 if (pixel_size.width() != pixel_size.height()) | 68 if (pixel_size.width() != pixel_size.height()) |
| 68 continue; | 69 continue; |
| 69 | 70 |
| 70 std::map<int, float>::iterator it = | 71 std::map<int, float>::iterator it = |
| 71 desired_pixel_sizes.find(pixel_size.width()); | 72 desired_pixel_sizes.find(pixel_size.width()); |
| 72 if (it == desired_pixel_sizes.end()) | 73 if (it == desired_pixel_sizes.end()) |
| 73 continue; | 74 continue; |
| 74 | 75 |
| 75 png_reps.push_back(gfx::ImagePNGRep(png_data[i].bitmap_data, it->second)); | 76 png_reps.push_back(gfx::ImagePNGRep(png_data[i].bitmap_data, it->second)); |
| 76 } | 77 } |
| 77 | 78 |
| 78 return png_reps; | 79 return png_reps; |
| 79 } | 80 } |
| 80 | 81 |
| 81 // Returns a resampled bitmap of | 82 // Returns a resampled bitmap of |desired_size| x |desired_size| by resampling |
| 82 // |desired_size_in_pixel| x |desired_size_in_pixel| by resampling the best | 83 // the best bitmap out of |input_bitmaps|. |
|
Peter Kasting
2014/10/16 22:36:53
Changing these names was mostly to reduce the line
| |
| 83 // bitmap out of |input_bitmaps|. ResizeBitmapByDownsamplingIfPossible() is | 84 // ResizeBitmapByDownsamplingIfPossible() is similar to SelectFaviconFrames() |
| 84 // similar to SelectFaviconFrames() but it operates on bitmaps which have | 85 // but it operates on bitmaps which have already been resampled via |
| 85 // already been resampled via SelectFaviconFrames(). | 86 // SelectFaviconFrames(). |
| 86 SkBitmap ResizeBitmapByDownsamplingIfPossible( | 87 SkBitmap ResizeBitmapByDownsamplingIfPossible( |
| 87 const std::vector<SkBitmap>& input_bitmaps, | 88 const std::vector<SkBitmap>& input_bitmaps, |
| 88 int desired_size_in_pixel) { | 89 int desired_size) { |
| 89 DCHECK(!input_bitmaps.empty()); | 90 DCHECK(!input_bitmaps.empty()); |
| 90 DCHECK_NE(desired_size_in_pixel, 0); | 91 DCHECK_NE(0, desired_size); |
| 91 | 92 |
| 92 SkBitmap best_bitmap; | 93 SkBitmap best_bitmap; |
| 93 for (size_t i = 0; i < input_bitmaps.size(); ++i) { | 94 for (size_t i = 0; i < input_bitmaps.size(); ++i) { |
| 94 const SkBitmap& input_bitmap = input_bitmaps[i]; | 95 const SkBitmap& input_bitmap = input_bitmaps[i]; |
| 95 if (input_bitmap.width() == desired_size_in_pixel && | 96 if (input_bitmap.width() == desired_size && |
| 96 input_bitmap.height() == desired_size_in_pixel) { | 97 input_bitmap.height() == desired_size) { |
| 97 return input_bitmap; | 98 return input_bitmap; |
| 98 } else if (best_bitmap.isNull()) { | 99 } else if (best_bitmap.isNull()) { |
| 99 best_bitmap = input_bitmap; | 100 best_bitmap = input_bitmap; |
| 100 } else if (input_bitmap.width() >= best_bitmap.width() && | 101 } else if (input_bitmap.width() >= best_bitmap.width() && |
| 101 input_bitmap.height() >= best_bitmap.height()) { | 102 input_bitmap.height() >= best_bitmap.height()) { |
| 102 if (best_bitmap.width() < desired_size_in_pixel || | 103 if (best_bitmap.width() < desired_size || |
| 103 best_bitmap.height() < desired_size_in_pixel) { | 104 best_bitmap.height() < desired_size) { |
| 104 best_bitmap = input_bitmap; | 105 best_bitmap = input_bitmap; |
| 105 } | 106 } |
| 106 } else { | 107 } else { |
| 107 if (input_bitmap.width() >= desired_size_in_pixel && | 108 if (input_bitmap.width() >= desired_size && |
| 108 input_bitmap.height() >= desired_size_in_pixel) { | 109 input_bitmap.height() >= desired_size) { |
| 109 best_bitmap = input_bitmap; | 110 best_bitmap = input_bitmap; |
| 110 } | 111 } |
| 111 } | 112 } |
| 112 } | 113 } |
| 113 | 114 |
| 114 if (desired_size_in_pixel % best_bitmap.width() == 0 && | 115 if (desired_size % best_bitmap.width() == 0 && |
| 115 desired_size_in_pixel % best_bitmap.height() == 0) { | 116 desired_size % best_bitmap.height() == 0) { |
| 116 // Use nearest neighbour resampling if upsampling by an integer. This | 117 // Use nearest neighbour resampling if upsampling by an integer. This |
| 117 // makes the result look similar to the result of SelectFaviconFrames(). | 118 // makes the result look similar to the result of SelectFaviconFrames(). |
| 118 SkBitmap bitmap; | 119 SkBitmap bitmap; |
| 119 bitmap.allocN32Pixels(desired_size_in_pixel, desired_size_in_pixel); | 120 bitmap.allocN32Pixels(desired_size, desired_size); |
| 120 if (!best_bitmap.isOpaque()) | 121 if (!best_bitmap.isOpaque()) |
| 121 bitmap.eraseARGB(0, 0, 0, 0); | 122 bitmap.eraseARGB(0, 0, 0, 0); |
| 122 | 123 |
| 123 SkCanvas canvas(bitmap); | 124 SkCanvas canvas(bitmap); |
| 124 SkRect dest(SkRect::MakeWH(desired_size_in_pixel, desired_size_in_pixel)); | 125 canvas.drawBitmapRect( |
| 125 canvas.drawBitmapRect(best_bitmap, NULL, dest); | 126 best_bitmap, NULL, |
| 127 SkRect::MakeFromIRect(SkIRect::MakeWH(desired_size, desired_size))); | |
| 126 return bitmap; | 128 return bitmap; |
| 127 } | 129 } |
| 128 return skia::ImageOperations::Resize(best_bitmap, | 130 return skia::ImageOperations::Resize(best_bitmap, |
| 129 skia::ImageOperations::RESIZE_LANCZOS3, | 131 skia::ImageOperations::RESIZE_LANCZOS3, |
| 130 desired_size_in_pixel, | 132 desired_size, |
| 131 desired_size_in_pixel); | 133 desired_size); |
| 132 } | 134 } |
| 133 | 135 |
| 134 } // namespace | 136 } // namespace |
| 135 | 137 |
| 136 std::vector<float> GetFaviconScales() { | 138 std::vector<float> GetFaviconScales() { |
| 137 const float kScale1x = 1.0f; | 139 const float kScale1x = 1.0f; |
| 138 std::vector<ui::ScaleFactor> resource_scale_factors = | 140 std::vector<ui::ScaleFactor> resource_scale_factors = |
| 139 ui::GetSupportedScaleFactors(); | 141 ui::GetSupportedScaleFactors(); |
| 140 | 142 |
| 141 // TODO(ios): 1.0f should not be necessary on iOS retina devices. However | 143 // TODO(ios): 1.0f should not be necessary on iOS retina devices. However |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 207 bitmaps.push_back(bitmap); | 209 bitmaps.push_back(bitmap); |
| 208 } | 210 } |
| 209 } | 211 } |
| 210 | 212 |
| 211 if (bitmaps.empty()) | 213 if (bitmaps.empty()) |
| 212 return gfx::Image(); | 214 return gfx::Image(); |
| 213 | 215 |
| 214 gfx::ImageSkia resized_image_skia; | 216 gfx::ImageSkia resized_image_skia; |
| 215 for (size_t i = 0; i < favicon_scales_to_generate.size(); ++i) { | 217 for (size_t i = 0; i < favicon_scales_to_generate.size(); ++i) { |
| 216 float scale = favicon_scales_to_generate[i]; | 218 float scale = favicon_scales_to_generate[i]; |
| 217 int desired_size_in_pixel = std::ceil(favicon_size * scale); | 219 int desired_size_in_pixel = |
| 220 static_cast<int>(std::ceil(favicon_size * scale)); | |
| 218 SkBitmap bitmap = | 221 SkBitmap bitmap = |
| 219 ResizeBitmapByDownsamplingIfPossible(bitmaps, desired_size_in_pixel); | 222 ResizeBitmapByDownsamplingIfPossible(bitmaps, desired_size_in_pixel); |
| 220 resized_image_skia.AddRepresentation(gfx::ImageSkiaRep(bitmap, scale)); | 223 resized_image_skia.AddRepresentation(gfx::ImageSkiaRep(bitmap, scale)); |
| 221 } | 224 } |
| 222 | 225 |
| 223 if (png_reps.empty()) | 226 if (png_reps.empty()) |
| 224 return gfx::Image(resized_image_skia); | 227 return gfx::Image(resized_image_skia); |
| 225 | 228 |
| 226 std::vector<gfx::ImageSkiaRep> resized_image_skia_reps = | 229 std::vector<gfx::ImageSkiaRep> resized_image_skia_reps = |
| 227 resized_image_skia.image_reps(); | 230 resized_image_skia.image_reps(); |
| 228 for (size_t i = 0; i < resized_image_skia_reps.size(); ++i) { | 231 for (size_t i = 0; i < resized_image_skia_reps.size(); ++i) { |
| 229 scoped_refptr<base::RefCountedBytes> png_bytes(new base::RefCountedBytes()); | 232 scoped_refptr<base::RefCountedBytes> png_bytes(new base::RefCountedBytes()); |
| 230 if (gfx::PNGCodec::EncodeBGRASkBitmap( | 233 if (gfx::PNGCodec::EncodeBGRASkBitmap( |
| 231 resized_image_skia_reps[i].sk_bitmap(), | 234 resized_image_skia_reps[i].sk_bitmap(), |
| 232 false, | 235 false, |
| 233 &png_bytes->data())) { | 236 &png_bytes->data())) { |
| 234 png_reps.push_back( | 237 png_reps.push_back( |
| 235 gfx::ImagePNGRep(png_bytes, resized_image_skia_reps[i].scale())); | 238 gfx::ImagePNGRep(png_bytes, resized_image_skia_reps[i].scale())); |
| 236 } | 239 } |
| 237 } | 240 } |
| 238 | 241 |
| 239 return gfx::Image(png_reps); | 242 return gfx::Image(png_reps); |
| 240 } | 243 } |
| 241 | 244 |
| 242 } // namespace favicon_base | 245 } // namespace favicon_base |
| OLD | NEW |