update dev300-m58
[ooovba.git] / agg / inc / agg_image_filters.h
blobe498d0567c843a202fde26f217940f2a9cf43ae0
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 // Image transformation filters,
17 // Filtering classes (image_filter_lut, image_filter),
18 // Basic filter shape classes
19 //----------------------------------------------------------------------------
20 #ifndef AGG_IMAGE_FILTERS_INCLUDED
21 #define AGG_IMAGE_FILTERS_INCLUDED
23 #include <math.h>
24 #include "agg_basics.h"
26 namespace agg
29 // See Implementation agg_image_filters.cpp
31 enum
33 image_filter_shift = 14, //----image_filter_shift
34 image_filter_size = 1 << image_filter_shift, //----image_filter_size
35 image_filter_mask = image_filter_size - 1, //----image_filter_mask
37 image_subpixel_shift = 8, //----image_subpixel_shift
38 image_subpixel_size = 1 << image_subpixel_shift, //----image_subpixel_size
39 image_subpixel_mask = image_subpixel_size - 1 //----image_subpixel_mask
43 //-----------------------------------------------------image_filter_lut
44 class image_filter_lut
46 public:
47 ~image_filter_lut();
48 image_filter_lut();
50 template<class FilterF> void calculate(const FilterF& filter,
51 bool normalization=true)
53 double r = filter.radius();
54 realloc(r);
55 unsigned i;
56 unsigned pivot = diameter() << (image_subpixel_shift - 1);
57 for(i = 0; i < pivot; i++)
59 double x = double(i) / double(image_subpixel_size);
60 double y = filter.calc_weight(x);
61 m_weight_array[pivot + i] =
62 m_weight_array[pivot - i] = int16(y * image_filter_size + 0.5);
64 unsigned end = (diameter() << image_subpixel_shift) - 1;
65 m_weight_array[0] = m_weight_array[end];
66 if(normalization)
68 normalize();
72 template<class FilterF> image_filter_lut(const FilterF& filter,
73 bool normalization=true) :
74 m_weight_array(0),
75 m_max_size(0)
77 calculate(filter, normalization);
80 double radius() const { return m_radius; }
81 unsigned diameter() const { return m_diameter; }
82 int start() const { return m_start; }
83 const int16* weight_array() const { return m_weight_array; }
84 void normalize();
86 private:
87 void realloc(double radius);
88 image_filter_lut(const image_filter_lut&);
89 const image_filter_lut& operator = (const image_filter_lut&);
91 double m_radius;
92 unsigned m_diameter;
93 int m_start;
94 int16* m_weight_array;
95 unsigned m_max_size;
100 //--------------------------------------------------------image_filter
101 template<class FilterF> class image_filter : public image_filter_lut
103 public:
104 image_filter()
106 calculate(m_filter_function);
108 private:
109 FilterF m_filter_function;
113 //-----------------------------------------------image_filter_bilinear
114 struct image_filter_bilinear
116 static double radius() { return 1.0; }
117 static double calc_weight(double x)
119 return 1.0 - x;
124 //-----------------------------------------------image_filter_hanning
125 struct image_filter_hanning
127 static double radius() { return 1.0; }
128 static double calc_weight(double x)
130 return 0.5 + 0.5 * cos(pi * x);
135 //-----------------------------------------------image_filter_hamming
136 struct image_filter_hamming
138 static double radius() { return 1.0; }
139 static double calc_weight(double x)
141 return 0.54 + 0.46 * cos(pi * x);
145 //-----------------------------------------------image_filter_hermite
146 struct image_filter_hermite
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;
155 //------------------------------------------------image_filter_quadric
156 struct image_filter_quadric
158 static double radius() { return 1.5; }
159 static double calc_weight(double x)
161 double t;
162 if(x < 0.5) return 0.75 - x * x;
163 if(x < 1.5) {t = x - 1.5; return 0.5 * t * t;}
164 return 0.0;
168 //------------------------------------------------image_filter_bicubic
169 class image_filter_bicubic
171 static double pow3(double x)
173 return (x <= 0.0) ? 0.0 : x * x * x;
176 public:
177 static double radius() { return 2.0; }
178 static double calc_weight(double x)
180 return
181 (1.0/6.0) *
182 (pow3(x + 2) - 4 * pow3(x + 1) + 6 * pow3(x) - 4 * pow3(x - 1));
186 //-------------------------------------------------image_filter_kaiser
187 class image_filter_kaiser
189 double a;
190 double i0a;
191 double epsilon;
193 public:
194 image_filter_kaiser(double b = 6.33) :
195 a(b), epsilon(1e-12)
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 * sqrt(1. - x * x)) * i0a;
206 private:
207 double bessel_i0(double x) const
209 int i;
210 double sum, y, t;
212 sum = 1.;
213 y = x * x / 4.;
214 t = y;
216 for(i = 2; t > epsilon; i++)
218 sum += t;
219 t *= (double)y / (i * i);
221 return sum;
225 //----------------------------------------------image_filter_catrom
226 struct image_filter_catrom
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)));
233 return 0.;
237 //---------------------------------------------image_filter_mitchell
238 class image_filter_mitchell
240 double p0, p2, p3;
241 double q0, q1, q2, q3;
243 public:
244 image_filter_mitchell(double b = 1.0/3.0, double c = 1.0/3.0) :
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));
259 return 0.0;
264 //----------------------------------------------image_filter_spline16
265 struct image_filter_spline16
267 static double radius() { return 2.0; }
268 static double calc_weight(double x)
270 if(x < 1.0)
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);
279 //---------------------------------------------image_filter_spline36
280 struct image_filter_spline36
282 static double radius() { return 3.0; }
283 static double calc_weight(double x)
285 if(x < 1.0)
287 return ((13.0/11.0 * x - 453.0/209.0) * x - 3.0/209.0) * x + 1.0;
289 if(x < 2.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);
298 //----------------------------------------------image_filter_gaussian
299 struct image_filter_gaussian
301 static double radius() { return 2.0; }
302 static double calc_weight(double x)
304 return exp(-2.0 * x * x) * sqrt(2.0 / pi);
309 //------------------------------------------------image_filter_bessel
310 struct image_filter_bessel
312 static double radius() { return 3.2383; }
313 static double calc_weight(double x)
315 return (x == 0.0) ? pi / 4.0 : j1(pi * x) / (2.0 * x);
320 //-------------------------------------------------image_filter_sinc
321 class image_filter_sinc
323 public:
324 image_filter_sinc(double r) : m_radius(r < 2.0 ? 2.0 : r) {}
325 double radius() const { return m_radius; }
326 double calc_weight(double x) const
328 if(x == 0.0) return 1.0;
329 x *= pi;
330 return sin(x) / x;
332 private:
333 double m_radius;
337 //-----------------------------------------------image_filter_lanczos
338 class image_filter_lanczos
340 public:
341 image_filter_lanczos(double r) : m_radius(r < 2.0 ? 2.0 : r) {}
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;
347 x *= pi;
348 double xr = x / m_radius;
349 return (sin(x) / x) * (sin(xr) / xr);
351 private:
352 double m_radius;
356 //----------------------------------------------image_filter_blackman
357 class image_filter_blackman
359 public:
360 image_filter_blackman(double r) : m_radius(r < 2.0 ? 2.0 : r) {}
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;
366 x *= pi;
367 double xr = x / m_radius;
368 return (sin(x) / x) * (0.42 + 0.5*cos(xr) + 0.08*cos(2*xr));
370 private:
371 double m_radius;
374 //------------------------------------------------image_filter_sinc36
375 class image_filter_sinc36 : public image_filter_sinc
376 { public: image_filter_sinc36() : image_filter_sinc(3.0){} };
378 //------------------------------------------------image_filter_sinc64
379 class image_filter_sinc64 : public image_filter_sinc
380 { public: image_filter_sinc64() : image_filter_sinc(4.0){} };
382 //-----------------------------------------------image_filter_sinc100
383 class image_filter_sinc100 : public image_filter_sinc
384 { public: image_filter_sinc100() : image_filter_sinc(5.0){} };
386 //-----------------------------------------------image_filter_sinc144
387 class image_filter_sinc144 : public image_filter_sinc
388 { public: image_filter_sinc144() : image_filter_sinc(6.0){} };
390 //-----------------------------------------------image_filter_sinc196
391 class image_filter_sinc196 : public image_filter_sinc
392 { public: image_filter_sinc196() : image_filter_sinc(7.0){} };
394 //-----------------------------------------------image_filter_sinc256
395 class image_filter_sinc256 : public image_filter_sinc
396 { public: image_filter_sinc256() : image_filter_sinc(8.0){} };
398 //---------------------------------------------image_filter_lanczos36
399 class image_filter_lanczos36 : public image_filter_lanczos
400 { public: image_filter_lanczos36() : image_filter_lanczos(3.0){} };
402 //---------------------------------------------image_filter_lanczos64
403 class image_filter_lanczos64 : public image_filter_lanczos
404 { public: image_filter_lanczos64() : image_filter_lanczos(4.0){} };
406 //--------------------------------------------image_filter_lanczos100
407 class image_filter_lanczos100 : public image_filter_lanczos
408 { public: image_filter_lanczos100() : image_filter_lanczos(5.0){} };
410 //--------------------------------------------image_filter_lanczos144
411 class image_filter_lanczos144 : public image_filter_lanczos
412 { public: image_filter_lanczos144() : image_filter_lanczos(6.0){} };
414 //--------------------------------------------image_filter_lanczos196
415 class image_filter_lanczos196 : public image_filter_lanczos
416 { public: image_filter_lanczos196() : image_filter_lanczos(7.0){} };
418 //--------------------------------------------image_filter_lanczos256
419 class image_filter_lanczos256 : public image_filter_lanczos
420 { public: image_filter_lanczos256() : image_filter_lanczos(8.0){} };
422 //--------------------------------------------image_filter_blackman36
423 class image_filter_blackman36 : public image_filter_blackman
424 { public: image_filter_blackman36() : image_filter_blackman(3.0){} };
426 //--------------------------------------------image_filter_blackman64
427 class image_filter_blackman64 : public image_filter_blackman
428 { public: image_filter_blackman64() : image_filter_blackman(4.0){} };
430 //-------------------------------------------image_filter_blackman100
431 class image_filter_blackman100 : public image_filter_blackman
432 { public: image_filter_blackman100() : image_filter_blackman(5.0){} };
434 //-------------------------------------------image_filter_blackman144
435 class image_filter_blackman144 : public image_filter_blackman
436 { public: image_filter_blackman144() : image_filter_blackman(6.0){} };
438 //-------------------------------------------image_filter_blackman196
439 class image_filter_blackman196 : public image_filter_blackman
440 { public: image_filter_blackman196() : image_filter_blackman(7.0){} };
442 //-------------------------------------------image_filter_blackman256
443 class image_filter_blackman256 : public image_filter_blackman
444 { public: image_filter_blackman256() : image_filter_blackman(8.0){} };
449 #endif