update dev300-m58
[ooovba.git] / agg / inc / agg_span_pattern_resample_gray.h
blob650e913c35b7134639000934f2eeb9c005fb443e
1 //----------------------------------------------------------------------------
2 // Anti-Grain Geometry - Version 2.3
3 // Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
4 //
5 // Permission to copy, use, modify, sell and distribute this software
6 // is granted provided this copyright notice appears in all copies.
7 // This software is provided "as is" without express or implied
8 // warranty, and with no claim as to its suitability for any purpose.
9 //
10 //----------------------------------------------------------------------------
11 // Contact: mcseem@antigrain.com
12 // mcseemagg@yahoo.com
13 // http://www.antigrain.com
14 //----------------------------------------------------------------------------
16 #ifndef AGG_SPAN_PATTERN_RESAMPLE_GRAY_INCLUDED
17 #define AGG_SPAN_PATTERN_RESAMPLE_GRAY_INCLUDED
19 #include "agg_color_gray.h"
20 #include "agg_span_image_resample.h"
22 namespace agg
25 //=======================================span_pattern_resample_gray_affine
26 template<class ColorT,
27 class WrapModeX,
28 class WrapModeY,
29 class Allocator = span_allocator<ColorT> >
30 class span_pattern_resample_gray_affine :
31 public span_image_resample_affine<ColorT, Allocator>
33 public:
34 typedef ColorT color_type;
35 typedef Allocator alloc_type;
36 typedef span_image_resample_affine<color_type, alloc_type> base_type;
37 typedef typename base_type::interpolator_type interpolator_type;
38 typedef typename color_type::value_type value_type;
39 typedef typename color_type::long_type long_type;
40 enum
42 base_shift = color_type::base_shift,
43 base_mask = color_type::base_mask,
44 downscale_shift = image_filter_shift
47 //--------------------------------------------------------------------
48 span_pattern_resample_gray_affine(alloc_type& alloc) :
49 base_type(alloc),
50 m_wrap_mode_x(1),
51 m_wrap_mode_y(1)
54 //--------------------------------------------------------------------
55 span_pattern_resample_gray_affine(alloc_type& alloc,
56 const rendering_buffer& src,
57 interpolator_type& inter,
58 const image_filter_lut& filter) :
59 base_type(alloc, src, color_type(0,0), inter, filter),
60 m_wrap_mode_x(src.width()),
61 m_wrap_mode_y(src.height())
64 //--------------------------------------------------------------------
65 void source_image(const rendering_buffer& src)
67 base_type::source_image(src);
68 m_wrap_mode_x = WrapModeX(src.width());
69 m_wrap_mode_y = WrapModeX(src.height());
72 //--------------------------------------------------------------------
73 color_type* generate(int x, int y, unsigned len)
75 color_type* span = base_type::allocator().span();
76 interpolator_type& intr = base_type::interpolator();
77 intr.begin(x + base_type::filter_dx_dbl(),
78 y + base_type::filter_dy_dbl(), len);
79 long_type fg;
81 int diameter = base_type::filter().diameter();
82 int filter_size = diameter << image_subpixel_shift;
83 int radius_x = (diameter * base_type::m_rx) >> 1;
84 int radius_y = (diameter * base_type::m_ry) >> 1;
85 int maxx = base_type::source_image().width() - 1;
86 int maxy = base_type::source_image().height() - 1;
87 const int16* weight_array = base_type::filter().weight_array();
91 intr.coordinates(&x, &y);
93 x += base_type::filter_dx_int() - radius_x;
94 y += base_type::filter_dy_int() - radius_y;
96 fg = image_filter_size / 2;
98 int y_lr = m_wrap_mode_y(y >> image_subpixel_shift);
99 int y_hr = ((image_subpixel_mask - (y & image_subpixel_mask)) *
100 base_type::m_ry_inv) >>
101 image_subpixel_shift;
102 int total_weight = 0;
103 int x_lr_ini = x >> image_subpixel_shift;
104 int x_hr_ini = ((image_subpixel_mask - (x & image_subpixel_mask)) *
105 base_type::m_rx_inv) >>
106 image_subpixel_shift;
109 int weight_y = weight_array[y_hr];
110 int x_lr = m_wrap_mode_x(x_lr_ini);
111 int x_hr = x_hr_ini;
112 const value_type* row_ptr = (const value_type*)base_type::source_image().row(y_lr);
115 const value_type* fg_ptr = row_ptr + x_lr;
116 int weight = (weight_y * weight_array[x_hr] +
117 image_filter_size / 2) >>
118 downscale_shift;
120 fg += *fg_ptr * weight;
121 total_weight += weight;
122 x_hr += base_type::m_rx_inv;
123 x_lr = ++m_wrap_mode_x;
125 while(x_hr < filter_size);
127 y_hr += base_type::m_ry_inv;
128 y_lr = ++m_wrap_mode_y;
129 } while(y_hr < filter_size);
131 fg /= total_weight;
133 if(fg < 0) fg = 0;
134 if(fg > base_mask) fg = base_mask;
136 span->v = (value_type)fg;
137 span->a = (value_type)base_mask;
139 ++span;
140 ++intr;
141 } while(--len);
142 return base_type::allocator().span();
145 private:
146 WrapModeX m_wrap_mode_x;
147 WrapModeY m_wrap_mode_y;
156 //============================================span_pattern_resample_gray
157 template<class ColorT,
158 class Interpolator,
159 class WrapModeX,
160 class WrapModeY,
161 class Allocator = span_allocator<ColorT> >
162 class span_pattern_resample_gray :
163 public span_image_resample<ColorT, Interpolator, Allocator>
165 public:
166 typedef ColorT color_type;
167 typedef Interpolator interpolator_type;
168 typedef Allocator alloc_type;
169 typedef span_image_resample<color_type, interpolator_type, alloc_type> base_type;
170 typedef typename color_type::value_type value_type;
171 typedef typename color_type::long_type long_type;
172 enum
174 base_shift = color_type::base_shift,
175 base_mask = color_type::base_mask,
176 downscale_shift = image_filter_shift
179 //--------------------------------------------------------------------
180 span_pattern_resample_gray(alloc_type& alloc) :
181 base_type(alloc),
182 m_wrap_mode_x(1),
183 m_wrap_mode_y(1)
186 //--------------------------------------------------------------------
187 span_pattern_resample_gray(alloc_type& alloc,
188 const rendering_buffer& src,
189 interpolator_type& inter,
190 const image_filter_lut& filter) :
191 base_type(alloc, src, color_type(0,0), inter, filter),
192 m_wrap_mode_x(src.width()),
193 m_wrap_mode_y(src.height())
196 //--------------------------------------------------------------------
197 void source_image(const rendering_buffer& src)
199 base_type::source_image(src);
200 m_wrap_mode_x = WrapModeX(src.width());
201 m_wrap_mode_y = WrapModeX(src.height());
204 //--------------------------------------------------------------------
205 color_type* generate(int x, int y, unsigned len)
207 color_type* span = base_type::allocator().span();
208 interpolator_type& intr = base_type::interpolator();
209 intr.begin(x + base_type::filter_dx_dbl(),
210 y + base_type::filter_dy_dbl(), len);
211 long_type fg;
213 int diameter = base_type::filter().diameter();
214 int filter_size = diameter << image_subpixel_shift;
215 const int16* weight_array = base_type::filter().weight_array();
219 int rx;
220 int ry;
221 int rx_inv = image_subpixel_size;
222 int ry_inv = image_subpixel_size;
223 intr.coordinates(&x, &y);
224 intr.local_scale(&rx, &ry);
226 rx = (rx * base_type::m_blur_x) >> image_subpixel_shift;
227 ry = (ry * base_type::m_blur_y) >> image_subpixel_shift;
229 if(rx < image_subpixel_size)
231 rx = image_subpixel_size;
233 else
235 if(rx > image_subpixel_size * base_type::m_scale_limit)
237 rx = image_subpixel_size * base_type::m_scale_limit;
239 rx_inv = image_subpixel_size * image_subpixel_size / rx;
242 if(ry < image_subpixel_size)
244 ry = image_subpixel_size;
246 else
248 if(ry > image_subpixel_size * base_type::m_scale_limit)
250 ry = image_subpixel_size * base_type::m_scale_limit;
252 ry_inv = image_subpixel_size * image_subpixel_size / ry;
255 int radius_x = (diameter * rx) >> 1;
256 int radius_y = (diameter * ry) >> 1;
257 int maxx = base_type::source_image().width() - 1;
258 int maxy = base_type::source_image().height() - 1;
260 x += base_type::filter_dx_int() - radius_x;
261 y += base_type::filter_dy_int() - radius_y;
263 fg = image_filter_size / 2;
265 int y_lr = m_wrap_mode_y(y >> image_subpixel_shift);
266 int y_hr = ((image_subpixel_mask - (y & image_subpixel_mask)) *
267 ry_inv) >>
268 image_subpixel_shift;
269 int total_weight = 0;
270 int x_lr_ini = x >> image_subpixel_shift;
271 int x_hr_ini = ((image_subpixel_mask - (x & image_subpixel_mask)) *
272 rx_inv) >>
273 image_subpixel_shift;
277 int weight_y = weight_array[y_hr];
278 int x_lr = m_wrap_mode_x(x_lr_ini);
279 int x_hr = x_hr_ini;
280 const value_type* row_ptr = (const value_type*)base_type::source_image().row(y_lr);
283 const value_type* fg_ptr = row_ptr + x_lr;
284 int weight = (weight_y * weight_array[x_hr] +
285 image_filter_size / 2) >>
286 downscale_shift;
287 fg += *fg_ptr * weight;
288 total_weight += weight;
289 x_hr += rx_inv;
290 x_lr = ++m_wrap_mode_x;
292 while(x_hr < filter_size);
293 y_hr += ry_inv;
294 y_lr = ++m_wrap_mode_y;
296 while(y_hr < filter_size);
298 fg /= total_weight;
300 if(fg < 0) fg = 0;
301 if(fg > base_mask) fg = base_mask;
303 span->v = (value_type)fg;
304 span->a = (value_type)base_mask;
306 ++span;
307 ++intr;
308 } while(--len);
309 return base_type::allocator().span();
312 private:
313 WrapModeX m_wrap_mode_x;
314 WrapModeY m_wrap_mode_y;
320 #endif