1 //----------------------------------------------------------------------------
2 // Anti-Grain Geometry - Version 2.3
3 // Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
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.
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"
25 //=======================================span_pattern_resample_gray_affine
26 template<class ColorT
,
29 class Allocator
= span_allocator
<ColorT
> >
30 class span_pattern_resample_gray_affine
:
31 public span_image_resample_affine
<ColorT
, Allocator
>
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
;
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
) :
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
);
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
);
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) >>
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
);
134 if(fg
> base_mask
) fg
= base_mask
;
136 span
->v
= (value_type
)fg
;
137 span
->a
= (value_type
)base_mask
;
142 return base_type::allocator().span();
146 WrapModeX m_wrap_mode_x
;
147 WrapModeY m_wrap_mode_y
;
156 //============================================span_pattern_resample_gray
157 template<class ColorT
,
161 class Allocator
= span_allocator
<ColorT
> >
162 class span_pattern_resample_gray
:
163 public span_image_resample
<ColorT
, Interpolator
, Allocator
>
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
;
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
) :
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
);
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();
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
;
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
;
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
)) *
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
)) *
273 image_subpixel_shift
;
277 int weight_y
= weight_array
[y_hr
];
278 int x_lr
= m_wrap_mode_x(x_lr_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) >>
287 fg
+= *fg_ptr
* weight
;
288 total_weight
+= weight
;
290 x_lr
= ++m_wrap_mode_x
;
292 while(x_hr
< filter_size
);
294 y_lr
= ++m_wrap_mode_y
;
296 while(y_hr
< filter_size
);
301 if(fg
> base_mask
) fg
= base_mask
;
303 span
->v
= (value_type
)fg
;
304 span
->a
= (value_type
)base_mask
;
309 return base_type::allocator().span();
313 WrapModeX m_wrap_mode_x
;
314 WrapModeY m_wrap_mode_y
;