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// Image transformations with filtering. Span generator base class 17// 18//---------------------------------------------------------------------------- 19#ifndef AGG_SPAN_IMAGE_FILTER_INCLUDED 20#define AGG_SPAN_IMAGE_FILTER_INCLUDED 21 22#include "agg_basics.h" 23#include "agg_image_filters.h" 24#include "agg_span_interpolator_linear.h" 25 26namespace agg 27{ 28 29 //-------------------------------------------------------span_image_filter 30 template<class Source, class Interpolator> class span_image_filter 31 { 32 public: 33 typedef Source source_type; 34 typedef Interpolator interpolator_type; 35 36 //-------------------------------------------------------------------- 37 span_image_filter() {} 38 span_image_filter(source_type& src, 39 interpolator_type& interpolator, 40 const image_filter_lut* filter) : 41 m_src(&src), 42 m_interpolator(&interpolator), 43 m_filter(filter), 44 m_dx_dbl(0.5), 45 m_dy_dbl(0.5), 46 m_dx_int(image_subpixel_scale / 2), 47 m_dy_int(image_subpixel_scale / 2) 48 {} 49 void attach(source_type& v) { m_src = &v; } 50 51 //-------------------------------------------------------------------- 52 source_type& source() { return *m_src; } 53 const source_type& source() const { return *m_src; } 54 const image_filter_lut& filter() const { return *m_filter; } 55 int filter_dx_int() const { return m_dx_int; } 56 int filter_dy_int() const { return m_dy_int; } 57 double filter_dx_dbl() const { return m_dx_dbl; } 58 double filter_dy_dbl() const { return m_dy_dbl; } 59 60 //-------------------------------------------------------------------- 61 void interpolator(interpolator_type& v) { m_interpolator = &v; } 62 void filter(const image_filter_lut& v) { m_filter = &v; } 63 void filter_offset(double dx, double dy) 64 { 65 m_dx_dbl = dx; 66 m_dy_dbl = dy; 67 m_dx_int = iround(dx * image_subpixel_scale); 68 m_dy_int = iround(dy * image_subpixel_scale); 69 } 70 void filter_offset(double d) { filter_offset(d, d); } 71 72 //-------------------------------------------------------------------- 73 interpolator_type& interpolator() { return *m_interpolator; } 74 75 //-------------------------------------------------------------------- 76 void prepare() {} 77 78 //-------------------------------------------------------------------- 79 private: 80 source_type* m_src; 81 interpolator_type* m_interpolator; 82 const image_filter_lut* m_filter; 83 double m_dx_dbl; 84 double m_dy_dbl; 85 unsigned m_dx_int; 86 unsigned m_dy_int; 87 }; 88 89 90 91 92 //==============================================span_image_resample_affine 93 template<class Source> 94 class span_image_resample_affine : 95 public span_image_filter<Source, span_interpolator_linear<trans_affine> > 96 { 97 public: 98 typedef Source source_type; 99 typedef span_interpolator_linear<trans_affine> interpolator_type; 100 typedef span_image_filter<source_type, interpolator_type> base_type; 101 102 //-------------------------------------------------------------------- 103 span_image_resample_affine() : 104 m_scale_limit(200.0), 105 m_blur_x(1.0), 106 m_blur_y(1.0) 107 {} 108 109 //-------------------------------------------------------------------- 110 span_image_resample_affine(source_type& src, 111 interpolator_type& inter, 112 const image_filter_lut& filter) : 113 base_type(src, inter, &filter), 114 m_scale_limit(200.0), 115 m_blur_x(1.0), 116 m_blur_y(1.0) 117 {} 118 119 120 //-------------------------------------------------------------------- 121 int scale_limit() const { return uround(m_scale_limit); } 122 void scale_limit(int v) { m_scale_limit = v; } 123 124 //-------------------------------------------------------------------- 125 double blur_x() const { return m_blur_x; } 126 double blur_y() const { return m_blur_y; } 127 void blur_x(double v) { m_blur_x = v; } 128 void blur_y(double v) { m_blur_y = v; } 129 void blur(double v) { m_blur_x = m_blur_y = v; } 130 131 //-------------------------------------------------------------------- 132 void prepare() 133 { 134 double scale_x; 135 double scale_y; 136 137 base_type::interpolator().transformer().scaling_abs(&scale_x, &scale_y); 138 139 if(scale_x * scale_y > m_scale_limit) 140 { 141 scale_x = scale_x * m_scale_limit / (scale_x * scale_y); 142 scale_y = scale_y * m_scale_limit / (scale_x * scale_y); 143 } 144 145 if(scale_x < 1) scale_x = 1; 146 if(scale_y < 1) scale_y = 1; 147 148 if(scale_x > m_scale_limit) scale_x = m_scale_limit; 149 if(scale_y > m_scale_limit) scale_y = m_scale_limit; 150 151 scale_x *= m_blur_x; 152 scale_y *= m_blur_y; 153 154 if(scale_x < 1) scale_x = 1; 155 if(scale_y < 1) scale_y = 1; 156 157 m_rx = uround( scale_x * double(image_subpixel_scale)); 158 m_rx_inv = uround(1.0/scale_x * double(image_subpixel_scale)); 159 160 m_ry = uround( scale_y * double(image_subpixel_scale)); 161 m_ry_inv = uround(1.0/scale_y * double(image_subpixel_scale)); 162 } 163 164 protected: 165 int m_rx; 166 int m_ry; 167 int m_rx_inv; 168 int m_ry_inv; 169 170 private: 171 double m_scale_limit; 172 double m_blur_x; 173 double m_blur_y; 174 }; 175 176 177 178 //=====================================================span_image_resample 179 template<class Source, class Interpolator> 180 class span_image_resample : 181 public span_image_filter<Source, Interpolator> 182 { 183 public: 184 typedef Source source_type; 185 typedef Interpolator interpolator_type; 186 typedef span_image_filter<source_type, interpolator_type> base_type; 187 188 //-------------------------------------------------------------------- 189 span_image_resample() : 190 m_scale_limit(20), 191 m_blur_x(image_subpixel_scale), 192 m_blur_y(image_subpixel_scale) 193 {} 194 195 //-------------------------------------------------------------------- 196 span_image_resample(source_type& src, 197 interpolator_type& inter, 198 const image_filter_lut& filter) : 199 base_type(src, inter, &filter), 200 m_scale_limit(20), 201 m_blur_x(image_subpixel_scale), 202 m_blur_y(image_subpixel_scale) 203 {} 204 205 //-------------------------------------------------------------------- 206 int scale_limit() const { return m_scale_limit; } 207 void scale_limit(int v) { m_scale_limit = v; } 208 209 //-------------------------------------------------------------------- 210 double blur_x() const { return double(m_blur_x) / double(image_subpixel_scale); } 211 double blur_y() const { return double(m_blur_y) / double(image_subpixel_scale); } 212 void blur_x(double v) { m_blur_x = uround(v * double(image_subpixel_scale)); } 213 void blur_y(double v) { m_blur_y = uround(v * double(image_subpixel_scale)); } 214 void blur(double v) { m_blur_x = 215 m_blur_y = uround(v * double(image_subpixel_scale)); } 216 217 protected: 218 AGG_INLINE void adjust_scale(int* rx, int* ry) 219 { 220 if(*rx < image_subpixel_scale) *rx = image_subpixel_scale; 221 if(*ry < image_subpixel_scale) *ry = image_subpixel_scale; 222 if(*rx > image_subpixel_scale * m_scale_limit) 223 { 224 *rx = image_subpixel_scale * m_scale_limit; 225 } 226 if(*ry > image_subpixel_scale * m_scale_limit) 227 { 228 *ry = image_subpixel_scale * m_scale_limit; 229 } 230 *rx = (*rx * m_blur_x) >> image_subpixel_shift; 231 *ry = (*ry * m_blur_y) >> image_subpixel_shift; 232 if(*rx < image_subpixel_scale) *rx = image_subpixel_scale; 233 if(*ry < image_subpixel_scale) *ry = image_subpixel_scale; 234 } 235 236 int m_scale_limit; 237 int m_blur_x; 238 int m_blur_y; 239 }; 240 241 242 243 244} 245 246#endif 247