merge the formfield patch from ooo-build
[ooovba.git] / agg / source / agg_image_filters.cpp
blobfa651f18ae12f0a780821bbc5b913bec510b1902
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 // Filtering class image_filter_lut implemantation
18 //----------------------------------------------------------------------------
21 #include "agg_image_filters.h"
24 namespace agg
27 //--------------------------------------------------------------------
28 image_filter_lut::~image_filter_lut()
30 delete [] m_weight_array;
34 //--------------------------------------------------------------------
35 image_filter_lut::image_filter_lut() :
36 m_weight_array(0),
37 m_max_size(0)
40 //--------------------------------------------------------------------
41 void image_filter_lut::realloc(double _radius)
43 m_radius = _radius;
44 m_diameter = unsigned(ceil(_radius)) * 2;
45 m_start = -int(m_diameter / 2 - 1);
46 unsigned size = m_diameter << image_subpixel_shift;
47 if(size > m_max_size)
49 delete [] m_weight_array;
50 m_weight_array = new int16 [size];
51 m_max_size = size;
57 //--------------------------------------------------------------------
58 // This function normalizes integer values and corrects the rounding
59 // errors. It doesn't do anything with the source floating point values
60 // (m_weight_array_dbl), it corrects only integers according to the rule
61 // of 1.0 which means that any sum of pixel weights must be equal to 1.0.
62 // So, the filter function must produce a graph of the proper shape.
63 //--------------------------------------------------------------------
64 void image_filter_lut::normalize()
66 unsigned i;
67 int flip = 1;
69 for(i = 0; i < image_subpixel_size; i++)
71 for(;;)
73 int sum = 0;
74 unsigned j;
75 for(j = 0; j < m_diameter; j++)
77 sum += m_weight_array[j * image_subpixel_size + i];
80 if(sum == image_filter_size) break;
82 double k = double(image_filter_size) / double(sum);
83 sum = 0;
84 for(j = 0; j < m_diameter; j++)
86 sum += m_weight_array[j * image_subpixel_size + i] =
87 int16(m_weight_array[j * image_subpixel_size + i] * k);
90 sum -= image_filter_size;
91 int16 inc = (sum > 0) ? -1 : 1;
93 for(j = 0; j < m_diameter && sum; j++)
95 flip ^= 1;
96 unsigned idx = flip ? m_diameter/2 + j/2 : m_diameter/2 - j/2;
97 int v = m_weight_array[idx * image_subpixel_size + i];
98 if(v < image_filter_size)
100 m_weight_array[idx * image_subpixel_size + i] =
101 m_weight_array[idx * image_subpixel_size + i] + inc;
102 sum += inc;
108 unsigned pivot = m_diameter << (image_subpixel_shift - 1);
110 for(i = 0; i < pivot; i++)
112 m_weight_array[pivot + i] = m_weight_array[pivot - i];
114 unsigned end = (diameter() << image_subpixel_shift) - 1;
115 m_weight_array[0] = m_weight_array[end];