update dev300-m57
[ooovba.git] / agg / inc / agg_span_image_resample_gray.h
blobac660a4409937c50eaefef8a62d83ab5fe7377be
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_IMAGE_RESAMPLE_GRAY_INCLUDED
17 #define AGG_SPAN_IMAGE_RESAMPLE_GRAY_INCLUDED
19 #include "agg_color_gray.h"
20 #include "agg_span_image_resample.h"
22 namespace agg
25 //========================================span_image_resample_gray_affine
26 template<class ColorT,
27 class Allocator = span_allocator<ColorT> >
28 class span_image_resample_gray_affine :
29 public span_image_resample_affine<ColorT, Allocator>
31 public:
32 typedef ColorT color_type;
33 typedef Allocator alloc_type;
34 typedef span_image_resample_affine<color_type, alloc_type> base_type;
35 typedef typename base_type::interpolator_type interpolator_type;
36 typedef typename color_type::value_type value_type;
37 typedef typename color_type::long_type long_type;
38 enum
40 base_shift = color_type::base_shift,
41 base_mask = color_type::base_mask,
42 downscale_shift = image_filter_shift
45 //--------------------------------------------------------------------
46 span_image_resample_gray_affine(alloc_type& alloc) : base_type(alloc) {}
48 //--------------------------------------------------------------------
49 span_image_resample_gray_affine(alloc_type& alloc,
50 const rendering_buffer& src,
51 const color_type& back_color,
52 interpolator_type& inter,
53 const image_filter_lut& filter) :
54 base_type(alloc, src, back_color, inter, filter)
58 //--------------------------------------------------------------------
59 color_type* generate(int x, int y, unsigned len)
61 base_type::interpolator().begin(x + base_type::filter_dx_dbl(),
62 y + base_type::filter_dy_dbl(), len);
64 long_type fg;
65 long_type src_alpha;
66 value_type back_v = base_type::background_color().v;
67 value_type back_a = base_type::background_color().a;
69 color_type* span = base_type::allocator().span();
71 int diameter = base_type::filter().diameter();
72 int filter_size = diameter << image_subpixel_shift;
73 int radius_x = (diameter * base_type::m_rx) >> 1;
74 int radius_y = (diameter * base_type::m_ry) >> 1;
75 int maxx = base_type::source_image().width() - 1;
76 int maxy = base_type::source_image().height() - 1;
78 const int16* weight_array = base_type::filter().weight_array();
82 base_type::interpolator().coordinates(&x, &y);
84 x += base_type::filter_dx_int() - radius_x;
85 y += base_type::filter_dy_int() - radius_y;
87 fg = src_alpha = image_filter_size / 2;
89 int y_lr = y >> image_subpixel_shift;
90 int y_hr = ((image_subpixel_mask - (y & image_subpixel_mask)) *
91 base_type::m_ry_inv) >>
92 image_subpixel_shift;
93 int total_weight = 0;
94 int x_lr_ini = x >> image_subpixel_shift;
95 int x_hr_ini = ((image_subpixel_mask - (x & image_subpixel_mask)) *
96 base_type::m_rx_inv) >>
97 image_subpixel_shift;
100 int weight_y = weight_array[y_hr];
101 int x_lr = x_lr_ini;
102 int x_hr = x_hr_ini;
103 if(y_lr >= 0 && y_lr <= maxy)
105 const value_type* fg_ptr = (const value_type*)
106 base_type::source_image().row(y_lr) + x_lr;
109 int weight = (weight_y * weight_array[x_hr] +
110 image_filter_size / 2) >>
111 downscale_shift;
113 if(x_lr >= 0 && x_lr <= maxx)
115 fg += *fg_ptr * weight;
116 src_alpha += base_mask * weight;
118 else
120 fg += back_v * weight;
121 src_alpha += back_a * weight;
123 total_weight += weight;
124 x_hr += base_type::m_rx_inv;
125 ++fg_ptr;
126 ++x_lr;
128 while(x_hr < filter_size);
130 else
134 int weight = (weight_y * weight_array[x_hr] +
135 image_filter_size / 2) >>
136 downscale_shift;
138 total_weight += weight;
139 fg += back_v * weight;
140 src_alpha += back_a * weight;
141 x_hr += base_type::m_rx_inv;
143 while(x_hr < filter_size);
145 y_hr += base_type::m_ry_inv;
146 ++y_lr;
148 while(y_hr < filter_size);
150 fg /= total_weight;
151 src_alpha /= total_weight;
153 if(fg < 0) fg = 0;
154 if(src_alpha < 0) src_alpha = 0;
156 if(src_alpha > base_mask) src_alpha = base_mask;
157 if(fg > src_alpha) fg = src_alpha;
159 span->v = (value_type)fg;
160 span->a = (value_type)src_alpha;
162 ++span;
163 ++base_type::interpolator();
164 } while(--len);
165 return base_type::allocator().span();
175 //==============================================span_image_resample_gray
176 template<class ColorT,
177 class Interpolator,
178 class Allocator = span_allocator<ColorT> >
179 class span_image_resample_gray :
180 public span_image_resample<ColorT, Interpolator, Allocator>
182 public:
183 typedef ColorT color_type;
184 typedef Interpolator interpolator_type;
185 typedef Allocator alloc_type;
186 typedef span_image_resample<color_type, interpolator_type, alloc_type> base_type;
187 typedef typename color_type::value_type value_type;
188 typedef typename color_type::long_type long_type;
189 enum
191 base_shift = color_type::base_shift,
192 base_mask = color_type::base_mask,
193 downscale_shift = image_filter_shift
196 //--------------------------------------------------------------------
197 span_image_resample_gray(alloc_type& alloc) :
198 base_type(alloc)
201 //--------------------------------------------------------------------
202 span_image_resample_gray(alloc_type& alloc,
203 const rendering_buffer& src,
204 const color_type& back_color,
205 interpolator_type& inter,
206 const image_filter_lut& filter) :
207 base_type(alloc, src, back_color, inter, filter)
210 //--------------------------------------------------------------------
211 color_type* generate(int x, int y, unsigned len)
213 color_type* span = base_type::allocator().span();
214 base_type::interpolator().begin(x + base_type::filter_dx_dbl(),
215 y + base_type::filter_dy_dbl(), len);
216 long_type fg;
217 long_type src_alpha;
218 value_type back_v = base_type::background_color().v;
219 value_type back_a = base_type::background_color().a;
221 int diameter = base_type::filter().diameter();
222 int filter_size = diameter << image_subpixel_shift;
224 const int16* weight_array = base_type::filter().weight_array();
228 int rx;
229 int ry;
230 int rx_inv = image_subpixel_size;
231 int ry_inv = image_subpixel_size;
232 base_type::interpolator().coordinates(&x, &y);
233 base_type::interpolator().local_scale(&rx, &ry);
235 rx = (rx * base_type::m_blur_x) >> image_subpixel_shift;
236 ry = (ry * base_type::m_blur_y) >> image_subpixel_shift;
238 if(rx < image_subpixel_size)
240 rx = image_subpixel_size;
242 else
244 if(rx > image_subpixel_size * base_type::m_scale_limit)
246 rx = image_subpixel_size * base_type::m_scale_limit;
248 rx_inv = image_subpixel_size * image_subpixel_size / rx;
251 if(ry < image_subpixel_size)
253 ry = image_subpixel_size;
255 else
257 if(ry > image_subpixel_size * base_type::m_scale_limit)
259 ry = image_subpixel_size * base_type::m_scale_limit;
261 ry_inv = image_subpixel_size * image_subpixel_size / ry;
264 int radius_x = (diameter * rx) >> 1;
265 int radius_y = (diameter * ry) >> 1;
266 int maxx = base_type::source_image().width() - 1;
267 int maxy = base_type::source_image().height() - 1;
269 x += base_type::filter_dx_int() - radius_x;
270 y += base_type::filter_dy_int() - radius_y;
272 fg = src_alpha = image_filter_size / 2;
274 int y_lr = y >> image_subpixel_shift;
275 int y_hr = ((image_subpixel_mask - (y & image_subpixel_mask)) *
276 ry_inv) >>
277 image_subpixel_shift;
278 int total_weight = 0;
279 int x_lr_ini = x >> image_subpixel_shift;
280 int x_hr_ini = ((image_subpixel_mask - (x & image_subpixel_mask)) *
281 rx_inv) >>
282 image_subpixel_shift;
286 int weight_y = weight_array[y_hr];
287 int x_lr = x_lr_ini;
288 int x_hr = x_hr_ini;
289 if(y_lr >= 0 && y_lr <= maxy)
291 const value_type* fg_ptr = (const value_type*)
292 base_type::source_image().row(y_lr) + x_lr;
295 int weight = (weight_y * weight_array[x_hr] +
296 image_filter_size / 2) >>
297 downscale_shift;
299 if(x_lr >= 0 && x_lr <= maxx)
301 fg += *fg_ptr * weight;
302 src_alpha += base_mask * weight;
304 else
306 fg += back_v * weight;
307 src_alpha += back_a * weight;
309 total_weight += weight;
310 x_hr += rx_inv;
311 ++fg_ptr;
312 ++x_lr;
314 while(x_hr < filter_size);
316 else
320 int weight = (weight_y * weight_array[x_hr] +
321 image_filter_size / 2) >>
322 downscale_shift;
324 total_weight += weight;
325 fg += back_v * weight;
326 src_alpha += back_a * weight;
327 x_hr += rx_inv;
329 while(x_hr < filter_size);
331 y_hr += ry_inv;
332 ++y_lr;
334 while(y_hr < filter_size);
336 fg /= total_weight;
337 src_alpha /= total_weight;
339 if(fg < 0) fg = 0;
340 if(src_alpha < 0) src_alpha = 0;
342 if(src_alpha > base_mask) src_alpha = base_mask;
343 if(fg > src_alpha) fg = src_alpha;
345 span->v = (value_type)fg;
346 span->a = (value_type)src_alpha;
348 ++span;
349 ++base_type::interpolator();
350 } while(--len);
351 return base_type::allocator().span();
359 #endif