Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(235)

Side by Side Diff: skia/ext/image_operations.cc

Issue 13726: Move Image operations and convolver to the skia namespace and clean up a few ... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 12 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « skia/ext/image_operations.h ('k') | skia/ext/image_operations_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2006-2008 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 #define _USE_MATH_DEFINES 5 #define _USE_MATH_DEFINES
6 #include <cmath> 6 #include <cmath>
7 #include <limits> 7 #include <limits>
8 #include <vector> 8 #include <vector>
9 9
10 #include "skia/ext/image_operations.h" 10 #include "skia/ext/image_operations.h"
11 11
12 #include "base/gfx/rect.h" 12 #include "base/gfx/rect.h"
13 #include "base/gfx/size.h" 13 #include "base/gfx/size.h"
14 #include "base/logging.h" 14 #include "base/logging.h"
15 #include "base/stack_container.h" 15 #include "base/stack_container.h"
16 #include "SkBitmap.h" 16 #include "SkBitmap.h"
17 #include "skia/ext/convolver.h" 17 #include "skia/ext/convolver.h"
18 18
19 namespace gfx { 19 namespace skia {
20
21 // TODO(brettw) remove this and put this file in the skia namespace.
22 using namespace gfx;
20 23
21 namespace { 24 namespace {
22 25
23 // Returns the ceiling/floor as an integer. 26 // Returns the ceiling/floor as an integer.
24 inline int CeilInt(float val) { 27 inline int CeilInt(float val) {
25 return static_cast<int>(ceil(val)); 28 return static_cast<int>(ceil(val));
26 } 29 }
27 inline int FloorInt(float val) { 30 inline int FloorInt(float val) {
28 return static_cast<int>(floor(val)); 31 return static_cast<int>(floor(val));
29 } 32 }
(...skipping 25 matching lines...) Expand all
55 sin(xpi / filter_size) / (xpi / filter_size); // sinc(x/filter_size) 58 sin(xpi / filter_size) / (xpi / filter_size); // sinc(x/filter_size)
56 } 59 }
57 60
58 // ResizeFilter ---------------------------------------------------------------- 61 // ResizeFilter ----------------------------------------------------------------
59 62
60 // Encapsulates computation and storage of the filters required for one complete 63 // Encapsulates computation and storage of the filters required for one complete
61 // resize operation. 64 // resize operation.
62 class ResizeFilter { 65 class ResizeFilter {
63 public: 66 public:
64 ResizeFilter(ImageOperations::ResizeMethod method, 67 ResizeFilter(ImageOperations::ResizeMethod method,
65 const Size& src_full_size, 68 int src_full_width, int src_full_height,
66 const Size& dest_size, 69 int dest_width, int dest_height,
67 const Rect& dest_subset); 70 const gfx::Rect& dest_subset);
68 71
69 // Returns the bounds in the input bitmap of data that is used in the output. 72 // Returns the bounds in the input bitmap of data that is used in the output.
70 // The filter offsets are within this rectangle. 73 // The filter offsets are within this rectangle.
71 const Rect& src_depend() { return src_depend_; } 74 const gfx::Rect& src_depend() { return src_depend_; }
72 75
73 // Returns the filled filter values. 76 // Returns the filled filter values.
74 const ConvolusionFilter1D& x_filter() { return x_filter_; } 77 const ConvolusionFilter1D& x_filter() { return x_filter_; }
75 const ConvolusionFilter1D& y_filter() { return y_filter_; } 78 const ConvolusionFilter1D& y_filter() { return y_filter_; }
76 79
77 private: 80 private:
78 // Returns the number of pixels that the filer spans, in filter space (the 81 // Returns the number of pixels that the filer spans, in filter space (the
79 // destination image). 82 // destination image).
80 float GetFilterSupport(float scale) { 83 float GetFilterSupport(float scale) {
81 switch (method_) { 84 switch (method_) {
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
116 return EvalLanczos(3, pos); 119 return EvalLanczos(3, pos);
117 default: 120 default:
118 NOTREACHED(); 121 NOTREACHED();
119 return 0; 122 return 0;
120 } 123 }
121 } 124 }
122 125
123 ImageOperations::ResizeMethod method_; 126 ImageOperations::ResizeMethod method_;
124 127
125 // Subset of source the filters will touch. 128 // Subset of source the filters will touch.
126 Rect src_depend_; 129 gfx::Rect src_depend_;
127 130
128 // Size of the filter support on one side only in the destination space. 131 // Size of the filter support on one side only in the destination space.
129 // See GetFilterSupport. 132 // See GetFilterSupport.
130 float x_filter_support_; 133 float x_filter_support_;
131 float y_filter_support_; 134 float y_filter_support_;
132 135
133 // Subset of scaled destination bitmap to compute. 136 // Subset of scaled destination bitmap to compute.
134 Rect out_bounds_; 137 gfx::Rect out_bounds_;
135 138
136 ConvolusionFilter1D x_filter_; 139 ConvolusionFilter1D x_filter_;
137 ConvolusionFilter1D y_filter_; 140 ConvolusionFilter1D y_filter_;
138 141
139 DISALLOW_EVIL_CONSTRUCTORS(ResizeFilter); 142 DISALLOW_EVIL_CONSTRUCTORS(ResizeFilter);
140 }; 143 };
141 144
142 ResizeFilter::ResizeFilter(ImageOperations::ResizeMethod method, 145 ResizeFilter::ResizeFilter(ImageOperations::ResizeMethod method,
143 const Size& src_full_size, 146 int src_full_width, int src_full_height,
144 const Size& dest_size, 147 int dest_width, int dest_height,
145 const Rect& dest_subset) 148 const gfx::Rect& dest_subset)
146 : method_(method), 149 : method_(method),
147 out_bounds_(dest_subset) { 150 out_bounds_(dest_subset) {
148 float scale_x = static_cast<float>(dest_size.width()) / 151 float scale_x = static_cast<float>(dest_width) /
149 static_cast<float>(src_full_size.width()); 152 static_cast<float>(src_full_width);
150 float scale_y = static_cast<float>(dest_size.height()) / 153 float scale_y = static_cast<float>(dest_height) /
151 static_cast<float>(src_full_size.height()); 154 static_cast<float>(src_full_height);
152 155
153 x_filter_support_ = GetFilterSupport(scale_x); 156 x_filter_support_ = GetFilterSupport(scale_x);
154 y_filter_support_ = GetFilterSupport(scale_y); 157 y_filter_support_ = GetFilterSupport(scale_y);
155 158
156 gfx::Rect src_full(0, 0, src_full_size.width(), src_full_size.height()); 159 gfx::Rect src_full(0, 0, src_full_width, src_full_height);
157 gfx::Rect dest_full(0, 0, 160 gfx::Rect dest_full(0, 0,
158 static_cast<int>(src_full_size.width() * scale_x + 0.5), 161 static_cast<int>(src_full_width * scale_x + 0.5),
159 static_cast<int>(src_full_size.height() * scale_y + 0.5)); 162 static_cast<int>(src_full_height * scale_y + 0.5));
160 163
161 // Support of the filter in source space. 164 // Support of the filter in source space.
162 float src_x_support = x_filter_support_ / scale_x; 165 float src_x_support = x_filter_support_ / scale_x;
163 float src_y_support = y_filter_support_ / scale_y; 166 float src_y_support = y_filter_support_ / scale_y;
164 167
165 ComputeFilters(src_full_size.width(), dest_subset.x(), dest_subset.width(), 168 ComputeFilters(src_full_width, dest_subset.x(), dest_subset.width(),
166 scale_x, src_x_support, &x_filter_); 169 scale_x, src_x_support, &x_filter_);
167 ComputeFilters(src_full_size.height(), dest_subset.y(), dest_subset.height(), 170 ComputeFilters(src_full_height, dest_subset.y(), dest_subset.height(),
168 scale_y, src_y_support, &y_filter_); 171 scale_y, src_y_support, &y_filter_);
169 } 172 }
170 173
171 void ResizeFilter::ComputeFilters(int src_size, 174 void ResizeFilter::ComputeFilters(int src_size,
172 int dest_subset_lo, int dest_subset_size, 175 int dest_subset_lo, int dest_subset_size,
173 float scale, float src_support, 176 float scale, float src_support,
174 ConvolusionFilter1D* output) { 177 ConvolusionFilter1D* output) {
175 int dest_subset_hi = dest_subset_lo + dest_subset_size; // [lo, hi) 178 int dest_subset_hi = dest_subset_lo + dest_subset_size; // [lo, hi)
176 179
177 // When we're doing a magnification, the scale will be larger than one. This 180 // When we're doing a magnification, the scale will be larger than one. This
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
247 } 250 }
248 } 251 }
249 252
250 } // namespace 253 } // namespace
251 254
252 // Resize ---------------------------------------------------------------------- 255 // Resize ----------------------------------------------------------------------
253 256
254 // static 257 // static
255 SkBitmap ImageOperations::Resize(const SkBitmap& source, 258 SkBitmap ImageOperations::Resize(const SkBitmap& source,
256 ResizeMethod method, 259 ResizeMethod method,
257 const Size& dest_size, 260 int dest_width, int dest_height,
258 const Rect& dest_subset) { 261 const gfx::Rect& dest_subset) {
259 DCHECK(Rect(dest_size.width(), dest_size.height()).Contains(dest_subset)) << 262 DCHECK(gfx::Rect(dest_width, dest_height).Contains(dest_subset)) <<
260 "The supplied subset does not fall within the destination image."; 263 "The supplied subset does not fall within the destination image.";
261 264
262 // If the size of source or destination is 0, i.e. 0x0, 0xN or Nx0, just 265 // If the size of source or destination is 0, i.e. 0x0, 0xN or Nx0, just
263 // return empty 266 // return empty
264 if (source.width() < 1 || source.height() < 1 || 267 if (source.width() < 1 || source.height() < 1 ||
265 dest_size.width() < 1 || dest_size.height() < 1) 268 dest_width < 1 || dest_height < 1)
266 return SkBitmap(); 269 return SkBitmap();
267 270
268 SkAutoLockPixels locker(source); 271 SkAutoLockPixels locker(source);
269 272
270 ResizeFilter filter(method, Size(source.width(), source.height()), 273 ResizeFilter filter(method, source.width(), source.height(),
271 dest_size, dest_subset); 274 dest_width, dest_height, dest_subset);
272 275
273 // Get a source bitmap encompassing this touched area. We construct the 276 // Get a source bitmap encompassing this touched area. We construct the
274 // offsets and row strides such that it looks like a new bitmap, while 277 // offsets and row strides such that it looks like a new bitmap, while
275 // referring to the old data. 278 // referring to the old data.
276 const uint8* source_subset = 279 const uint8* source_subset =
277 reinterpret_cast<const uint8*>(source.getPixels()); 280 reinterpret_cast<const uint8*>(source.getPixels());
278 281
279 // Convolve into the result. 282 // Convolve into the result.
280 SkBitmap result; 283 SkBitmap result;
281 result.setConfig(SkBitmap::kARGB_8888_Config, 284 result.setConfig(SkBitmap::kARGB_8888_Config,
282 dest_subset.width(), dest_subset.height()); 285 dest_subset.width(), dest_subset.height());
283 result.allocPixels(); 286 result.allocPixels();
284 BGRAConvolve2D(source_subset, static_cast<int>(source.rowBytes()), 287 BGRAConvolve2D(source_subset, static_cast<int>(source.rowBytes()),
285 !source.isOpaque(), filter.x_filter(), filter.y_filter(), 288 !source.isOpaque(), filter.x_filter(), filter.y_filter(),
286 static_cast<unsigned char*>(result.getPixels())); 289 static_cast<unsigned char*>(result.getPixels()));
287 290
288 // Preserve the "opaque" flag for use as an optimization later. 291 // Preserve the "opaque" flag for use as an optimization later.
289 result.setIsOpaque(source.isOpaque()); 292 result.setIsOpaque(source.isOpaque());
290 293
291 return result; 294 return result;
292 } 295 }
293 296
294 // static 297 // static
295 SkBitmap ImageOperations::Resize(const SkBitmap& source, 298 SkBitmap ImageOperations::Resize(const SkBitmap& source,
296 ResizeMethod method, 299 ResizeMethod method,
297 const Size& dest_size) { 300 int dest_width, int dest_height) {
298 Rect dest_subset(0, 0, dest_size.width(), dest_size.height()); 301 gfx::Rect dest_subset(0, 0, dest_width, dest_height);
299 return Resize(source, method, dest_size, dest_subset); 302 return Resize(source, method, dest_width, dest_height, dest_subset);
300 } 303 }
301 304
302 // static 305 // static
303 SkBitmap ImageOperations::CreateBlendedBitmap(const SkBitmap& first, 306 SkBitmap ImageOperations::CreateBlendedBitmap(const SkBitmap& first,
304 const SkBitmap& second, 307 const SkBitmap& second,
305 double alpha) { 308 double alpha) {
306 DCHECK(alpha <= 1 && alpha >= 0); 309 DCHECK(alpha <= 1 && alpha >= 0);
307 DCHECK(first.width() == second.width()); 310 DCHECK(first.width() == second.width());
308 DCHECK(first.height() == second.height()); 311 DCHECK(first.height() == second.height());
309 DCHECK(first.bytesPerPixel() == second.bytesPerPixel()); 312 DCHECK(first.bytesPerPixel() == second.bytesPerPixel());
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
351 SkColorGetB(first_pixel) * first_alpha + 354 SkColorGetB(first_pixel) * first_alpha +
352 SkColorGetB(second_pixel) * alpha); 355 SkColorGetB(second_pixel) * alpha);
353 356
354 dst_row[x] = SkColorSetARGB(a, r, g, b); 357 dst_row[x] = SkColorSetARGB(a, r, g, b);
355 } 358 }
356 } 359 }
357 360
358 return blended; 361 return blended;
359 } 362 }
360 363
361 } // namespace gfx 364 } // namespace skia
362 365
OLDNEW
« no previous file with comments | « skia/ext/image_operations.h ('k') | skia/ext/image_operations_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698