Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "chrome/browser/thumbnails/content_analysis.h" | 5 #include "chrome/browser/thumbnails/content_analysis.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 | 9 |
| 10 #include <algorithm> | 10 #include <algorithm> |
| 11 #include <cmath> | 11 #include <cmath> |
| 12 #include <cstdlib> | 12 #include <cstdlib> |
| 13 #include <functional> | 13 #include <functional> |
| 14 #include <limits> | 14 #include <limits> |
| 15 #include <memory> | 15 #include <memory> |
| 16 #include <numeric> | 16 #include <numeric> |
| 17 #include <vector> | 17 #include <vector> |
| 18 | 18 |
| 19 #include "skia/ext/platform_canvas.h" | 19 #include "skia/ext/platform_canvas.h" |
| 20 #include "testing/gtest/include/gtest/gtest.h" | 20 #include "testing/gtest/include/gtest/gtest.h" |
| 21 #include "third_party/skia/include/core/SkBitmap.h" | 21 #include "third_party/skia/include/core/SkBitmap.h" |
| 22 #include "third_party/skia/include/core/SkColor.h" | 22 #include "third_party/skia/include/core/SkColor.h" |
| 23 #include "ui/gfx/canvas.h" | 23 #include "ui/gfx/canvas.h" |
| 24 #include "ui/gfx/color_analysis.h" | 24 #include "ui/gfx/color_analysis.h" |
| 25 #include "ui/gfx/color_utils.h" | 25 #include "ui/gfx/color_utils.h" |
| 26 #include "ui/gfx/geometry/rect.h" | 26 #include "ui/gfx/geometry/rect.h" |
| 27 #include "ui/gfx/geometry/rect_f.h" | |
| 27 #include "ui/gfx/geometry/size.h" | 28 #include "ui/gfx/geometry/size.h" |
| 28 #include "ui/gfx/image/image.h" | 29 #include "ui/gfx/image/image.h" |
| 29 | 30 |
| 30 namespace { | 31 namespace { |
| 31 | 32 |
| 32 #ifndef M_PI | 33 #ifndef M_PI |
| 33 #define M_PI 3.14159265358979323846 | 34 #define M_PI 3.14159265358979323846 |
| 34 #endif | 35 #endif |
| 35 | 36 |
| 36 unsigned long ImagePixelSum(const SkBitmap& bitmap, const gfx::Rect& rect) { | 37 unsigned long ImagePixelSum(const SkBitmap& bitmap, const gfx::Rect& rect) { |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 120 data_sum = ImagePixelSum(reduced_color, echo_rect); | 121 data_sum = ImagePixelSum(reduced_color, echo_rect); |
| 121 all_sum = ImagePixelSum(reduced_color, gfx::Rect(800, 600)); | 122 all_sum = ImagePixelSum(reduced_color, gfx::Rect(800, 600)); |
| 122 EXPECT_GT(data_sum, 0U); | 123 EXPECT_GT(data_sum, 0U); |
| 123 EXPECT_EQ(data_sum, all_sum); | 124 EXPECT_EQ(data_sum, all_sum); |
| 124 } | 125 } |
| 125 | 126 |
| 126 TEST_F(ThumbnailContentAnalysisTest, ApplyGradientMagnitudeOnFrame) { | 127 TEST_F(ThumbnailContentAnalysisTest, ApplyGradientMagnitudeOnFrame) { |
| 127 gfx::Canvas canvas(gfx::Size(800, 600), 1.0f, true); | 128 gfx::Canvas canvas(gfx::Size(800, 600), 1.0f, true); |
| 128 | 129 |
| 129 // The image consists of a single white block in the centre. | 130 // The image consists of a single white block in the centre. |
| 130 gfx::Rect draw_rect(300, 200, 200, 200); | 131 gfx::RectF draw_rect(300, 200, 200, 200); |
| 131 canvas.FillRect(gfx::Rect(0, 0, 800, 600), SkColorSetRGB(0, 0, 0)); | 132 canvas.FillRect(gfx::Rect(0, 0, 800, 600), SkColorSetRGB(0, 0, 0)); |
| 132 canvas.DrawRect(draw_rect, SkColorSetRGB(255, 255, 255)); | 133 canvas.DrawRect(draw_rect, SkColorSetRGB(255, 255, 255)); |
| 133 | 134 |
| 134 SkBitmap source = canvas.GetBitmap(); | 135 SkBitmap source = canvas.GetBitmap(); |
| 135 | 136 |
| 136 SkBitmap reduced_color; | 137 SkBitmap reduced_color; |
| 137 reduced_color.allocPixels(SkImageInfo::MakeA8(source.width(), | 138 reduced_color.allocPixels(SkImageInfo::MakeA8(source.width(), |
| 138 source.height())); | 139 source.height())); |
| 139 | 140 |
| 140 gfx::Vector3dF transform(0.299f, 0.587f, 0.114f); | 141 gfx::Vector3dF transform(0.299f, 0.587f, 0.114f); |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 157 unsigned long all_sum = ImagePixelSum(reduced_color, gfx::Rect(800, 600)); | 158 unsigned long all_sum = ImagePixelSum(reduced_color, gfx::Rect(800, 600)); |
| 158 EXPECT_GT(data_sum, 0U); | 159 EXPECT_GT(data_sum, 0U); |
| 159 EXPECT_EQ(data_sum, all_sum); | 160 EXPECT_EQ(data_sum, all_sum); |
| 160 EXPECT_EQ(ImagePixelSum(reduced_color, inner_rect), 0U); | 161 EXPECT_EQ(ImagePixelSum(reduced_color, inner_rect), 0U); |
| 161 } | 162 } |
| 162 | 163 |
| 163 TEST_F(ThumbnailContentAnalysisTest, ExtractImageProfileInformation) { | 164 TEST_F(ThumbnailContentAnalysisTest, ExtractImageProfileInformation) { |
| 164 gfx::Canvas canvas(gfx::Size(800, 600), 1.0f, true); | 165 gfx::Canvas canvas(gfx::Size(800, 600), 1.0f, true); |
| 165 | 166 |
| 166 // The image consists of a white frame drawn in the centre. | 167 // The image consists of a white frame drawn in the centre. |
| 167 gfx::Rect draw_rect(100, 100, 200, 100); | 168 gfx::RectF draw_rect(100, 100, 200, 100); |
| 168 gfx::Rect image_rect(0, 0, 800, 600); | 169 gfx::Rect image_rect(0, 0, 800, 600); |
| 169 canvas.FillRect(image_rect, SkColorSetRGB(0, 0, 0)); | 170 canvas.FillRect(image_rect, SkColorSetRGB(0, 0, 0)); |
| 170 canvas.DrawRect(draw_rect, SkColorSetRGB(255, 255, 255)); | 171 canvas.DrawRect(draw_rect, SkColorSetRGB(255, 255, 255)); |
| 171 | 172 |
| 172 SkBitmap source = canvas.GetBitmap(); | 173 SkBitmap source = canvas.GetBitmap(); |
| 173 SkBitmap reduced_color; | 174 SkBitmap reduced_color; |
| 174 reduced_color.allocPixels(SkImageInfo::MakeA8(source.width(), | 175 reduced_color.allocPixels(SkImageInfo::MakeA8(source.width(), |
| 175 source.height())); | 176 source.height())); |
| 176 | 177 |
| 177 gfx::Vector3dF transform(1, 0, 0); | 178 gfx::Vector3dF transform(1, 0, 0); |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 222 } | 223 } |
| 223 | 224 |
| 224 TEST_F(ThumbnailContentAnalysisTest, | 225 TEST_F(ThumbnailContentAnalysisTest, |
| 225 ExtractImageProfileInformationWithClosing) { | 226 ExtractImageProfileInformationWithClosing) { |
| 226 gfx::Canvas canvas(gfx::Size(800, 600), 1.0f, true); | 227 gfx::Canvas canvas(gfx::Size(800, 600), 1.0f, true); |
| 227 | 228 |
| 228 // The image consists of a two white frames drawn side by side, with a | 229 // The image consists of a two white frames drawn side by side, with a |
| 229 // single-pixel vertical gap in between. | 230 // single-pixel vertical gap in between. |
| 230 gfx::Rect image_rect(0, 0, 800, 600); | 231 gfx::Rect image_rect(0, 0, 800, 600); |
| 231 canvas.FillRect(image_rect, SkColorSetRGB(0, 0, 0)); | 232 canvas.FillRect(image_rect, SkColorSetRGB(0, 0, 0)); |
| 232 canvas.DrawRect(gfx::Rect(300, 250, 99, 100), SkColorSetRGB(255, 255, 255)); | 233 canvas.DrawRect(gfx::RectF(300, 250, 99, 100), SkColorSetRGB(255, 255, 255)); |
| 233 canvas.DrawRect(gfx::Rect(401, 250, 99, 100), SkColorSetRGB(255, 255, 255)); | 234 canvas.DrawRect(gfx::RectF(401, 250, 99, 100), SkColorSetRGB(255, 255, 255)); |
| 234 | 235 |
| 235 SkBitmap source = canvas.GetBitmap(); | 236 SkBitmap source = canvas.GetBitmap(); |
| 236 SkBitmap reduced_color; | 237 SkBitmap reduced_color; |
| 237 reduced_color.allocPixels(SkImageInfo::MakeA8(source.width(), | 238 reduced_color.allocPixels(SkImageInfo::MakeA8(source.width(), |
| 238 source.height())); | 239 source.height())); |
| 239 | 240 |
| 240 gfx::Vector3dF transform(1, 0, 0); | 241 gfx::Vector3dF transform(1, 0, 0); |
| 241 EXPECT_TRUE(color_utils::ApplyColorReduction( | 242 EXPECT_TRUE(color_utils::ApplyColorReduction( |
| 242 source, transform, true, &reduced_color)); | 243 source, transform, true, &reduced_color)); |
| 243 std::vector<float> column_profile; | 244 std::vector<float> column_profile; |
| (...skipping 370 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 614 | 615 |
| 615 // 'Fine print' at the bottom. | 616 // 'Fine print' at the bottom. |
| 616 const int fine_print = 8; | 617 const int fine_print = 8; |
| 617 const SkColor print_color = SkColorSetRGB(45, 30, 30); | 618 const SkColor print_color = SkColorSetRGB(45, 30, 30); |
| 618 for (int y = footer_rect.y() + fine_print; | 619 for (int y = footer_rect.y() + fine_print; |
| 619 y < footer_rect.bottom() - fine_print; | 620 y < footer_rect.bottom() - fine_print; |
| 620 y += 2 * fine_print) { | 621 y += 2 * fine_print) { |
| 621 for (int x = footer_rect.x() + fine_print; | 622 for (int x = footer_rect.x() + fine_print; |
| 622 x < footer_rect.right() - fine_print; | 623 x < footer_rect.right() - fine_print; |
| 623 x += 2 * fine_print) { | 624 x += 2 * fine_print) { |
| 624 canvas.DrawRect(gfx::Rect(x, y, fine_print, fine_print), print_color); | 625 canvas.DrawRect(gfx::RectF(x, y, fine_print, fine_print), print_color); |
| 625 } | 626 } |
| 626 } | 627 } |
| 627 | 628 |
| 628 // Blocky content at the top. | 629 // Blocky content at the top. |
| 629 const int block_size = header_rect.height() - margin_vertical; | 630 const int block_size = header_rect.height() - margin_vertical; |
| 630 for (int x = header_rect.x() + margin_horizontal; | 631 for (int x = header_rect.x() + margin_horizontal; |
| 631 x < header_rect.right() - block_size; | 632 x < header_rect.right() - block_size; |
| 632 x += block_size + margin_horizontal) { | 633 x += block_size + margin_horizontal) { |
| 633 const int half_block = block_size / 2 - 5; | 634 const int half_block = block_size / 2 - 5; |
| 634 const SkColor block_color = SkColorSetRGB(255, 255, 255); | 635 const SkColor block_color = SkColorSetRGB(255, 255, 255); |
| 635 const int y = header_rect.y() + margin_vertical / 2; | 636 const int y = header_rect.y() + margin_vertical / 2; |
| 636 int second_col = x + half_block + 10; | 637 int second_col = x + half_block + 10; |
| 637 int second_row = y + half_block + 10; | 638 int second_row = y + half_block + 10; |
| 638 canvas.FillRect(gfx::Rect(x, y, half_block, block_size), block_color); | 639 canvas.FillRect(gfx::Rect(x, y, half_block, block_size), block_color); |
| 639 canvas.FillRect(gfx::Rect(second_col, y, half_block, half_block), | 640 canvas.FillRect(gfx::Rect(second_col, y, half_block, half_block), |
| 640 block_color); | 641 block_color); |
| 641 canvas.FillRect(gfx::Rect(second_col, second_row, half_block, half_block), | 642 canvas.FillRect(gfx::Rect(second_col, second_row, half_block, half_block), |
| 642 block_color); | 643 block_color); |
| 643 } | 644 } |
| 644 | 645 |
| 645 // Now the main body. Mostly text with some 'pictures'. | 646 // Now the main body. Mostly text with some 'pictures'. |
| 646 for (int y = body_rect.y() + fine_print; | 647 for (int y = body_rect.y() + fine_print; |
| 647 y < body_rect.bottom() - fine_print; | 648 y < body_rect.bottom() - fine_print; |
| 648 y += 2 * fine_print) { | 649 y += 2 * fine_print) { |
| 649 for (int x = body_rect.x() + fine_print; | 650 for (int x = body_rect.x() + fine_print; |
| 650 x < body_rect.right() - fine_print; | 651 x < body_rect.right() - fine_print; |
| 651 x += 2 * fine_print) { | 652 x += 2 * fine_print) { |
| 652 canvas.DrawRect(gfx::Rect(x, y, fine_print, fine_print), print_color); | 653 canvas.DrawRect(gfx::RectF(x, y, fine_print, fine_print), print_color); |
| 653 } | 654 } |
| 654 } | 655 } |
| 655 | 656 |
| 656 for (int line = 0; line < 3; ++line) { | 657 for (int line = 0; line < 3; ++line) { |
| 657 int alignment = line % 2; | 658 int alignment = line % 2; |
| 658 const int y = body_rect.y() + | 659 const int y = body_rect.y() + |
| 659 body_rect.height() / 3 * line + margin_vertical; | 660 body_rect.height() / 3 * line + margin_vertical; |
| 660 const int x = body_rect.x() + | 661 const int x = body_rect.x() + |
| 661 alignment * body_rect.width() / 2 + margin_vertical; | 662 alignment * body_rect.width() / 2 + margin_vertical; |
| 662 gfx::Rect pict_rect(x, y, | 663 gfx::RectF pict_rect(x, y, body_rect.width() / 2 - 2 * margin_vertical, |
|
msw
2017/04/07 10:12:23
Should these div ops use floating point literals n
Uzair
2017/04/07 10:53:54
How about canvas.drawRect(gfx::RectF(pict_rect),..
| |
| 663 body_rect.width() / 2 - 2 * margin_vertical, | 664 body_rect.height() / 3 - 2 * margin_vertical); |
| 664 body_rect.height() / 3 - 2 * margin_vertical); | |
| 665 canvas.FillRect(pict_rect, SkColorSetRGB(255, 255, 255)); | 665 canvas.FillRect(pict_rect, SkColorSetRGB(255, 255, 255)); |
| 666 canvas.DrawRect(pict_rect, SkColorSetRGB(0, 0, 0)); | 666 canvas.DrawRect(pict_rect, SkColorSetRGB(0, 0, 0)); |
| 667 } | 667 } |
| 668 | 668 |
| 669 SkBitmap source = canvas.GetBitmap(); | 669 SkBitmap source = canvas.GetBitmap(); |
| 670 | 670 |
| 671 SkBitmap result = CreateRetargetedThumbnailImage( | 671 SkBitmap result = CreateRetargetedThumbnailImage( |
| 672 source, gfx::Size(424, 264), 2.5); | 672 source, gfx::Size(424, 264), 2.5); |
| 673 EXPECT_FALSE(result.empty()); | 673 EXPECT_FALSE(result.empty()); |
| 674 | 674 |
| 675 // Given the nature of computation We can't really assert much here about the | 675 // Given the nature of computation We can't really assert much here about the |
| 676 // image itself. We know it should have been computed, should be smaller than | 676 // image itself. We know it should have been computed, should be smaller than |
| 677 // the original and it must not be zero. | 677 // the original and it must not be zero. |
| 678 EXPECT_LT(result.width(), image_size.width()); | 678 EXPECT_LT(result.width(), image_size.width()); |
| 679 EXPECT_LT(result.height(), image_size.height()); | 679 EXPECT_LT(result.height(), image_size.height()); |
| 680 | 680 |
| 681 int histogram[256] = {}; | 681 int histogram[256] = {}; |
| 682 color_utils::BuildLumaHistogram(result, histogram); | 682 color_utils::BuildLumaHistogram(result, histogram); |
| 683 int non_zero_color_count = std::count_if( | 683 int non_zero_color_count = std::count_if( |
| 684 histogram, histogram + 256, [](int value) { return value > 0; }); | 684 histogram, histogram + 256, [](int value) { return value > 0; }); |
| 685 EXPECT_GT(non_zero_color_count, 4); | 685 EXPECT_GT(non_zero_color_count, 4); |
| 686 | 686 |
| 687 } | 687 } |
| 688 | 688 |
| 689 } // namespace thumbnailing_utils | 689 } // namespace thumbnailing_utils |
| OLD | NEW |