1//---------------------------------------------------------------------------- 2// Anti-Grain Geometry - Version 2.4 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//---------------------------------------------------------------------------- 15// 16// Filtering class image_filter_lut implemantation 17// 18//---------------------------------------------------------------------------- 19 20 21#include "agg_image_filters.h" 22 23 24namespace agg 25{ 26 //-------------------------------------------------------------------- 27 void image_filter_lut::realloc_lut(double radius) 28 { 29 m_radius = radius; 30 m_diameter = uceil(radius) * 2; 31 m_start = -int(m_diameter / 2 - 1); 32 unsigned size = m_diameter << image_subpixel_shift; 33 if(size > m_weight_array.size()) 34 { 35 m_weight_array.resize(size); 36 } 37 } 38 39 40 41 //-------------------------------------------------------------------- 42 // This function normalizes integer values and corrects the rounding 43 // errors. It doesn't do anything with the source floating point values 44 // (m_weight_array_dbl), it corrects only integers according to the rule 45 // of 1.0 which means that any sum of pixel weights must be equal to 1.0. 46 // So, the filter function must produce a graph of the proper shape. 47 //-------------------------------------------------------------------- 48 void image_filter_lut::normalize() 49 { 50 unsigned i; 51 int flip = 1; 52 53 for(i = 0; i < image_subpixel_scale; i++) 54 { 55 for(;;) 56 { 57 int sum = 0; 58 unsigned j; 59 for(j = 0; j < m_diameter; j++) 60 { 61 sum += m_weight_array[j * image_subpixel_scale + i]; 62 } 63 64 if(sum == image_filter_scale) break; 65 66 double k = double(image_filter_scale) / double(sum); 67 sum = 0; 68 for(j = 0; j < m_diameter; j++) 69 { 70 sum += m_weight_array[j * image_subpixel_scale + i] = 71 iround(m_weight_array[j * image_subpixel_scale + i] * k); 72 } 73 74 sum -= image_filter_scale; 75 int inc = (sum > 0) ? -1 : 1; 76 77 for(j = 0; j < m_diameter && sum; j++) 78 { 79 flip ^= 1; 80 unsigned idx = flip ? m_diameter/2 + j/2 : m_diameter/2 - j/2; 81 int v = m_weight_array[idx * image_subpixel_scale + i]; 82 if(v < image_filter_scale) 83 { 84 m_weight_array[idx * image_subpixel_scale + i] += inc; 85 sum += inc; 86 } 87 } 88 } 89 } 90 91 unsigned pivot = m_diameter << (image_subpixel_shift - 1); 92 93 for(i = 0; i < pivot; i++) 94 { 95 m_weight_array[pivot + i] = m_weight_array[pivot - i]; 96 } 97 unsigned end = (diameter() << image_subpixel_shift) - 1; 98 m_weight_array[0] = m_weight_array[end]; 99 } 100 101 102} 103 104