summaryrefslogtreecommitdiffstats
path: root/base
diff options
context:
space:
mode:
authorbrettw@google.com <brettw@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2008-12-02 22:35:42 +0000
committerbrettw@google.com <brettw@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2008-12-02 22:35:42 +0000
commit004a96a015b5dfcadaad4ea1b192c97c415b75de (patch)
treecb32d3809e4366c07e837416a106a3083d2690a5 /base
parentf8ed412acb7bcab9855d0ebd9d29f7e38a3a8f92 (diff)
downloadchromium_src-004a96a015b5dfcadaad4ea1b192c97c415b75de.zip
chromium_src-004a96a015b5dfcadaad4ea1b192c97c415b75de.tar.gz
chromium_src-004a96a015b5dfcadaad4ea1b192c97c415b75de.tar.bz2
Move convolver, image_operations, and skia_utils from base/gfx to skia/ext.
This changes the namespace in those files from "gfx" to "skia". I split skia_utils into two parts, the Windows specific part is now in a separate file called skia_utils_win. There were several obsolete includes of these headers which I removed. I also removed img_resize_perftest which isn't used and has bitrotted. Review URL: http://codereview.chromium.org/12842 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@6248 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base')
-rw-r--r--base/build/base_gfx.vcproj24
-rw-r--r--base/build/base_unittests.vcproj8
-rw-r--r--base/gfx/base_gfx.scons4
-rw-r--r--base/gfx/convolver.cc335
-rw-r--r--base/gfx/convolver.h137
-rw-r--r--base/gfx/convolver_unittest.cc127
-rw-r--r--base/gfx/image_operations.cc362
-rw-r--r--base/gfx/image_operations.h63
-rw-r--r--base/gfx/image_operations_unittest.cc148
-rw-r--r--base/gfx/img_resize_perftest.cc70
-rw-r--r--base/gfx/native_theme.cc12
-rw-r--r--base/gfx/skia_utils.cc75
-rw-r--r--base/gfx/skia_utils.h56
-rw-r--r--base/gfx/skia_utils_mac.cc83
-rw-r--r--base/gfx/skia_utils_mac.h51
15 files changed, 6 insertions, 1549 deletions
diff --git a/base/build/base_gfx.vcproj b/base/build/base_gfx.vcproj
index ef4b5de..70875a9 100644
--- a/base/build/base_gfx.vcproj
+++ b/base/build/base_gfx.vcproj
@@ -122,14 +122,6 @@
</References>
<Files>
<File
- RelativePath="..\gfx\convolver.cc"
- >
- </File>
- <File
- RelativePath="..\gfx\convolver.h"
- >
- </File>
- <File
RelativePath="..\gfx\gdi_util.cc"
>
</File>
@@ -138,14 +130,6 @@
>
</File>
<File
- RelativePath="..\gfx\image_operations.cc"
- >
- </File>
- <File
- RelativePath="..\gfx\image_operations.h"
- >
- </File>
- <File
RelativePath="..\gfx\native_theme.cc"
>
</File>
@@ -193,14 +177,6 @@
RelativePath="..\gfx\size.h"
>
</File>
- <File
- RelativePath="..\gfx\skia_utils.cc"
- >
- </File>
- <File
- RelativePath="..\gfx\skia_utils.h"
- >
- </File>
</Files>
<Globals>
</Globals>
diff --git a/base/build/base_unittests.vcproj b/base/build/base_unittests.vcproj
index 3c75166..e822992 100644
--- a/base/build/base_unittests.vcproj
+++ b/base/build/base_unittests.vcproj
@@ -396,14 +396,6 @@
Name="gfx_tests"
>
<File
- RelativePath="..\gfx\convolver_unittest.cc"
- >
- </File>
- <File
- RelativePath="..\gfx\image_operations_unittest.cc"
- >
- </File>
- <File
RelativePath="..\gfx\png_codec_unittest.cc"
>
</File>
diff --git a/base/gfx/base_gfx.scons b/base/gfx/base_gfx.scons
index 7173340..a69206b 100644
--- a/base/gfx/base_gfx.scons
+++ b/base/gfx/base_gfx.scons
@@ -25,16 +25,13 @@ if env['PLATFORM'] == 'win32':
)
input_files = [
- 'convolver.cc',
'gdi_util.cc',
- 'image_operations.cc',
'native_theme.cc',
'png_decoder.cc',
'png_encoder.cc',
'point.cc',
'rect.cc',
'size.cc',
- 'skia_utils.cc',
]
if env['PLATFORM'] in ('posix', 'darwin'):
@@ -43,7 +40,6 @@ if env['PLATFORM'] in ('posix', 'darwin'):
to_be_ported_files = [
'gdi_util.cc',
'native_theme.cc',
- 'skia_utils.cc',
]
for remove in to_be_ported_files:
input_files.remove(remove)
diff --git a/base/gfx/convolver.cc b/base/gfx/convolver.cc
deleted file mode 100644
index fd3503f..0000000
--- a/base/gfx/convolver.cc
+++ /dev/null
@@ -1,335 +0,0 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <algorithm>
-
-#include "base/basictypes.h"
-#include "base/gfx/convolver.h"
-#include "base/logging.h"
-
-namespace gfx {
-
-namespace {
-
-// Converts the argument to an 8-bit unsigned value by clamping to the range
-// 0-255.
-inline uint8 ClampTo8(int32 a) {
- if (static_cast<uint32>(a) < 256)
- return a; // Avoid the extra check in the common case.
- if (a < 0)
- return 0;
- return 255;
-}
-
-// Stores a list of rows in a circular buffer. The usage is you write into it
-// by calling AdvanceRow. It will keep track of which row in the buffer it
-// should use next, and the total number of rows added.
-class CircularRowBuffer {
- public:
- // The number of pixels in each row is given in |source_row_pixel_width|.
- // The maximum number of rows needed in the buffer is |max_y_filter_size|
- // (we only need to store enough rows for the biggest filter).
- //
- // We use the |first_input_row| to compute the coordinates of all of the
- // following rows returned by Advance().
- CircularRowBuffer(int dest_row_pixel_width, int max_y_filter_size,
- int first_input_row)
- : row_byte_width_(dest_row_pixel_width * 4),
- num_rows_(max_y_filter_size),
- next_row_(0),
- next_row_coordinate_(first_input_row) {
- buffer_.resize(row_byte_width_ * max_y_filter_size);
- row_addresses_.resize(num_rows_);
- }
-
- // Moves to the next row in the buffer, returning a pointer to the beginning
- // of it.
- uint8* AdvanceRow() {
- uint8* row = &buffer_[next_row_ * row_byte_width_];
- next_row_coordinate_++;
-
- // Set the pointer to the next row to use, wrapping around if necessary.
- next_row_++;
- if (next_row_ == num_rows_)
- next_row_ = 0;
- return row;
- }
-
- // Returns a pointer to an "unrolled" array of rows. These rows will start
- // at the y coordinate placed into |*first_row_index| and will continue in
- // order for the maximum number of rows in this circular buffer.
- //
- // The |first_row_index_| may be negative. This means the circular buffer
- // starts before the top of the image (it hasn't been filled yet).
- uint8* const* GetRowAddresses(int* first_row_index) {
- // Example for a 4-element circular buffer holding coords 6-9.
- // Row 0 Coord 8
- // Row 1 Coord 9
- // Row 2 Coord 6 <- next_row_ = 2, next_row_coordinate_ = 10.
- // Row 3 Coord 7
- //
- // The "next" row is also the first (lowest) coordinate. This computation
- // may yield a negative value, but that's OK, the math will work out
- // since the user of this buffer will compute the offset relative
- // to the first_row_index and the negative rows will never be used.
- *first_row_index = next_row_coordinate_ - num_rows_;
-
- int cur_row = next_row_;
- for (int i = 0; i < num_rows_; i++) {
- row_addresses_[i] = &buffer_[cur_row * row_byte_width_];
-
- // Advance to the next row, wrapping if necessary.
- cur_row++;
- if (cur_row == num_rows_)
- cur_row = 0;
- }
- return &row_addresses_[0];
- }
-
- private:
- // The buffer storing the rows. They are packed, each one row_byte_width_.
- std::vector<uint8> buffer_;
-
- // Number of bytes per row in the |buffer_|.
- int row_byte_width_;
-
- // The number of rows available in the buffer.
- int num_rows_;
-
- // The next row index we should write into. This wraps around as the
- // circular buffer is used.
- int next_row_;
-
- // The y coordinate of the |next_row_|. This is incremented each time a
- // new row is appended and does not wrap.
- int next_row_coordinate_;
-
- // Buffer used by GetRowAddresses().
- std::vector<uint8*> row_addresses_;
-};
-
-// Convolves horizontally along a single row. The row data is given in
-// |src_data| and continues for the num_values() of the filter.
-template<bool has_alpha>
-void ConvolveHorizontally(const uint8* src_data,
- const ConvolusionFilter1D& filter,
- unsigned char* out_row) {
- // Loop over each pixel on this row in the output image.
- int num_values = filter.num_values();
- for (int out_x = 0; out_x < num_values; out_x++) {
- // Get the filter that determines the current output pixel.
- int filter_offset, filter_length;
- const int16* filter_values =
- filter.FilterForValue(out_x, &filter_offset, &filter_length);
-
- // Compute the first pixel in this row that the filter affects. It will
- // touch |filter_length| pixels (4 bytes each) after this.
- const uint8* row_to_filter = &src_data[filter_offset * 4];
-
- // Apply the filter to the row to get the destination pixel in |accum|.
- int32 accum[4] = {0};
- for (int filter_x = 0; filter_x < filter_length; filter_x++) {
- int16 cur_filter = filter_values[filter_x];
- accum[0] += cur_filter * row_to_filter[filter_x * 4 + 0];
- accum[1] += cur_filter * row_to_filter[filter_x * 4 + 1];
- accum[2] += cur_filter * row_to_filter[filter_x * 4 + 2];
- if (has_alpha)
- accum[3] += cur_filter * row_to_filter[filter_x * 4 + 3];
- }
-
- // Bring this value back in range. All of the filter scaling factors
- // are in fixed point with kShiftBits bits of fractional part.
- accum[0] >>= ConvolusionFilter1D::kShiftBits;
- accum[1] >>= ConvolusionFilter1D::kShiftBits;
- accum[2] >>= ConvolusionFilter1D::kShiftBits;
- if (has_alpha)
- accum[3] >>= ConvolusionFilter1D::kShiftBits;
-
- // Store the new pixel.
- out_row[out_x * 4 + 0] = ClampTo8(accum[0]);
- out_row[out_x * 4 + 1] = ClampTo8(accum[1]);
- out_row[out_x * 4 + 2] = ClampTo8(accum[2]);
- if (has_alpha)
- out_row[out_x * 4 + 3] = ClampTo8(accum[3]);
- }
-}
-
-// Does vertical convolusion to produce one output row. The filter values and
-// length are given in the first two parameters. These are applied to each
-// of the rows pointed to in the |source_data_rows| array, with each row
-// being |pixel_width| wide.
-//
-// The output must have room for |pixel_width * 4| bytes.
-template<bool has_alpha>
-void ConvolveVertically(const int16* filter_values,
- int filter_length,
- uint8* const* source_data_rows,
- int pixel_width,
- uint8* out_row) {
- // We go through each column in the output and do a vertical convolusion,
- // generating one output pixel each time.
- for (int out_x = 0; out_x < pixel_width; out_x++) {
- // Compute the number of bytes over in each row that the current column
- // we're convolving starts at. The pixel will cover the next 4 bytes.
- int byte_offset = out_x * 4;
-
- // Apply the filter to one column of pixels.
- int32 accum[4] = {0};
- for (int filter_y = 0; filter_y < filter_length; filter_y++) {
- int16 cur_filter = filter_values[filter_y];
- accum[0] += cur_filter * source_data_rows[filter_y][byte_offset + 0];
- accum[1] += cur_filter * source_data_rows[filter_y][byte_offset + 1];
- accum[2] += cur_filter * source_data_rows[filter_y][byte_offset + 2];
- if (has_alpha)
- accum[3] += cur_filter * source_data_rows[filter_y][byte_offset + 3];
- }
-
- // Bring this value back in range. All of the filter scaling factors
- // are in fixed point with kShiftBits bits of precision.
- accum[0] >>= ConvolusionFilter1D::kShiftBits;
- accum[1] >>= ConvolusionFilter1D::kShiftBits;
- accum[2] >>= ConvolusionFilter1D::kShiftBits;
- if (has_alpha)
- accum[3] >>= ConvolusionFilter1D::kShiftBits;
-
- // Store the new pixel.
- out_row[byte_offset + 0] = ClampTo8(accum[0]);
- out_row[byte_offset + 1] = ClampTo8(accum[1]);
- out_row[byte_offset + 2] = ClampTo8(accum[2]);
- if (has_alpha) {
- uint8 alpha = ClampTo8(accum[3]);
-
- // Make sure the alpha channel doesn't come out larger than any of the
- // color channels. We use premultipled alpha channels, so this should
- // never happen, but rounding errors will cause this from time to time.
- // These "impossible" colors will cause overflows (and hence random pixel
- // values) when the resulting bitmap is drawn to the screen.
- //
- // We only need to do this when generating the final output row (here).
- int max_color_channel = std::max(out_row[byte_offset + 0],
- std::max(out_row[byte_offset + 1], out_row[byte_offset + 2]));
- if (alpha < max_color_channel)
- out_row[byte_offset + 3] = max_color_channel;
- else
- out_row[byte_offset + 3] = alpha;
- } else {
- // No alpha channel, the image is opaque.
- out_row[byte_offset + 3] = 0xff;
- }
- }
-}
-
-} // namespace
-
-// ConvolusionFilter1D ---------------------------------------------------------
-
-void ConvolusionFilter1D::AddFilter(int filter_offset,
- const float* filter_values,
- int filter_length) {
- FilterInstance instance;
- instance.data_location = static_cast<int>(filter_values_.size());
- instance.offset = filter_offset;
- instance.length = filter_length;
- filters_.push_back(instance);
-
- DCHECK(filter_length > 0);
- for (int i = 0; i < filter_length; i++)
- filter_values_.push_back(FloatToFixed(filter_values[i]));
-
- max_filter_ = std::max(max_filter_, filter_length);
-}
-
-void ConvolusionFilter1D::AddFilter(int filter_offset,
- const int16* filter_values,
- int filter_length) {
- FilterInstance instance;
- instance.data_location = static_cast<int>(filter_values_.size());
- instance.offset = filter_offset;
- instance.length = filter_length;
- filters_.push_back(instance);
-
- DCHECK(filter_length > 0);
- for (int i = 0; i < filter_length; i++)
- filter_values_.push_back(filter_values[i]);
-
- max_filter_ = std::max(max_filter_, filter_length);
-}
-
-// BGRAConvolve2D -------------------------------------------------------------
-
-void BGRAConvolve2D(const uint8* source_data,
- int source_byte_row_stride,
- bool source_has_alpha,
- const ConvolusionFilter1D& filter_x,
- const ConvolusionFilter1D& filter_y,
- uint8* output) {
- int max_y_filter_size = filter_y.max_filter();
-
- // The next row in the input that we will generate a horizontally
- // convolved row for. If the filter doesn't start at the beginning of the
- // image (this is the case when we are only resizing a subset), then we
- // don't want to generate any output rows before that. Compute the starting
- // row for convolusion as the first pixel for the first vertical filter.
- int filter_offset, filter_length;
- const int16* filter_values =
- filter_y.FilterForValue(0, &filter_offset, &filter_length);
- int next_x_row = filter_offset;
-
- // We loop over each row in the input doing a horizontal convolusion. This
- // will result in a horizontally convolved image. We write the results into
- // a circular buffer of convolved rows and do vertical convolusion as rows
- // are available. This prevents us from having to store the entire
- // intermediate image and helps cache coherency.
- CircularRowBuffer row_buffer(filter_x.num_values(), max_y_filter_size,
- filter_offset);
-
- // Loop over every possible output row, processing just enough horizontal
- // convolusions to run each subsequent vertical convolusion.
- int output_row_byte_width = filter_x.num_values() * 4;
- int num_output_rows = filter_y.num_values();
- for (int out_y = 0; out_y < num_output_rows; out_y++) {
- filter_values = filter_y.FilterForValue(out_y,
- &filter_offset, &filter_length);
-
- // Generate output rows until we have enough to run the current filter.
- while (next_x_row < filter_offset + filter_length) {
- if (source_has_alpha) {
- ConvolveHorizontally<true>(
- &source_data[next_x_row * source_byte_row_stride],
- filter_x, row_buffer.AdvanceRow());
- } else {
- ConvolveHorizontally<false>(
- &source_data[next_x_row * source_byte_row_stride],
- filter_x, row_buffer.AdvanceRow());
- }
- next_x_row++;
- }
-
- // Compute where in the output image this row of final data will go.
- uint8* cur_output_row = &output[out_y * output_row_byte_width];
-
- // Get the list of rows that the circular buffer has, in order.
- int first_row_in_circular_buffer;
- uint8* const* rows_to_convolve =
- row_buffer.GetRowAddresses(&first_row_in_circular_buffer);
-
- // Now compute the start of the subset of those rows that the filter
- // needs.
- uint8* const* first_row_for_filter =
- &rows_to_convolve[filter_offset - first_row_in_circular_buffer];
-
- if (source_has_alpha) {
- ConvolveVertically<true>(filter_values, filter_length,
- first_row_for_filter,
- filter_x.num_values(), cur_output_row);
- } else {
- ConvolveVertically<false>(filter_values, filter_length,
- first_row_for_filter,
- filter_x.num_values(), cur_output_row);
- }
- }
-}
-
-} // namespace gfx
-
diff --git a/base/gfx/convolver.h b/base/gfx/convolver.h
deleted file mode 100644
index 12c9228..0000000
--- a/base/gfx/convolver.h
+++ /dev/null
@@ -1,137 +0,0 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef BASE_GFX_CONVOLVER_H__
-#define BASE_GFX_CONVOLVER_H__
-
-#include <vector>
-
-#include "base/basictypes.h"
-
-// avoid confusion with Mac OS X's math library (Carbon)
-#if defined(OS_MACOSX)
-#undef FloatToFixed
-#endif
-
-namespace gfx {
-
-// Represents a filter in one dimension. Each output pixel has one entry in this
-// object for the filter values contributing to it. You build up the filter
-// list by calling AddFilter for each output pixel (in order).
-//
-// We do 2-dimensional convolusion by first convolving each row by one
-// ConvolusionFilter1D, then convolving each column by another one.
-//
-// Entries are stored in fixed point, shifted left by kShiftBits.
-class ConvolusionFilter1D {
- public:
- // The number of bits that fixed point values are shifted by.
- enum { kShiftBits = 14 };
-
- ConvolusionFilter1D() : max_filter_(0) {
- }
-
- // Convert between floating point and our fixed point representation.
- static inline int16 FloatToFixed(float f) {
- return static_cast<int16>(f * (1 << kShiftBits));
- }
- static inline unsigned char FixedToChar(int16 x) {
- return static_cast<unsigned char>(x >> kShiftBits);
- }
-
- // Returns the maximum pixel span of a filter.
- int max_filter() const { return max_filter_; }
-
- // Returns the number of filters in this filter. This is the dimension of the
- // output image.
- int num_values() const { return static_cast<int>(filters_.size()); }
-
- // Appends the given list of scaling values for generating a given output
- // pixel. |filter_offset| is the distance from the edge of the image to where
- // the scaling factors start. The scaling factors apply to the source pixels
- // starting from this position, and going for the next |filter_length| pixels.
- //
- // You will probably want to make sure your input is normalized (that is,
- // all entries in |filter_values| sub to one) to prevent affecting the overall
- // brighness of the image.
- //
- // The filter_length must be > 0.
- //
- // This version will automatically convert your input to fixed point.
- void AddFilter(int filter_offset,
- const float* filter_values,
- int filter_length);
-
- // Same as the above version, but the input is already fixed point.
- void AddFilter(int filter_offset,
- const int16* filter_values,
- int filter_length);
-
- // Retrieves a filter for the given |value_offset|, a position in the output
- // image in the direction we're convolving. The offset and length of the
- // filter values are put into the corresponding out arguments (see AddFilter
- // above for what these mean), and a pointer to the first scaling factor is
- // returned. There will be |filter_length| values in this array.
- inline const int16* FilterForValue(int value_offset,
- int* filter_offset,
- int* filter_length) const {
- const FilterInstance& filter = filters_[value_offset];
- *filter_offset = filter.offset;
- *filter_length = filter.length;
- return &filter_values_[filter.data_location];
- }
-
- private:
- struct FilterInstance {
- // Offset within filter_values for this instance of the filter.
- int data_location;
-
- // Distance from the left of the filter to the center. IN PIXELS
- int offset;
-
- // Number of values in this filter instance.
- int length;
- };
-
- // Stores the information for each filter added to this class.
- std::vector<FilterInstance> filters_;
-
- // We store all the filter values in this flat list, indexed by
- // |FilterInstance.data_location| to avoid the mallocs required for storing
- // each one separately.
- std::vector<int16> filter_values_;
-
- // The maximum size of any filter we've added.
- int max_filter_;
-};
-
-// Does a two-dimensional convolusion on the given source image.
-//
-// It is assumed the source pixel offsets referenced in the input filters
-// reference only valid pixels, so the source image size is not required. Each
-// row of the source image starts |source_byte_row_stride| after the previous
-// one (this allows you to have rows with some padding at the end).
-//
-// The result will be put into the given output buffer. The destination image
-// size will be xfilter.num_values() * yfilter.num_values() pixels. It will be
-// in rows of exactly xfilter.num_values() * 4 bytes.
-//
-// |source_has_alpha| is a hint that allows us to avoid doing computations on
-// the alpha channel if the image is opaque. If you don't know, set this to
-// true and it will work properly, but setting this to false will be a few
-// percent faster if you know the image is opaque.
-//
-// The layout in memory is assumed to be 4-bytes per pixel in B-G-R-A order
-// (this is ARGB when loaded into 32-bit words on a little-endian machine).
-void BGRAConvolve2D(const uint8* source_data,
- int source_byte_row_stride,
- bool source_has_alpha,
- const ConvolusionFilter1D& xfilter,
- const ConvolusionFilter1D& yfilter,
- uint8* output);
-
-} // namespace gfx
-
-#endif // BASE_GFX_CONVOLVER_H__
-
diff --git a/base/gfx/convolver_unittest.cc b/base/gfx/convolver_unittest.cc
deleted file mode 100644
index 0a30a6b..0000000
--- a/base/gfx/convolver_unittest.cc
+++ /dev/null
@@ -1,127 +0,0 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <string.h>
-#include <time.h>
-#include <vector>
-
-#include "base/gfx/convolver.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace gfx {
-
-namespace {
-
-// Fills the given filter with impulse functions for the range 0->num_entries.
- void FillImpulseFilter(int num_entries, ConvolusionFilter1D* filter) {
- float one = 1.0f;
- for (int i = 0; i < num_entries; i++)
- filter->AddFilter(i, &one, 1);
-}
-
-// Filters the given input with the impulse function, and verifies that it
-// does not change.
-void TestImpulseConvolusion(const unsigned char* data, int width, int height) {
- int byte_count = width * height * 4;
-
- ConvolusionFilter1D filter_x;
- FillImpulseFilter(width, &filter_x);
-
- ConvolusionFilter1D filter_y;
- FillImpulseFilter(height, &filter_y);
-
- std::vector<unsigned char> output;
- output.resize(byte_count);
- BGRAConvolve2D(data, width * 4, true, filter_x, filter_y, &output[0]);
-
- // Output should exactly match input.
- EXPECT_EQ(0, memcmp(data, &output[0], byte_count));
-}
-
-// Fills the destination filter with a box filter averaging every two pixels
-// to produce the output.
-void FillBoxFilter(int size, ConvolusionFilter1D* filter) {
- const float box[2] = { 0.5, 0.5 };
- for (int i = 0; i < size; i++)
- filter->AddFilter(i * 2, box, 2);
-}
-
-} // namespace
-
-// Tests that each pixel, when set and run through the impulse filter, does
-// not change.
-TEST(Convolver, Impulse) {
- // We pick an "odd" size that is not likely to fit on any boundaries so that
- // we can see if all the widths and paddings are handled properly.
- int width = 15;
- int height = 31;
- int byte_count = width * height * 4;
- std::vector<unsigned char> input;
- input.resize(byte_count);
-
- unsigned char* input_ptr = &input[0];
- for (int y = 0; y < height; y++) {
- for (int x = 0; x < width; x++) {
- for (int channel = 0; channel < 3; channel++) {
- memset(input_ptr, 0, byte_count);
- input_ptr[(y * width + x) * 4 + channel] = 0xff;
- // Always set the alpha channel or it will attempt to "fix" it for us.
- input_ptr[(y * width + x) * 4 + 3] = 0xff;
- TestImpulseConvolusion(input_ptr, width, height);
- }
- }
- }
-}
-
-// Tests that using a box filter to halve an image results in every square of 4
-// pixels in the original get averaged to a pixel in the output.
-TEST(Convolver, Halve) {
- static const int kSize = 16;
-
- int src_width = kSize;
- int src_height = kSize;
- int src_row_stride = src_width * 4;
- int src_byte_count = src_row_stride * src_height;
- std::vector<unsigned char> input;
- input.resize(src_byte_count);
-
- int dest_width = src_width / 2;
- int dest_height = src_height / 2;
- int dest_byte_count = dest_width * dest_height * 4;
- std::vector<unsigned char> output;
- output.resize(dest_byte_count);
-
- // First fill the array with a bunch of random data.
- srand(static_cast<unsigned>(time(NULL)));
- for (int i = 0; i < src_byte_count; i++)
- input[i] = rand() * 255 / RAND_MAX;
-
- // Compute the filters.
- ConvolusionFilter1D filter_x, filter_y;
- FillBoxFilter(dest_width, &filter_x);
- FillBoxFilter(dest_height, &filter_y);
-
- // Do the convolusion.
- BGRAConvolve2D(&input[0], src_width, true, filter_x, filter_y, &output[0]);
-
- // Compute the expected results and check, allowing for a small difference
- // to account for rounding errors.
- for (int y = 0; y < dest_height; y++) {
- for (int x = 0; x < dest_width; x++) {
- for (int channel = 0; channel < 4; channel++) {
- int src_offset = (y * 2 * src_row_stride + x * 2 * 4) + channel;
- int value = input[src_offset] + // Top left source pixel.
- input[src_offset + 4] + // Top right source pixel.
- input[src_offset + src_row_stride] + // Lower left.
- input[src_offset + src_row_stride + 4]; // Lower right.
- value /= 4; // Average.
- int difference = value - output[(y * dest_width + x) * 4 + channel];
- EXPECT_TRUE(difference >= -1 || difference <= 1);
- }
- }
- }
-}
-
-} // namespace gfx
-
diff --git a/base/gfx/image_operations.cc b/base/gfx/image_operations.cc
deleted file mode 100644
index a60d19e..0000000
--- a/base/gfx/image_operations.cc
+++ /dev/null
@@ -1,362 +0,0 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-#define _USE_MATH_DEFINES
-#include <cmath>
-#include <limits>
-#include <vector>
-
-#include "base/gfx/image_operations.h"
-
-#include "base/gfx/convolver.h"
-#include "base/gfx/rect.h"
-#include "base/gfx/size.h"
-#include "base/logging.h"
-#include "base/stack_container.h"
-#include "SkBitmap.h"
-
-namespace gfx {
-
-namespace {
-
-// Returns the ceiling/floor as an integer.
-inline int CeilInt(float val) {
- return static_cast<int>(ceil(val));
-}
-inline int FloorInt(float val) {
- return static_cast<int>(floor(val));
-}
-
-// Filter function computation -------------------------------------------------
-
-// Evaluates the box filter, which goes from -0.5 to +0.5.
-float EvalBox(float x) {
- return (x >= -0.5f && x < 0.5f) ? 1.0f : 0.0f;
-}
-
-// Evaluates the Lanczos filter of the given filter size window for the given
-// position.
-//
-// |filter_size| is the width of the filter (the "window"), outside of which
-// the value of the function is 0. Inside of the window, the value is the
-// normalized sinc function:
-// lanczos(x) = sinc(x) * sinc(x / filter_size);
-// where
-// sinc(x) = sin(pi*x) / (pi*x);
-float EvalLanczos(int filter_size, float x) {
- if (x <= -filter_size || x >= filter_size)
- return 0.0f; // Outside of the window.
- if (x > -std::numeric_limits<float>::epsilon() &&
- x < std::numeric_limits<float>::epsilon())
- return 1.0f; // Special case the discontinuity at the origin.
- float xpi = x * static_cast<float>(M_PI);
- return (sin(xpi) / xpi) * // sinc(x)
- sin(xpi / filter_size) / (xpi / filter_size); // sinc(x/filter_size)
-}
-
-// ResizeFilter ----------------------------------------------------------------
-
-// Encapsulates computation and storage of the filters required for one complete
-// resize operation.
-class ResizeFilter {
- public:
- ResizeFilter(ImageOperations::ResizeMethod method,
- const Size& src_full_size,
- const Size& dest_size,
- const Rect& dest_subset);
-
- // Returns the bounds in the input bitmap of data that is used in the output.
- // The filter offsets are within this rectangle.
- const Rect& src_depend() { return src_depend_; }
-
- // Returns the filled filter values.
- const ConvolusionFilter1D& x_filter() { return x_filter_; }
- const ConvolusionFilter1D& y_filter() { return y_filter_; }
-
- private:
- // Returns the number of pixels that the filer spans, in filter space (the
- // destination image).
- float GetFilterSupport(float scale) {
- switch (method_) {
- case ImageOperations::RESIZE_BOX:
- // The box filter just scales with the image scaling.
- return 0.5f; // Only want one side of the filter = /2.
- case ImageOperations::RESIZE_LANCZOS3:
- // The lanczos filter takes as much space in the source image in
- // each direction as the size of the window = 3 for Lanczos3.
- return 3.0f;
- default:
- NOTREACHED();
- return 1.0f;
- }
- }
-
- // Computes one set of filters either horizontally or vertically. The caller
- // will specify the "min" and "max" rather than the bottom/top and
- // right/bottom so that the same code can be re-used in each dimension.
- //
- // |src_depend_lo| and |src_depend_size| gives the range for the source
- // depend rectangle (horizontally or vertically at the caller's discretion
- // -- see above for what this means).
- //
- // Likewise, the range of destination values to compute and the scale factor
- // for the transform is also specified.
- void ComputeFilters(int src_size,
- int dest_subset_lo, int dest_subset_size,
- float scale, float src_support,
- ConvolusionFilter1D* output);
-
- // Computes the filter value given the coordinate in filter space.
- inline float ComputeFilter(float pos) {
- switch (method_) {
- case ImageOperations::RESIZE_BOX:
- return EvalBox(pos);
- case ImageOperations::RESIZE_LANCZOS3:
- return EvalLanczos(3, pos);
- default:
- NOTREACHED();
- return 0;
- }
- }
-
- ImageOperations::ResizeMethod method_;
-
- // Subset of source the filters will touch.
- Rect src_depend_;
-
- // Size of the filter support on one side only in the destination space.
- // See GetFilterSupport.
- float x_filter_support_;
- float y_filter_support_;
-
- // Subset of scaled destination bitmap to compute.
- Rect out_bounds_;
-
- ConvolusionFilter1D x_filter_;
- ConvolusionFilter1D y_filter_;
-
- DISALLOW_EVIL_CONSTRUCTORS(ResizeFilter);
-};
-
-ResizeFilter::ResizeFilter(ImageOperations::ResizeMethod method,
- const Size& src_full_size,
- const Size& dest_size,
- const Rect& dest_subset)
- : method_(method),
- out_bounds_(dest_subset) {
- float scale_x = static_cast<float>(dest_size.width()) /
- static_cast<float>(src_full_size.width());
- float scale_y = static_cast<float>(dest_size.height()) /
- static_cast<float>(src_full_size.height());
-
- x_filter_support_ = GetFilterSupport(scale_x);
- y_filter_support_ = GetFilterSupport(scale_y);
-
- gfx::Rect src_full(0, 0, src_full_size.width(), src_full_size.height());
- gfx::Rect dest_full(0, 0,
- static_cast<int>(src_full_size.width() * scale_x + 0.5),
- static_cast<int>(src_full_size.height() * scale_y + 0.5));
-
- // Support of the filter in source space.
- float src_x_support = x_filter_support_ / scale_x;
- float src_y_support = y_filter_support_ / scale_y;
-
- ComputeFilters(src_full_size.width(), dest_subset.x(), dest_subset.width(),
- scale_x, src_x_support, &x_filter_);
- ComputeFilters(src_full_size.height(), dest_subset.y(), dest_subset.height(),
- scale_y, src_y_support, &y_filter_);
-}
-
-void ResizeFilter::ComputeFilters(int src_size,
- int dest_subset_lo, int dest_subset_size,
- float scale, float src_support,
- ConvolusionFilter1D* output) {
- int dest_subset_hi = dest_subset_lo + dest_subset_size; // [lo, hi)
-
- // When we're doing a magnification, the scale will be larger than one. This
- // means the destination pixels are much smaller than the source pixels, and
- // that the range covered by the filter won't necessarily cover any source
- // pixel boundaries. Therefore, we use these clamped values (max of 1) for
- // some computations.
- float clamped_scale = std::min(1.0f, scale);
-
- // Speed up the divisions below by turning them into multiplies.
- float inv_scale = 1.0f / scale;
-
- StackVector<float, 64> filter_values;
- StackVector<int16, 64> fixed_filter_values;
-
- // Loop over all pixels in the output range. We will generate one set of
- // filter values for each one. Those values will tell us how to blend the
- // source pixels to compute the destination pixel.
- for (int dest_subset_i = dest_subset_lo; dest_subset_i < dest_subset_hi;
- dest_subset_i++) {
- // Reset the arrays. We don't declare them inside so they can re-use the
- // same malloc-ed buffer.
- filter_values->clear();
- fixed_filter_values->clear();
-
- // This is the pixel in the source directly under the pixel in the dest.
- float src_pixel = dest_subset_i * inv_scale;
-
- // Compute the (inclusive) range of source pixels the filter covers.
- int src_begin = std::max(0, FloorInt(src_pixel - src_support));
- int src_end = std::min(src_size - 1, CeilInt(src_pixel + src_support));
-
- // Compute the unnormalized filter value at each location of the source
- // it covers.
- float filter_sum = 0.0f; // Sub of the filter values for normalizing.
- for (int cur_filter_pixel = src_begin; cur_filter_pixel <= src_end;
- cur_filter_pixel++) {
- // Distance from the center of the filter, this is the filter coordinate
- // in source space.
- float src_filter_pos = cur_filter_pixel - src_pixel;
-
- // Since the filter really exists in dest space, map it there.
- float dest_filter_pos = src_filter_pos * clamped_scale;
-
- // Compute the filter value at that location.
- float filter_value = ComputeFilter(dest_filter_pos);
- filter_values->push_back(filter_value);
-
- filter_sum += filter_value;
- }
- DCHECK(!filter_values->empty()) << "We should always get a filter!";
-
- // The filter must be normalized so that we don't affect the brightness of
- // the image. Convert to normalized fixed point.
- int16 fixed_sum = 0;
- for (size_t i = 0; i < filter_values->size(); i++) {
- int16 cur_fixed = output->FloatToFixed(filter_values[i] / filter_sum);
- fixed_sum += cur_fixed;
- fixed_filter_values->push_back(cur_fixed);
- }
-
- // The conversion to fixed point will leave some rounding errors, which
- // we add back in to avoid affecting the brightness of the image. We
- // arbitrarily add this to the center of the filter array (this won't always
- // be the center of the filter function since it could get clipped on the
- // edges, but it doesn't matter enough to worry about that case).
- int16 leftovers = output->FloatToFixed(1.0f) - fixed_sum;
- fixed_filter_values[fixed_filter_values->size() / 2] += leftovers;
-
- // Now it's ready to go.
- output->AddFilter(src_begin, &fixed_filter_values[0],
- static_cast<int>(fixed_filter_values->size()));
- }
-}
-
-} // namespace
-
-// Resize ----------------------------------------------------------------------
-
-// static
-SkBitmap ImageOperations::Resize(const SkBitmap& source,
- ResizeMethod method,
- const Size& dest_size,
- const Rect& dest_subset) {
- DCHECK(Rect(dest_size.width(), dest_size.height()).Contains(dest_subset)) <<
- "The supplied subset does not fall within the destination image.";
-
- // If the size of source or destination is 0, i.e. 0x0, 0xN or Nx0, just
- // return empty
- if (source.width() < 1 || source.height() < 1 ||
- dest_size.width() < 1 || dest_size.height() < 1)
- return SkBitmap();
-
- SkAutoLockPixels locker(source);
-
- ResizeFilter filter(method, Size(source.width(), source.height()),
- dest_size, dest_subset);
-
- // Get a source bitmap encompassing this touched area. We construct the
- // offsets and row strides such that it looks like a new bitmap, while
- // referring to the old data.
- const uint8* source_subset =
- reinterpret_cast<const uint8*>(source.getPixels());
-
- // Convolve into the result.
- SkBitmap result;
- result.setConfig(SkBitmap::kARGB_8888_Config,
- dest_subset.width(), dest_subset.height());
- result.allocPixels();
- BGRAConvolve2D(source_subset, static_cast<int>(source.rowBytes()),
- !source.isOpaque(), filter.x_filter(), filter.y_filter(),
- static_cast<unsigned char*>(result.getPixels()));
-
- // Preserve the "opaque" flag for use as an optimization later.
- result.setIsOpaque(source.isOpaque());
-
- return result;
-}
-
-// static
-SkBitmap ImageOperations::Resize(const SkBitmap& source,
- ResizeMethod method,
- const Size& dest_size) {
- Rect dest_subset(0, 0, dest_size.width(), dest_size.height());
- return Resize(source, method, dest_size, dest_subset);
-}
-
-// static
-SkBitmap ImageOperations::CreateBlendedBitmap(const SkBitmap& first,
- const SkBitmap& second,
- double alpha) {
- DCHECK(alpha <= 1 && alpha >= 0);
- DCHECK(first.width() == second.width());
- DCHECK(first.height() == second.height());
- DCHECK(first.bytesPerPixel() == second.bytesPerPixel());
- DCHECK(first.config() == SkBitmap::kARGB_8888_Config);
-
- // Optimize for case where we won't need to blend anything.
- static const double alpha_min = 1.0 / 255;
- static const double alpha_max = 254.0 / 255;
- if (alpha < alpha_min) {
- return first;
- } else if (alpha > alpha_max) {
- return second;
- }
-
- SkAutoLockPixels lock_first(first);
- SkAutoLockPixels lock_second(second);
-
- SkBitmap blended;
- blended.setConfig(SkBitmap::kARGB_8888_Config, first.width(),
- first.height(), 0);
- blended.allocPixels();
- blended.eraseARGB(0, 0, 0, 0);
-
- double first_alpha = 1 - alpha;
-
- for (int y = 0; y < first.height(); y++) {
- uint32* first_row = first.getAddr32(0, y);
- uint32* second_row = second.getAddr32(0, y);
- uint32* dst_row = blended.getAddr32(0, y);
-
- for (int x = 0; x < first.width(); x++) {
- uint32 first_pixel = first_row[x];
- uint32 second_pixel = second_row[x];
-
- int a = static_cast<int>(
- SkColorGetA(first_pixel) * first_alpha +
- SkColorGetA(second_pixel) * alpha);
- int r = static_cast<int>(
- SkColorGetR(first_pixel) * first_alpha +
- SkColorGetR(second_pixel) * alpha);
- int g = static_cast<int>(
- SkColorGetG(first_pixel) * first_alpha +
- SkColorGetG(second_pixel) * alpha);
- int b = static_cast<int>(
- SkColorGetB(first_pixel) * first_alpha +
- SkColorGetB(second_pixel) * alpha);
-
- dst_row[x] = SkColorSetARGB(a, r, g, b);
- }
- }
-
- return blended;
-}
-
-} // namespace gfx
-
diff --git a/base/gfx/image_operations.h b/base/gfx/image_operations.h
deleted file mode 100644
index 826e651..0000000
--- a/base/gfx/image_operations.h
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef BASE_GFX_IMAGE_OPERATIONS_H__
-#define BASE_GFX_IMAGE_OPERATIONS_H__
-
-#include "base/basictypes.h"
-#include "base/gfx/rect.h"
-
-class SkBitmap;
-
-namespace gfx {
-
-class ImageOperations {
- public:
- enum ResizeMethod {
- // Box filter. This is a weighted average of all of the pixels touching
- // the destination pixel. For enlargement, this is nearest neighbor.
- //
- // You probably don't want this, it is here for testing since it is easy to
- // compute. Use RESIZE_LANCZOS3 instead.
- RESIZE_BOX,
-
- // 3-cycle Lanczos filter. This is tall in the middle, goes negative on
- // each side, then oscillates 2 more times. It gives nice sharp edges.
- RESIZE_LANCZOS3,
- };
-
- // Resizes the given source bitmap using the specified resize method, so that
- // the entire image is (dest_size) big. The dest_subset is the rectangle in
- // this destination image that should actually be returned.
- //
- // The output image will be (dest_subset.width(), dest_subset.height()). This
- // will save work if you do not need the entire bitmap.
- //
- // The destination subset must be smaller than the destination image.
- static SkBitmap Resize(const SkBitmap& source,
- ResizeMethod method,
- const Size& dest_size,
- const Rect& dest_subset);
-
- // Alternate version for resizing and returning the entire bitmap rather than
- // a subset.
- static SkBitmap Resize(const SkBitmap& source,
- ResizeMethod method,
- const Size& dest_size);
-
-
- // Create a bitmap that is a blend of two others. The alpha argument
- // specifies the opacity of the second bitmap. The provided bitmaps must
- // use have the kARGB_8888_Config config and be of equal dimensions.
- static SkBitmap CreateBlendedBitmap(const SkBitmap& first,
- const SkBitmap& second,
- double alpha);
- private:
- ImageOperations(); // Class for scoping only.
-};
-
-} // namespace gfx
-
-#endif // BASE_GFX_IMAGE_OPERATIONS_H__
-
diff --git a/base/gfx/image_operations_unittest.cc b/base/gfx/image_operations_unittest.cc
deleted file mode 100644
index a15e648..0000000
--- a/base/gfx/image_operations_unittest.cc
+++ /dev/null
@@ -1,148 +0,0 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <stdlib.h>
-
-#include "base/gfx/image_operations.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "SkBitmap.h"
-
-namespace {
-
-// Computes the average pixel value for the given range, inclusive.
-uint32_t AveragePixel(const SkBitmap& bmp,
- int x_min, int x_max,
- int y_min, int y_max) {
- float accum[4] = {0, 0, 0, 0};
- int count = 0;
- for (int y = y_min; y <= y_max; y++) {
- for (int x = x_min; x <= x_max; x++) {
- uint32_t cur = *bmp.getAddr32(x, y);
- accum[0] += SkColorGetB(cur);
- accum[1] += SkColorGetG(cur);
- accum[2] += SkColorGetR(cur);
- accum[3] += SkColorGetA(cur);
- count++;
- }
- }
-
- return SkColorSetARGB(static_cast<unsigned char>(accum[3] / count),
- static_cast<unsigned char>(accum[2] / count),
- static_cast<unsigned char>(accum[1] / count),
- static_cast<unsigned char>(accum[0] / count));
-}
-
-// Returns true if each channel of the given two colors are "close." This is
-// used for comparing colors where rounding errors may cause off-by-one.
-bool ColorsClose(uint32_t a, uint32_t b) {
- return abs(static_cast<int>(SkColorGetB(a) - SkColorGetB(b))) < 2 &&
- abs(static_cast<int>(SkColorGetG(a) - SkColorGetG(b))) < 2 &&
- abs(static_cast<int>(SkColorGetR(a) - SkColorGetR(b))) < 2 &&
- abs(static_cast<int>(SkColorGetA(a) - SkColorGetA(b))) < 2;
-}
-
-void FillDataToBitmap(int w, int h, SkBitmap* bmp) {
- bmp->setConfig(SkBitmap::kARGB_8888_Config, w, h);
- bmp->allocPixels();
-
- unsigned char* src_data =
- reinterpret_cast<unsigned char*>(bmp->getAddr32(0, 0));
- for (int i = 0; i < w * h; i++) {
- src_data[i * 4 + 0] = static_cast<unsigned char>(i % 255);
- src_data[i * 4 + 1] = static_cast<unsigned char>(i % 255);
- src_data[i * 4 + 2] = static_cast<unsigned char>(i % 255);
- src_data[i * 4 + 3] = static_cast<unsigned char>(i % 255);
- }
-}
-
-} // namespace
-
-// Makes the bitmap 50% the size as the original using a box filter. This is
-// an easy operation that we can check the results for manually.
-TEST(ImageOperations, Halve) {
- // Make our source bitmap.
- int src_w = 30, src_h = 38;
- SkBitmap src;
- FillDataToBitmap(src_w, src_h, &src);
-
- // Do a halving of the full bitmap.
- SkBitmap actual_results = gfx::ImageOperations::Resize(
- src, gfx::ImageOperations::RESIZE_BOX, gfx::Size(src_w / 2, src_h / 2));
- ASSERT_EQ(src_w / 2, actual_results.width());
- ASSERT_EQ(src_h / 2, actual_results.height());
-
- // Compute the expected values & compare.
- SkAutoLockPixels lock(actual_results);
- for (int y = 0; y < actual_results.height(); y++) {
- for (int x = 0; x < actual_results.width(); x++) {
- int first_x = std::max(0, x * 2 - 1);
- int last_x = std::min(src_w - 1, x * 2);
-
- int first_y = std::max(0, y * 2 - 1);
- int last_y = std::min(src_h - 1, y * 2);
-
- uint32_t expected_color = AveragePixel(src,
- first_x, last_x, first_y, last_y);
- EXPECT_TRUE(ColorsClose(expected_color, *actual_results.getAddr32(x, y)));
- }
- }
-}
-
-TEST(ImageOperations, HalveSubset) {
- // Make our source bitmap.
- int src_w = 16, src_h = 34;
- SkBitmap src;
- FillDataToBitmap(src_w, src_h, &src);
-
- // Do a halving of the full bitmap.
- SkBitmap full_results = gfx::ImageOperations::Resize(
- src, gfx::ImageOperations::RESIZE_BOX, gfx::Size(src_w / 2, src_h / 2));
- ASSERT_EQ(src_w / 2, full_results.width());
- ASSERT_EQ(src_h / 2, full_results.height());
-
- // Now do a halving of a a subset, recall the destination subset is in the
- // destination coordinate system (max = half of the original image size).
- gfx::Rect subset_rect(2, 3, 3, 6);
- SkBitmap subset_results = gfx::ImageOperations::Resize(
- src, gfx::ImageOperations::RESIZE_BOX,
- gfx::Size(src_w / 2, src_h / 2), subset_rect);
- ASSERT_EQ(subset_rect.width(), subset_results.width());
- ASSERT_EQ(subset_rect.height(), subset_results.height());
-
- // The computed subset and the corresponding subset of the original image
- // should be the same.
- SkAutoLockPixels full_lock(full_results);
- SkAutoLockPixels subset_lock(subset_results);
- for (int y = 0; y < subset_rect.height(); y++) {
- for (int x = 0; x < subset_rect.width(); x++) {
- ASSERT_EQ(
- *full_results.getAddr32(x + subset_rect.x(), y + subset_rect.y()),
- *subset_results.getAddr32(x, y));
- }
- }
-}
-
-// Resamples an iamge to the same image, it should give almost the same result.
-TEST(ImageOperations, ResampleToSame) {
- // Make our source bitmap.
- int src_w = 16, src_h = 34;
- SkBitmap src;
- FillDataToBitmap(src_w, src_h, &src);
-
- // Do a resize of the full bitmap to the same size. The lanczos filter is good
- // enough that we should get exactly the same image for output.
- SkBitmap results = gfx::ImageOperations::Resize(
- src, gfx::ImageOperations::RESIZE_LANCZOS3, gfx::Size(src_w, src_h));
- ASSERT_EQ(src_w, results.width());
- ASSERT_EQ(src_h, results.height());
-
- SkAutoLockPixels src_lock(src);
- SkAutoLockPixels results_lock(results);
- for (int y = 0; y < src_h; y++) {
- for (int x = 0; x < src_w; x++) {
- EXPECT_EQ(*src.getAddr32(x, y), *results.getAddr32(x, y));
- }
- }
-}
-
diff --git a/base/gfx/img_resize_perftest.cc b/base/gfx/img_resize_perftest.cc
deleted file mode 100644
index 6a4b070..0000000
--- a/base/gfx/img_resize_perftest.cc
+++ /dev/null
@@ -1,70 +0,0 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <stdlib.h>
-#include <time.h>
-
-#include "base/perftimer.h"
-#include "base/gfx/convolver.h"
-#include "base/gfx/image_operations.h"
-#include "base/gfx/image_resizer.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace {
-
-void FillRandomData(char* dest, int byte_count) {
- srand(static_cast<unsigned>(time(NULL)));
- for (int i = 0; i < byte_count; i++)
- dest[i] = rand() * 255 / RAND_MAX;
-}
-
-} // namespace
-
-// Old code gives [1521, 1519]ms for this, 4000x4000 -> 2100x2100 lanczos8
-
-TEST(ImageResizePerf, BigFilter) {
- static const int kSrcWidth = 4000;
- static const int kSrcHeight = 4000;
- static const int kSrcByteSize = kSrcWidth * kSrcHeight * 4;
-
- SkBitmap src_bmp;
- src_bmp.setConfig(SkBitmap::kARGB_8888_Config, kSrcWidth, kSrcHeight);
- src_bmp.allocPixels();
- FillRandomData(reinterpret_cast<char*>(src_bmp.getAddr32(0, 0)),
- kSrcByteSize);
-
- // Make the dest size > 1/2 so the 50% optimization doesn't kick in.
- static const int kDestWidth = 1400;
- static const int kDestHeight = 1400;
-
- PerfTimeLogger resize_timer("resize");
- gfx::ImageResizer resizer(gfx::ImageResizer::LANCZOS3);
- SkBitmap dest = resizer.Resize(src_bmp, kDestWidth, kDestHeight);
-}
-
-// The original image filter we were using took 523ms for this test, while this
-// one takes 857ms.
-// TODO(brettw) make this at least 64% faster.
-TEST(ImageOperationPerf, BigFilter) {
- static const int kSrcWidth = 4000;
- static const int kSrcHeight = 4000;
- static const int kSrcByteSize = kSrcWidth * kSrcHeight * 4;
-
- SkBitmap src_bmp;
- src_bmp.setConfig(SkBitmap::kARGB_8888_Config, kSrcWidth, kSrcHeight);
- src_bmp.allocPixels();
- src_bmp.setIsOpaque(true);
- FillRandomData(reinterpret_cast<char*>(src_bmp.getAddr32(0, 0)),
- kSrcByteSize);
-
- // Make the dest size > 1/2 so the 50% optimization doesn't kick in.
- static const int kDestWidth = 1400;
- static const int kDestHeight = 1400;
-
- PerfTimeLogger resize_timer("resize");
- SkBitmap dest = gfx::ImageOperations::Resize(src_bmp,
- gfx::ImageOperations::RESIZE_LANCZOS3, (float)kDestWidth / (float)kSrcWidth,
- (float)kDestHeight / (float)kSrcHeight);
-}
-
diff --git a/base/gfx/native_theme.cc b/base/gfx/native_theme.cc
index 71289d8..8c7914d 100644
--- a/base/gfx/native_theme.cc
+++ b/base/gfx/native_theme.cc
@@ -10,11 +10,11 @@
#include <vssym32.h>
#include "base/gfx/gdi_util.h"
-#include "base/gfx/skia_utils.h"
#include "base/gfx/rect.h"
#include "base/logging.h"
#include "base/scoped_handle.h"
#include "skia/ext/platform_canvas.h"
+#include "skia/ext/skia_utils_win.h"
#include "skia/include/SkShader.h"
namespace gfx {
@@ -213,8 +213,8 @@ HRESULT NativeTheme::PaintScrollbarTrack(HDC hdc,
} else {
// Create a 2x2 checkerboard pattern using the 3D face and highlight
// colors.
- SkColor face = COLORREFToSkColor(color3DFace);
- SkColor highlight = COLORREFToSkColor(GetSysColor(COLOR_3DHILIGHT));
+ SkColor face = skia::COLORREFToSkColor(color3DFace);
+ SkColor highlight = skia::COLORREFToSkColor(GetSysColor(COLOR_3DHILIGHT));
SkColor buffer[] = { face, highlight, highlight, face };
SkBitmap bitmap;
bitmap.setConfig(SkBitmap::kARGB_8888_Config, 2, 2);
@@ -232,7 +232,7 @@ HRESULT NativeTheme::PaintScrollbarTrack(HDC hdc,
shader->setLocalMatrix(matrix);
SkPaint paint;
paint.setShader(shader)->unref();
- canvas->drawIRect(RECTToSkIRect(*target_rect), paint);
+ canvas->drawIRect(skia::RECTToSkIRect(*target_rect), paint);
}
if (classic_state & DFCS_PUSHED)
InvertRect(hdc, target_rect);
@@ -466,7 +466,7 @@ HRESULT NativeTheme::GetThemeColor(ThemeName theme,
COLORREF color_ref;
if (get_theme_color_(handle, part_id, state_id, prop_id, &color_ref) ==
S_OK) {
- *color = gfx::COLORREFToSkColor(color_ref);
+ *color = skia::COLORREFToSkColor(color_ref);
return S_OK;
}
}
@@ -480,7 +480,7 @@ SkColor NativeTheme::GetThemeColorWithDefault(ThemeName theme,
int default_sys_color) const {
SkColor color;
if (GetThemeColor(theme, part_id, state_id, prop_id, &color) != S_OK)
- color = gfx::COLORREFToSkColor(GetSysColor(default_sys_color));
+ color = skia::COLORREFToSkColor(GetSysColor(default_sys_color));
return color;
}
diff --git a/base/gfx/skia_utils.cc b/base/gfx/skia_utils.cc
deleted file mode 100644
index 7b70056..0000000
--- a/base/gfx/skia_utils.cc
+++ /dev/null
@@ -1,75 +0,0 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/gfx/skia_utils.h"
-
-#include "base/logging.h"
-#include "SkRect.h"
-#include "SkGradientShader.h"
-
-namespace {
-
-COMPILE_ASSERT(offsetof(RECT, left) == offsetof(SkIRect, fLeft), o1);
-COMPILE_ASSERT(offsetof(RECT, top) == offsetof(SkIRect, fTop), o2);
-COMPILE_ASSERT(offsetof(RECT, right) == offsetof(SkIRect, fRight), o3);
-COMPILE_ASSERT(offsetof(RECT, bottom) == offsetof(SkIRect, fBottom), o4);
-COMPILE_ASSERT(sizeof(RECT().left) == sizeof(SkIRect().fLeft), o5);
-COMPILE_ASSERT(sizeof(RECT().top) == sizeof(SkIRect().fTop), o6);
-COMPILE_ASSERT(sizeof(RECT().right) == sizeof(SkIRect().fRight), o7);
-COMPILE_ASSERT(sizeof(RECT().bottom) == sizeof(SkIRect().fBottom), o8);
-COMPILE_ASSERT(sizeof(RECT) == sizeof(SkIRect), o9);
-
-} // namespace
-
-namespace gfx {
-
-POINT SkPointToPOINT(const SkPoint& point) {
- POINT win_point = { SkScalarRound(point.fX), SkScalarRound(point.fY) };
- return win_point;
-}
-
-SkRect RECTToSkRect(const RECT& rect) {
- SkRect sk_rect = { SkIntToScalar(rect.left), SkIntToScalar(rect.top),
- SkIntToScalar(rect.right), SkIntToScalar(rect.bottom) };
- return sk_rect;
-}
-
-SkShader* CreateGradientShader(int start_point,
- int end_point,
- SkColor start_color,
- SkColor end_color) {
- SkColor grad_colors[2] = { start_color, end_color};
- SkPoint grad_points[2];
- grad_points[0].set(SkIntToScalar(0), SkIntToScalar(start_point));
- grad_points[1].set(SkIntToScalar(0), SkIntToScalar(end_point));
-
- return SkGradientShader::CreateLinear(
- grad_points, grad_colors, NULL, 2, SkShader::kRepeat_TileMode);
-}
-
-
-SkColor COLORREFToSkColor(COLORREF color) {
-#ifndef _MSC_VER
- return SkColorSetRGB(GetRValue(color), GetGValue(color), GetBValue(color));
-#else
- // ARGB = 0xFF000000 | ((0BGR -> RGB0) >> 8)
- return 0xFF000000u | (_byteswap_ulong(color) >> 8);
-#endif
-}
-
-COLORREF SkColorToCOLORREF(SkColor color) {
- // Currently, Alpha is always 255 or the color is 0 so there is no need to
- // demultiply the channels. If this DCHECK() is ever hit, the full
- // (SkColorGetX(color) * 255 / a) will have to be added in the conversion.
- DCHECK((0xFF == SkColorGetA(color)) || (0 == color));
-#ifndef _MSC_VER
- return RGB(SkColorGetR(color), SkColorGetG(color), SkColorGetB(color));
-#else
- // 0BGR = ((ARGB -> BGRA) >> 8)
- return (_byteswap_ulong(color) >> 8);
-#endif
-}
-
-} // namespace gfx
-
diff --git a/base/gfx/skia_utils.h b/base/gfx/skia_utils.h
deleted file mode 100644
index 8509072..0000000
--- a/base/gfx/skia_utils.h
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef BASE_GFX_SKIA_UTILS_H__
-#define BASE_GFX_SKIA_UTILS_H__
-
-#include "SkColor.h"
-#include "SkShader.h"
-
-struct SkIRect;
-struct SkPoint;
-struct SkRect;
-typedef unsigned long DWORD;
-typedef DWORD COLORREF;
-typedef struct tagPOINT POINT;
-typedef struct tagRECT RECT;
-
-namespace gfx {
-
-// Converts a Skia point to a Windows POINT.
-POINT SkPointToPOINT(const SkPoint& point);
-
-// Converts a Windows RECT to a Skia rect.
-SkRect RECTToSkRect(const RECT& rect);
-
-// Converts a Windows RECT to a Skia rect.
-// Both use same in-memory format. Verified by COMPILE_ASSERT() in
-// skia_utils.cc.
-inline const SkIRect& RECTToSkIRect(const RECT& rect) {
- return reinterpret_cast<const SkIRect&>(rect);
-}
-
-// Converts a Skia rect to a Windows RECT.
-// Both use same in-memory format. Verified by COMPILE_ASSERT() in
-// skia_utils.cc.
-inline const RECT& SkIRectToRECT(const SkIRect& rect) {
- return reinterpret_cast<const RECT&>(rect);
-}
-
-// Creates a vertical gradient shader. The caller owns the shader.
-SkShader* CreateGradientShader(int start_point,
- int end_point,
- SkColor start_color,
- SkColor end_color);
-
-// Converts COLORREFs (0BGR) to the ARGB layout Skia expects.
-SkColor COLORREFToSkColor(COLORREF color);
-
-// Converts ARGB to COLORREFs (0BGR).
-COLORREF SkColorToCOLORREF(SkColor color);
-
-} // namespace gfx
-
-#endif
-
diff --git a/base/gfx/skia_utils_mac.cc b/base/gfx/skia_utils_mac.cc
deleted file mode 100644
index b5962c3..0000000
--- a/base/gfx/skia_utils_mac.cc
+++ /dev/null
@@ -1,83 +0,0 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/gfx/skia_utils_mac.h"
-
-#include "base/logging.h"
-#include "SkMatrix.h"
-#include "SkRect.h"
-
-namespace gfx {
-
-CGAffineTransform SkMatrixToCGAffineTransform(const SkMatrix& matrix) {
- // CGAffineTransforms don't support perspective transforms, so make sure
- // we don't get those.
- DCHECK(matrix[SkMatrix::kMPersp0] == 0.0f);
- DCHECK(matrix[SkMatrix::kMPersp1] == 0.0f);
- DCHECK(matrix[SkMatrix::kMPersp2] == 1.0f);
-
- return CGAffineTransformMake(matrix[SkMatrix::kMScaleX],
- matrix[SkMatrix::kMSkewY],
- matrix[SkMatrix::kMSkewX],
- matrix[SkMatrix::kMScaleY],
- matrix[SkMatrix::kMTransX],
- matrix[SkMatrix::kMTransY]);
-}
-
-SkIRect CGRectToSkIRect(const CGRect& rect) {
- SkIRect sk_rect = {
- SkScalarRound(rect.origin.x),
- SkScalarRound(rect.origin.y),
- SkScalarRound(rect.origin.x + rect.size.width),
- SkScalarRound(rect.origin.y + rect.size.height)
- };
- return sk_rect;
-}
-
-SkRect CGRectToSkRect(const CGRect& rect) {
- SkRect sk_rect = {
- rect.origin.x,
- rect.origin.y,
- rect.origin.x + rect.size.width,
- rect.origin.y + rect.size.height,
- };
- return sk_rect;
-}
-
-CGRect SkIRectToCGRect(const SkIRect& rect) {
- CGRect cg_rect = {
- { rect.fLeft, rect.fTop },
- { rect.fRight - rect.fLeft, rect.fBottom - rect.fTop }
- };
- return cg_rect;
-}
-
-CGRect SkRectToCGRect(const SkRect& rect) {
- CGRect cg_rect = {
- { rect.fLeft, rect.fTop },
- { rect.fRight - rect.fLeft, rect.fBottom - rect.fTop }
- };
- return cg_rect;
-}
-
-// Converts CGColorRef to the ARGB layout Skia expects.
-SkColor CGColorRefToSkColor(CGColorRef color) {
- DCHECK(CGColorGetNumberOfComponents(color) == 4);
- const CGFloat *components = CGColorGetComponents(color);
- return SkColorSetARGB(SkScalarRound(255.0 * components[3]), // alpha
- SkScalarRound(255.0 * components[0]), // red
- SkScalarRound(255.0 * components[1]), // green
- SkScalarRound(255.0 * components[2])); // blue
-}
-
-// Converts ARGB to CGColorRef.
-CGColorRef SkColorToCGColorRef(SkColor color) {
- return CGColorCreateGenericRGB(SkColorGetR(color) / 255.0,
- SkColorGetG(color) / 255.0,
- SkColorGetB(color) / 255.0,
- SkColorGetA(color) / 255.0);
-}
-
-} // namespace gfx
-
diff --git a/base/gfx/skia_utils_mac.h b/base/gfx/skia_utils_mac.h
deleted file mode 100644
index a99905f..0000000
--- a/base/gfx/skia_utils_mac.h
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-
-#ifndef BASE_GFX_SKIA_UTILS_MAC_H__
-#define BASE_GFX_SKIA_UTILS_MAC_H__
-
-#include "SkColor.h"
-#include <CoreGraphics/CGColor.h>
-
-struct SkMatrix;
-struct SkIRect;
-struct SkPoint;
-struct SkRect;
-
-namespace gfx {
-
-// Converts a Skia point to a CoreGraphics CGPoint.
-// Both use same in-memory format.
-inline const CGPoint& SkPointToCGPoint(const SkPoint& point) {
- return reinterpret_cast<const CGPoint&>(point);
-}
-
-// Converts a CoreGraphics point to a Skia CGPoint.
-// Both use same in-memory format.
-inline const SkPoint& CGPointToSkPoint(const CGPoint& point) {
- return reinterpret_cast<const SkPoint&>(point);
-}
-
-// Matrix converters.
-CGAffineTransform SkMatrixToCGAffineTransform(const SkMatrix& matrix);
-
-// Rectangle converters.
-SkRect CGRectToSkRect(const CGRect& rect);
-SkIRect CGRectToSkIRect(const CGRect& rect);
-
-// Converts a Skia rect to a CoreGraphics CGRect.
-CGRect SkIRectToCGRect(const SkIRect& rect);
-CGRect SkRectToCGRect(const SkRect& rect);
-
-// Converts CGColorRef to the ARGB layout Skia expects.
-SkColor CGColorRefToSkColor(CGColorRef color);
-
-// Converts ARGB to CGColorRef.
-CGColorRef SkColorToCGColorRef(SkColor color);
-
-} // namespace gfx
-
-#endif
-