20 #ifndef AGG_IMAGE_FILTERS_INCLUDED 21 #define AGG_IMAGE_FILTERS_INCLUDED 23 #include "agg_array.h" 31 enum image_filter_scale_e
33 image_filter_shift = 14,
34 image_filter_scale = 1 << image_filter_shift,
35 image_filter_mask = image_filter_scale - 1
38 enum image_subpixel_scale_e
40 image_subpixel_shift = 8,
41 image_subpixel_scale = 1 << image_subpixel_shift,
42 image_subpixel_mask = image_subpixel_scale - 1
50 template<
class FilterF>
void calculate(
const FilterF& filter,
51 bool normalization=
true)
54 double r = filter.radius();
57 unsigned pivot = diameter() << (image_subpixel_shift - 1);
58 for(i = 0; i < pivot; i++)
60 double x = double(i) / double(image_subpixel_scale);
61 double y = filter.calc_weight(x);
62 m_weight_array[pivot + i] =
63 m_weight_array[pivot - i] = (int16)iround(y * image_filter_scale);
65 unsigned end = (diameter() << image_subpixel_shift) - 1;
66 m_weight_array[0] = m_weight_array[end];
76 bool normalization=
true)
78 calculate(filter, normalization);
81 double radius()
const {
return m_radius; }
82 unsigned diameter()
const {
return m_diameter; }
83 int start()
const {
return m_start; }
84 const int16* weight_array()
const {
return &m_weight_array[0]; }
88 void realloc_lut(
double radius);
106 calculate(m_filter_function);
109 FilterF m_filter_function;
116 static double radius() {
return 1.0; }
117 static double calc_weight(
double x)
127 static double radius() {
return 1.0; }
128 static double calc_weight(
double x)
130 return 0.5 + 0.5 * std::cos(pi * x);
138 static double radius() {
return 1.0; }
139 static double calc_weight(
double x)
141 return 0.54 + 0.46 * std::cos(pi * x);
148 static double radius() {
return 1.0; }
149 static double calc_weight(
double x)
151 return (2.0 * x - 3.0) * x * x + 1.0;
158 static double radius() {
return 1.5; }
159 static double calc_weight(
double x)
162 if(x < 0.5)
return 0.75 - x * x;
163 if(x < 1.5) {t = x - 1.5;
return 0.5 * t * t;}
171 static double pow3(
double x)
173 return (x <= 0.0) ? 0.0 : x * x * x;
177 static double radius() {
return 2.0; }
178 static double calc_weight(
double x)
182 (pow3(x + 2) - 4 * pow3(x + 1) + 6 * pow3(x) - 4 * pow3(x - 1));
197 i0a = 1.0 / bessel_i0(b);
200 static double radius() {
return 1.0; }
201 double calc_weight(
double x)
const 203 return bessel_i0(a * std::sqrt(1. - x * x)) * i0a;
207 double bessel_i0(
double x)
const 216 for(i = 2; t > epsilon; i++)
219 t *= (double)y / (i * i);
228 static double radius() {
return 2.0; }
229 static double calc_weight(
double x)
231 if(x < 1.0)
return 0.5 * (2.0 + x * x * (-5.0 + x * 3.0));
232 if(x < 2.0)
return 0.5 * (4.0 + x * (-8.0 + x * (5.0 - x)));
241 double q0, q1, q2, q3;
245 p0((6.0 - 2.0 * b) / 6.0),
246 p2((-18.0 + 12.0 * b + 6.0 * c) / 6.0),
247 p3((12.0 - 9.0 * b - 6.0 * c) / 6.0),
248 q0((8.0 * b + 24.0 * c) / 6.0),
249 q1((-12.0 * b - 48.0 * c) / 6.0),
250 q2((6.0 * b + 30.0 * c) / 6.0),
251 q3((-b - 6.0 * c) / 6.0)
254 static double radius() {
return 2.0; }
255 double calc_weight(
double x)
const 257 if(x < 1.0)
return p0 + x * x * (p2 + x * p3);
258 if(x < 2.0)
return q0 + x * (q1 + x * (q2 + x * q3));
267 static double radius() {
return 2.0; }
268 static double calc_weight(
double x)
272 return ((x - 9.0/5.0 ) * x - 1.0/5.0 ) * x + 1.0;
274 return ((-1.0/3.0 * (x-1) + 4.0/5.0) * (x-1) - 7.0/15.0 ) * (x-1);
282 static double radius() {
return 3.0; }
283 static double calc_weight(
double x)
287 return ((13.0/11.0 * x - 453.0/209.0) * x - 3.0/209.0) * x + 1.0;
291 return ((-6.0/11.0 * (x-1) + 270.0/209.0) * (x-1) - 156.0/ 209.0) * (x-1);
293 return ((1.0/11.0 * (x-2) - 45.0/209.0) * (x-2) + 26.0/209.0) * (x-2);
301 static double radius() {
return 2.0; }
302 static double calc_weight(
double x)
304 return std::exp(-2.0 * x * x) * std::sqrt(2.0 / pi);
312 static double radius() {
return 3.2383; }
313 static double calc_weight(
double x)
315 return (x == 0.0) ? pi / 4.0 : besj(pi * x, 1) / (2.0 * x);
325 double radius()
const {
return m_radius; }
326 double calc_weight(
double x)
const 328 if(x == 0.0)
return 1.0;
330 return std::sin(x) / x;
342 double radius()
const {
return m_radius; }
343 double calc_weight(
double x)
const 345 if(x == 0.0)
return 1.0;
346 if(x > m_radius)
return 0.0;
348 double xr = x / m_radius;
349 return (std::sin(x) / x) * (std::sin(xr) / xr);
361 double radius()
const {
return m_radius; }
362 double calc_weight(
double x)
const 364 if(x == 0.0)
return 1.0;
365 if(x > m_radius)
return 0.0;
367 double xr = x / m_radius;
368 return (std::sin(x) / x) * (0.42 + 0.5*std::cos(xr) + 0.08*std::cos(2*xr));