select_favicon_frames.cc revision 5c02ac1a9c1b504631c0a3d2b6e737b5d738bae1
15c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// Copyright 2014 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "components/favicon_base/select_favicon_frames.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include <limits> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <set> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "skia/ext/image_operations.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/skia/include/core/SkCanvas.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/image/image.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/image/image_skia.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/size.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)size_t BiggestCandidate(const std::vector<gfx::Size>& candidate_sizes) { 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t max_index = 0; 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int max_area = candidate_sizes[0].GetArea(); 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 1; i < candidate_sizes.size(); ++i) { 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int area = candidate_sizes[i].GetArea(); 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (area > max_area) { 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) max_area = area; 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) max_index = i; 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return max_index; 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SkBitmap SampleNearestNeighbor(const SkBitmap& contents, int desired_size) { 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkBitmap bitmap; 335c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu bitmap.setConfig(SkBitmap::kARGB_8888_Config, desired_size, desired_size); 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bitmap.allocPixels(); 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!contents.isOpaque()) 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bitmap.eraseARGB(0, 0, 0, 0); 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkCanvas canvas(bitmap); 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkRect dest(SkRect::MakeWH(desired_size, desired_size)); 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) canvas.drawBitmapRect(contents, NULL, dest); 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return bitmap; 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 475c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuenum ResizeMethod { NONE, SAMPLE_NEAREST_NEIGHBOUR, LANCZOS }; 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)size_t GetCandidateIndexWithBestScore( 5058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const std::vector<gfx::Size>& candidate_sizes_in_pixel, 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui::ScaleFactor scale_factor, 5258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) int desired_size_in_dip, 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) float* score, 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResizeMethod* resize_method) { 5558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) DCHECK_NE(desired_size_in_dip, 0); 5658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 5768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) float scale = ui::GetImageScale(scale_factor); 5858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) int desired_size_in_pixel = 5958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) static_cast<int>(desired_size_in_dip * scale + 0.5f); 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Try to find an exact match. 6258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) for (size_t i = 0; i < candidate_sizes_in_pixel.size(); ++i) { 6358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (candidate_sizes_in_pixel[i].width() == desired_size_in_pixel && 6458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) candidate_sizes_in_pixel[i].height() == desired_size_in_pixel) { 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *score = 1; 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *resize_method = NONE; 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return i; 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // Huge favicon bitmaps often have a completely different visual style from 7258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // smaller favicon bitmaps. Avoid these favicon bitmaps when a favicon of 7358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // gfx::kFaviconSize DIP is requested. 7458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const int kHugeEdgeSizeInPixel = desired_size_in_pixel * 8; 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // Order of preference: 7758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // 1) Bitmaps with width and height smaller than |kHugeEdgeSizeInPixel|. 7858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // 2) Bitmaps which need to be scaled down instead of up. 7958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // 3) Bitmaps which do not need to be scaled as much. 805c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu size_t candidate_index = std::numeric_limits<size_t>::max(); 8158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) float candidate_score = 0; 8258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) for (size_t i = 0; i < candidate_sizes_in_pixel.size(); ++i) { 8358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) float average_edge_in_pixel = (candidate_sizes_in_pixel[i].width() + 845c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu candidate_sizes_in_pixel[i].height()) / 855c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 2.0f; 8658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 8758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) float score = 0; 8858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (candidate_sizes_in_pixel[i].width() >= kHugeEdgeSizeInPixel || 8958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) candidate_sizes_in_pixel[i].height() >= kHugeEdgeSizeInPixel) { 905c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu score = 915c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu std::min(1.0f, desired_size_in_pixel / average_edge_in_pixel) * 0.01f; 9258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } else if (candidate_sizes_in_pixel[i].width() >= desired_size_in_pixel && 9358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) candidate_sizes_in_pixel[i].height() >= desired_size_in_pixel) { 9458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) score = desired_size_in_pixel / average_edge_in_pixel * 0.01f + 0.15f; 9558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } else { 9658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) score = std::min(1.0f, average_edge_in_pixel / desired_size_in_pixel) * 975c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 0.01f + 985c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 0.1f; 9958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 10058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 1015c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (candidate_index == std::numeric_limits<size_t>::max() || 1025c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu score > candidate_score) { 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) candidate_index = i; 10458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) candidate_score = score; 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) *score = candidate_score; 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // Integer multiples are built using nearest neighbor sampling. Otherwise, 11058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // Lanczos scaling is used. 11158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const gfx::Size& candidate_size_in_pixel = 11258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) candidate_sizes_in_pixel[candidate_index]; 11358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (candidate_size_in_pixel.IsEmpty()) { 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *resize_method = NONE; 11558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } else if (desired_size_in_pixel % candidate_size_in_pixel.width() == 0 && 11658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) desired_size_in_pixel % candidate_size_in_pixel.height() == 0) { 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *resize_method = SAMPLE_NEAREST_NEIGHBOUR; 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *resize_method = LANCZOS; 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return candidate_index; 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Represents the index of the best candidate for a |scale_factor| from the 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// |candidate_sizes| passed into GetCandidateIndicesWithBestScores(). 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct SelectionResult { 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // index in |candidate_sizes| of the best candidate. 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t index; 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The ScaleFactor for which |index| is the best candidate. 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui::ScaleFactor scale_factor; 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // How the bitmap data that the bitmap with |candidate_sizes[index]| should 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // be resized for displaying in the UI. 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResizeMethod resize_method; 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GetCandidateIndicesWithBestScores( 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::vector<gfx::Size>& candidate_sizes, 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::vector<ui::ScaleFactor>& scale_factors, 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int desired_size, 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) float* match_score, 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<SelectionResult>* results) { 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (candidate_sizes.empty()) { 1450529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (match_score) 1460529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch *match_score = 0.0f; 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (desired_size == 0) { 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Just return the biggest image available. 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SelectionResult result; 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result.index = BiggestCandidate(candidate_sizes); 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result.scale_factor = ui::SCALE_FACTOR_100P; 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result.resize_method = NONE; 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) results->push_back(result); 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (match_score) 15858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) *match_score = 1.0f; 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) float total_score = 0; 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < scale_factors.size(); ++i) { 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) float score; 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SelectionResult result; 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result.scale_factor = scale_factors[i]; 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result.index = GetCandidateIndexWithBestScore(candidate_sizes, 1685c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu result.scale_factor, 1695c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu desired_size, 1705c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu &score, 1715c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu &result.resize_method); 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) results->push_back(result); 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) total_score += score; 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (match_score) 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *match_score = total_score / scale_factors.size(); 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Resize |source_bitmap| using |resize_method|. 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SkBitmap GetResizedBitmap(const SkBitmap& source_bitmap, 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int desired_size_in_dip, 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui::ScaleFactor scale_factor, 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResizeMethod resize_method) { 18568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) float scale = ui::GetImageScale(scale_factor); 1865c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu int desired_size_in_pixel = 1875c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu static_cast<int>(desired_size_in_dip * scale + 0.5f); 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) switch (resize_method) { 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case NONE: 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return source_bitmap; 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SAMPLE_NEAREST_NEIGHBOUR: 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SampleNearestNeighbor(source_bitmap, desired_size_in_pixel); 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case LANCZOS: 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return skia::ImageOperations::Resize( 1965c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu source_bitmap, 1975c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu skia::ImageOperations::RESIZE_LANCZOS3, 1985c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu desired_size_in_pixel, 1995c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu desired_size_in_pixel); 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return source_bitmap; 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const float kSelectFaviconFramesInvalidScore = -1.0f; 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::ImageSkia SelectFaviconFrames( 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::vector<SkBitmap>& bitmaps, 210d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) const std::vector<gfx::Size>& original_sizes, 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::vector<ui::ScaleFactor>& scale_factors, 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int desired_size, 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) float* match_score) { 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<SelectionResult> results; 2155c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu GetCandidateIndicesWithBestScores( 2165c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu original_sizes, scale_factors, desired_size, match_score, &results); 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::ImageSkia multi_image; 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < results.size(); ++i) { 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SelectionResult& result = results[i]; 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkBitmap resized_bitmap = GetResizedBitmap(bitmaps[result.index], 2225c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu desired_size, 2235c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu result.scale_factor, 2245c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu result.resize_method); 2255c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu multi_image.AddRepresentation(gfx::ImageSkiaRep( 2265c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu resized_bitmap, ui::GetImageScale(result.scale_factor))); 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return multi_image; 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SelectFaviconFrameIndices( 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::vector<gfx::Size>& frame_pixel_sizes, 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::vector<ui::ScaleFactor>& scale_factors, 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int desired_size, 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<size_t>* best_indices, 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) float* match_score) { 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<SelectionResult> results; 2385c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu GetCandidateIndicesWithBestScores( 2395c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu frame_pixel_sizes, scale_factors, desired_size, match_score, &results); 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::set<size_t> already_added; 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < results.size(); ++i) { 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t index = results[i].index; 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // GetCandidateIndicesWithBestScores() will return duplicate indices if the 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // bitmap data with |frame_pixel_sizes[index]| should be used for multiple 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // scale factors. Remove duplicates here such that |best_indices| contains 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // no duplicates. 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (already_added.find(index) == already_added.end()) { 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) already_added.insert(index); 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) best_indices->push_back(index); 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 254