incubator-ooo-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From p..@apache.org
Subject svn commit: r1184758 [14/17] - in /incubator/ooo/trunk/main: ./ agg/inc/ agg/source/ solenv/config/
Date Sun, 16 Oct 2011 04:13:21 GMT
Modified: incubator/ooo/trunk/main/agg/inc/agg_span_image_filter_rgb.h
URL: http://svn.apache.org/viewvc/incubator/ooo/trunk/main/agg/inc/agg_span_image_filter_rgb.h?rev=1184758&r1=1184757&r2=1184758&view=diff
==============================================================================
--- incubator/ooo/trunk/main/agg/inc/agg_span_image_filter_rgb.h (original)
+++ incubator/ooo/trunk/main/agg/inc/agg_span_image_filter_rgb.h Sun Oct 16 04:13:16 2011
@@ -1,5 +1,5 @@
 //----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
 // Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
 //
 // Permission to copy, use, modify, sell and distribute this software 
@@ -20,7 +20,6 @@
 // PostScript and PDF technology for software developers.
 // 
 //----------------------------------------------------------------------------
-
 #ifndef AGG_SPAN_IMAGE_FILTER_RGB_INCLUDED
 #define AGG_SPAN_IMAGE_FILTER_RGB_INCLUDED
 
@@ -32,146 +31,198 @@
 namespace agg
 {
 
-
-    //==============================================span_image_filter_rgb_nn
-    template<class ColorT,
-             class Order, 
-             class Interpolator,
-             class Allocator = span_allocator<ColorT> > 
+    //===============================================span_image_filter_rgb_nn
+    template<class Source, class Interpolator> 
     class span_image_filter_rgb_nn : 
-    public span_image_filter<ColorT, Interpolator, Allocator>
+    public span_image_filter<Source, Interpolator>
     {
     public:
-        typedef ColorT color_type;
-        typedef Order order_type;
+        typedef Source source_type;
+        typedef typename source_type::color_type color_type;
+        typedef typename source_type::order_type order_type;
         typedef Interpolator interpolator_type;
-        typedef Allocator alloc_type;
-        typedef span_image_filter<color_type, interpolator_type, alloc_type> base_type;
+        typedef span_image_filter<source_type, interpolator_type> base_type;
         typedef typename color_type::value_type value_type;
         typedef typename color_type::calc_type calc_type;
-        enum
+        enum base_scale_e
         {
             base_shift = color_type::base_shift,
             base_mask  = color_type::base_mask
         };
 
         //--------------------------------------------------------------------
-        span_image_filter_rgb_nn(alloc_type& alloc) : base_type(alloc) {}
-
-        //--------------------------------------------------------------------
-        span_image_filter_rgb_nn(alloc_type& alloc,
-                                 const rendering_buffer& src, 
-                                 const color_type& back_color,
+        span_image_filter_rgb_nn() {}
+        span_image_filter_rgb_nn(source_type& src, 
                                  interpolator_type& inter) :
-            base_type(alloc, src, back_color, inter, 0) 
+            base_type(src, inter, 0) 
         {}
 
         //--------------------------------------------------------------------
-        color_type* generate(int x, int y, unsigned len)
+        void generate(color_type* span, int x, int y, unsigned len)
         {
             base_type::interpolator().begin(x + base_type::filter_dx_dbl(), 
                                             y + base_type::filter_dy_dbl(), len);
+            do
+            {
+                base_type::interpolator().coordinates(&x, &y);
+                const value_type* fg_ptr = (const value_type*)
+                    base_type::source().span(x >> image_subpixel_shift, 
+                                             y >> image_subpixel_shift, 
+                                             1);
+                span->r = fg_ptr[order_type::R];
+                span->g = fg_ptr[order_type::G];
+                span->b = fg_ptr[order_type::B];
+                span->a = base_mask;
+                ++span;
+                ++base_type::interpolator();
 
-            calc_type fg[3];
-            calc_type src_alpha;
+            } while(--len);
+        }
+    };
 
-            const value_type *fg_ptr;
-            color_type* span = base_type::allocator().span();
 
-            int maxx = base_type::source_image().width() - 1;
-            int maxy = base_type::source_image().height() - 1;
 
+    //==========================================span_image_filter_rgb_bilinear
+    template<class Source, class Interpolator> 
+    class span_image_filter_rgb_bilinear : 
+    public span_image_filter<Source, Interpolator>
+    {
+    public:
+        typedef Source source_type;
+        typedef typename source_type::color_type color_type;
+        typedef typename source_type::order_type order_type;
+        typedef Interpolator interpolator_type;
+        typedef span_image_filter<source_type, interpolator_type> base_type;
+        typedef typename color_type::value_type value_type;
+        typedef typename color_type::calc_type calc_type;
+        enum base_scale_e
+        {
+            base_shift = color_type::base_shift,
+            base_mask  = color_type::base_mask
+        };
+
+        //--------------------------------------------------------------------
+        span_image_filter_rgb_bilinear() {}
+        span_image_filter_rgb_bilinear(source_type& src, 
+                                       interpolator_type& inter) :
+            base_type(src, inter, 0) 
+        {}
+
+
+        //--------------------------------------------------------------------
+        void generate(color_type* span, int x, int y, unsigned len)
+        {
+            base_type::interpolator().begin(x + base_type::filter_dx_dbl(), 
+                                            y + base_type::filter_dy_dbl(), len);
+            calc_type fg[3];
+            const value_type *fg_ptr;
             do
             {
-                base_type::interpolator().coordinates(&x, &y);
+                int x_hr;
+                int y_hr;
 
-                x >>= image_subpixel_shift;
-                y >>= image_subpixel_shift;
+                base_type::interpolator().coordinates(&x_hr, &y_hr);
 
-                if(x >= 0    && y >= 0 &&
-                   x <= maxx && y <= maxy) 
-                {
-                    fg_ptr = (const value_type*)base_type::source_image().row(y) + x + x + x;
-                    fg[0] = *fg_ptr++;
-                    fg[1] = *fg_ptr++;
-                    fg[2] = *fg_ptr++;
-                    src_alpha = base_mask;
-                }
-                else
-                {
-                    fg[order_type::R] = base_type::background_color().r;
-                    fg[order_type::G] = base_type::background_color().g;
-                    fg[order_type::B] = base_type::background_color().b;
-                    src_alpha         = base_type::background_color().a;
-                }
+                x_hr -= base_type::filter_dx_int();
+                y_hr -= base_type::filter_dy_int();
+
+                int x_lr = x_hr >> image_subpixel_shift;
+                int y_lr = y_hr >> image_subpixel_shift;
+
+                unsigned weight;
+
+                fg[0] = 
+                fg[1] = 
+                fg[2] = image_subpixel_scale * image_subpixel_scale / 2;
+
+                x_hr &= image_subpixel_mask;
+                y_hr &= image_subpixel_mask;
+
+                fg_ptr = (const value_type*)base_type::source().span(x_lr, y_lr, 2);
+                weight = (image_subpixel_scale - x_hr) * 
+                         (image_subpixel_scale - y_hr);
+                fg[0] += weight * *fg_ptr++;
+                fg[1] += weight * *fg_ptr++;
+                fg[2] += weight * *fg_ptr;
+
+                fg_ptr = (const value_type*)base_type::source().next_x();
+                weight = x_hr * (image_subpixel_scale - y_hr);
+                fg[0] += weight * *fg_ptr++;
+                fg[1] += weight * *fg_ptr++;
+                fg[2] += weight * *fg_ptr;
+
+                fg_ptr = (const value_type*)base_type::source().next_y();
+                weight = (image_subpixel_scale - x_hr) * y_hr;
+                fg[0] += weight * *fg_ptr++;
+                fg[1] += weight * *fg_ptr++;
+                fg[2] += weight * *fg_ptr;
+
+                fg_ptr = (const value_type*)base_type::source().next_x();
+                weight = x_hr * y_hr;
+                fg[0] += weight * *fg_ptr++;
+                fg[1] += weight * *fg_ptr++;
+                fg[2] += weight * *fg_ptr;
+
+                span->r = value_type(fg[order_type::R] >> (image_subpixel_shift * 2));
+                span->g = value_type(fg[order_type::G] >> (image_subpixel_shift * 2));
+                span->b = value_type(fg[order_type::B] >> (image_subpixel_shift * 2));
+                span->a = base_mask;
 
-                span->r = (value_type)fg[order_type::R];
-                span->g = (value_type)fg[order_type::G];
-                span->b = (value_type)fg[order_type::B];
-                span->a = (value_type)src_alpha;
                 ++span;
                 ++base_type::interpolator();
 
             } while(--len);
-
-            return base_type::allocator().span();
         }
     };
 
 
 
-
-    //=========================================span_image_filter_rgb_bilinear
-    template<class ColorT,
-             class Order, 
-             class Interpolator, 
-             class Allocator = span_allocator<ColorT> > 
-    class span_image_filter_rgb_bilinear : 
-    public span_image_filter<ColorT, Interpolator, Allocator>
+    //=====================================span_image_filter_rgb_bilinear_clip
+    template<class Source, class Interpolator> 
+    class span_image_filter_rgb_bilinear_clip : 
+    public span_image_filter<Source, Interpolator>
     {
     public:
-        typedef ColorT color_type;
-        typedef Order order_type;
+        typedef Source source_type;
+        typedef typename source_type::color_type color_type;
+        typedef typename source_type::order_type order_type;
         typedef Interpolator interpolator_type;
-        typedef Allocator alloc_type;
-        typedef span_image_filter<color_type, interpolator_type, alloc_type> base_type;
+        typedef span_image_filter<source_type, interpolator_type> base_type;
         typedef typename color_type::value_type value_type;
         typedef typename color_type::calc_type calc_type;
-        enum
+        enum base_scale_e
         {
             base_shift = color_type::base_shift,
             base_mask  = color_type::base_mask
         };
 
         //--------------------------------------------------------------------
-        span_image_filter_rgb_bilinear(alloc_type& alloc) : base_type(alloc) {}
-
-        //--------------------------------------------------------------------
-        span_image_filter_rgb_bilinear(alloc_type& alloc,
-                                       const rendering_buffer& src, 
-                                       const color_type& back_color,
-                                       interpolator_type& inter) :
-            base_type(alloc, src, back_color, inter, 0) 
+        span_image_filter_rgb_bilinear_clip() {}
+        span_image_filter_rgb_bilinear_clip(source_type& src, 
+                                            const color_type& back_color,
+                                            interpolator_type& inter) :
+            base_type(src, inter, 0),
+            m_back_color(back_color)
         {}
+        const color_type& background_color() const { return m_back_color; }
+        void background_color(const color_type& v)   { m_back_color = v; }
 
         //--------------------------------------------------------------------
-        color_type* generate(int x, int y, unsigned len)
+        void generate(color_type* span, int x, int y, unsigned len)
         {
             base_type::interpolator().begin(x + base_type::filter_dx_dbl(), 
                                             y + base_type::filter_dy_dbl(), len);
             calc_type fg[3];
             calc_type src_alpha;
-            value_type back_r = base_type::background_color().r;
-            value_type back_g = base_type::background_color().g;
-            value_type back_b = base_type::background_color().b;
-            value_type back_a = base_type::background_color().a;
+            value_type back_r = m_back_color.r;
+            value_type back_g = m_back_color.g;
+            value_type back_b = m_back_color.b;
+            value_type back_a = m_back_color.a;
 
             const value_type *fg_ptr;
 
-            color_type* span = base_type::allocator().span();
-
-            int maxx = base_type::source_image().width() - 1;
-            int maxy = base_type::source_image().height() - 1;
+            int maxx = base_type::source().width() - 1;
+            int maxy = base_type::source().height() - 1;
 
             do
             {
@@ -192,26 +243,30 @@ namespace agg
                 {
                     fg[0] = 
                     fg[1] = 
-                    fg[2] = image_subpixel_size * image_subpixel_size / 2;
+                    fg[2] = image_subpixel_scale * image_subpixel_scale / 2;
 
                     x_hr &= image_subpixel_mask;
                     y_hr &= image_subpixel_mask;
-                    fg_ptr = (const value_type*)base_type::source_image().row(y_lr) + x_lr + x_lr + x_lr;
 
-                    weight = (image_subpixel_size - x_hr) * 
-                             (image_subpixel_size - y_hr);
+                    fg_ptr = (const value_type*)
+                        base_type::source().row_ptr(y_lr) + x_lr + x_lr + x_lr;
+
+                    weight = (image_subpixel_scale - x_hr) * 
+                             (image_subpixel_scale - y_hr);
                     fg[0] += weight * *fg_ptr++;
                     fg[1] += weight * *fg_ptr++;
                     fg[2] += weight * *fg_ptr++;
 
-                    weight = x_hr * (image_subpixel_size - y_hr);
+                    weight = x_hr * (image_subpixel_scale - y_hr);
                     fg[0] += weight * *fg_ptr++;
                     fg[1] += weight * *fg_ptr++;
                     fg[2] += weight * *fg_ptr++;
 
-                    fg_ptr = (const value_type*)base_type::source_image().next_row(fg_ptr - 6);
+                    ++y_lr;
+                    fg_ptr = (const value_type*)
+                        base_type::source().row_ptr(y_lr) + x_lr + x_lr + x_lr;
 
-                    weight = (image_subpixel_size - x_hr) * y_hr;
+                    weight = (image_subpixel_scale - x_hr) * y_hr;
                     fg[0] += weight * *fg_ptr++;
                     fg[1] += weight * *fg_ptr++;
                     fg[2] += weight * *fg_ptr++;
@@ -241,17 +296,19 @@ namespace agg
                         fg[0] = 
                         fg[1] = 
                         fg[2] = 
-                        src_alpha = image_subpixel_size * image_subpixel_size / 2;
+                        src_alpha = image_subpixel_scale * image_subpixel_scale / 2;
 
                         x_hr &= image_subpixel_mask;
                         y_hr &= image_subpixel_mask;
 
-                        weight = (image_subpixel_size - x_hr) * 
-                                 (image_subpixel_size - y_hr);
+                        weight = (image_subpixel_scale - x_hr) * 
+                                 (image_subpixel_scale - y_hr);
                         if(x_lr >= 0    && y_lr >= 0 &&
                            x_lr <= maxx && y_lr <= maxy)
                         {
-                            fg_ptr = (const value_type*)base_type::source_image().row(y_lr) + x_lr + x_lr + x_lr;
+                            fg_ptr = (const value_type*)
+                                base_type::source().row_ptr(y_lr) + x_lr + x_lr + x_lr;
+
                             fg[0] += weight * *fg_ptr++;
                             fg[1] += weight * *fg_ptr++;
                             fg[2] += weight * *fg_ptr++;
@@ -267,11 +324,13 @@ namespace agg
 
                         x_lr++;
 
-                        weight = x_hr * (image_subpixel_size - y_hr);
+                        weight = x_hr * (image_subpixel_scale - y_hr);
                         if(x_lr >= 0    && y_lr >= 0 &&
                            x_lr <= maxx && y_lr <= maxy)
                         {
-                            fg_ptr = (const value_type*)base_type::source_image().row(y_lr) + x_lr + x_lr + x_lr;
+                            fg_ptr = (const value_type*)
+                                base_type::source().row_ptr(y_lr) + x_lr + x_lr + x_lr;
+
                             fg[0]     += weight * *fg_ptr++;
                             fg[1]     += weight * *fg_ptr++;
                             fg[2]     += weight * *fg_ptr++;
@@ -288,11 +347,13 @@ namespace agg
                         x_lr--;
                         y_lr++;
 
-                        weight = (image_subpixel_size - x_hr) * y_hr;
+                        weight = (image_subpixel_scale - x_hr) * y_hr;
                         if(x_lr >= 0    && y_lr >= 0 &&
                            x_lr <= maxx && y_lr <= maxy)
                         {
-                            fg_ptr = (const value_type*)base_type::source_image().row(y_lr) + x_lr + x_lr + x_lr;
+                            fg_ptr = (const value_type*)
+                                base_type::source().row_ptr(y_lr) + x_lr + x_lr + x_lr;
+
                             fg[0] += weight * *fg_ptr++;
                             fg[1] += weight * *fg_ptr++;
                             fg[2] += weight * *fg_ptr++;
@@ -312,7 +373,9 @@ namespace agg
                         if(x_lr >= 0    && y_lr >= 0 &&
                            x_lr <= maxx && y_lr <= maxy)
                         {
-                            fg_ptr = (const value_type*)base_type::source_image().row(y_lr) + x_lr + x_lr + x_lr;
+                            fg_ptr = (const value_type*)
+                                base_type::source().row_ptr(y_lr) + x_lr + x_lr + x_lr;
+
                             fg[0] += weight * *fg_ptr++;
                             fg[1] += weight * *fg_ptr++;
                             fg[2] += weight * *fg_ptr++;
@@ -341,79 +404,58 @@ namespace agg
                 ++base_type::interpolator();
 
             } while(--len);
-
-            return base_type::allocator().span();
         }
+    private:
+        color_type m_back_color;
     };
 
 
 
-
-
-
-
-
-    //=========================================span_image_filter_rgb_2x2
-    template<class ColorT,
-             class Order, 
-             class Interpolator, 
-             class Allocator = span_allocator<ColorT> > 
+    //===============================================span_image_filter_rgb_2x2
+    template<class Source, class Interpolator> 
     class span_image_filter_rgb_2x2 : 
-    public span_image_filter<ColorT, Interpolator, Allocator>
+    public span_image_filter<Source, Interpolator>
     {
     public:
-        typedef ColorT color_type;
-        typedef Order order_type;
+        typedef Source source_type;
+        typedef typename source_type::color_type color_type;
+        typedef typename source_type::order_type order_type;
         typedef Interpolator interpolator_type;
-        typedef Allocator alloc_type;
-        typedef span_image_filter<color_type, interpolator_type, alloc_type> base_type;
+        typedef span_image_filter<source_type, interpolator_type> base_type;
         typedef typename color_type::value_type value_type;
         typedef typename color_type::calc_type calc_type;
-        enum
+        enum base_scale_e
         {
             base_shift = color_type::base_shift,
             base_mask  = color_type::base_mask
         };
 
         //--------------------------------------------------------------------
-        span_image_filter_rgb_2x2(alloc_type& alloc) : base_type(alloc) {}
-
-        //--------------------------------------------------------------------
-        span_image_filter_rgb_2x2(alloc_type& alloc,
-                                  const rendering_buffer& src, 
-                                  const color_type& back_color,
+        span_image_filter_rgb_2x2() {}
+        span_image_filter_rgb_2x2(source_type& src, 
                                   interpolator_type& inter,
                                   const image_filter_lut& filter) :
-            base_type(alloc, src, back_color, inter, &filter) 
+            base_type(src, inter, &filter) 
         {}
 
+
         //--------------------------------------------------------------------
-        color_type* generate(int x, int y, unsigned len)
+        void generate(color_type* span, int x, int y, unsigned len)
         {
             base_type::interpolator().begin(x + base_type::filter_dx_dbl(), 
                                             y + base_type::filter_dy_dbl(), len);
+
             calc_type fg[3];
-            calc_type src_alpha;
-            value_type back_r = base_type::background_color().r;
-            value_type back_g = base_type::background_color().g;
-            value_type back_b = base_type::background_color().b;
-            value_type back_a = base_type::background_color().a;
 
             const value_type *fg_ptr;
-
-            color_type* span = base_type::allocator().span();
             const int16* weight_array = base_type::filter().weight_array() + 
                                         ((base_type::filter().diameter()/2 - 1) << 
                                           image_subpixel_shift);
-
-            int maxx = base_type::source_image().width() - 1;
-            int maxy = base_type::source_image().height() - 1;
-
             do
             {
                 int x_hr;
                 int y_hr;
-                
+
                 base_type::interpolator().coordinates(&x_hr, &y_hr);
 
                 x_hr -= base_type::filter_dx_int();
@@ -421,261 +463,110 @@ namespace agg
 
                 int x_lr = x_hr >> image_subpixel_shift;
                 int y_lr = y_hr >> image_subpixel_shift;
-                unsigned weight;
-
-                if(x_lr >= 0    && y_lr >= 0 &&
-                   x_lr <  maxx && y_lr <  maxy) 
-                {
-                    fg[0] = fg[1] = fg[2] = image_filter_size / 2;
-
-                    x_hr &= image_subpixel_mask;
-                    y_hr &= image_subpixel_mask;
-                    fg_ptr = (const value_type*)base_type::source_image().row(y_lr) + x_lr + x_lr + x_lr;
-
-                    weight = (weight_array[x_hr + image_subpixel_size] * 
-                              weight_array[y_hr + image_subpixel_size] + 
-                              image_filter_size / 2) >> 
-                              image_filter_shift;
-                    fg[0] += weight * *fg_ptr++;
-                    fg[1] += weight * *fg_ptr++;
-                    fg[2] += weight * *fg_ptr++;
-
-                    weight = (weight_array[x_hr] * 
-                              weight_array[y_hr + image_subpixel_size] + 
-                              image_filter_size / 2) >> 
-                              image_filter_shift;
-                    fg[0] += weight * *fg_ptr++;
-                    fg[1] += weight * *fg_ptr++;
-                    fg[2] += weight * *fg_ptr++;
-
-                    fg_ptr = (const value_type*)base_type::source_image().next_row(fg_ptr - 6);
-
-                    weight = (weight_array[x_hr + image_subpixel_size] * 
-                              weight_array[y_hr] + 
-                              image_filter_size / 2) >> 
-                              image_filter_shift;
-                    fg[0] += weight * *fg_ptr++;
-                    fg[1] += weight * *fg_ptr++;
-                    fg[2] += weight * *fg_ptr++;
-
-                    weight = (weight_array[x_hr] * 
-                              weight_array[y_hr] + 
-                              image_filter_size / 2) >> 
-                              image_filter_shift;
-                    fg[0] += weight * *fg_ptr++;
-                    fg[1] += weight * *fg_ptr++;
-                    fg[2] += weight * *fg_ptr++;
-
-                    fg[0] >>= image_filter_shift;
-                    fg[1] >>= image_filter_shift;
-                    fg[2] >>= image_filter_shift;
-                    src_alpha = base_mask;
-
-                    if(fg[0] > base_mask) fg[0] = base_mask;
-                    if(fg[1] > base_mask) fg[1] = base_mask;
-                    if(fg[2] > base_mask) fg[2] = base_mask;
-                }
-                else
-                {
-                    if(x_lr < -1   || y_lr < -1 ||
-                       x_lr > maxx || y_lr > maxy)
-                    {
-                        fg[order_type::R] = back_r;
-                        fg[order_type::G] = back_g;
-                        fg[order_type::B] = back_b;
-                        src_alpha         = back_a;
-                    }
-                    else
-                    {
-                        fg[0] = fg[1] = fg[2] = src_alpha = image_filter_size / 2;
 
-                        x_hr &= image_subpixel_mask;
-                        y_hr &= image_subpixel_mask;
-
-                        weight = (weight_array[x_hr + image_subpixel_size] * 
-                                  weight_array[y_hr + image_subpixel_size] + 
-                                  image_filter_size / 2) >> 
-                                  image_filter_shift;
-                        if(x_lr >= 0    && y_lr >= 0 &&
-                           x_lr <= maxx && y_lr <= maxy)
-                        {
-                            fg_ptr = (const value_type*)base_type::source_image().row(y_lr) + x_lr + x_lr + x_lr;
-                            fg[0] += weight * *fg_ptr++;
-                            fg[1] += weight * *fg_ptr++;
-                            fg[2] += weight * *fg_ptr++;
-                            src_alpha += weight * base_mask;
-                        }
-                        else
-                        {
-                            fg[order_type::R] += back_r * weight;
-                            fg[order_type::G] += back_g * weight;
-                            fg[order_type::B] += back_b * weight;
-                            src_alpha         += back_a * weight;
-                        }
-
-                        x_lr++;
-
-                        weight = (weight_array[x_hr] * 
-                                  weight_array[y_hr + image_subpixel_size] + 
-                                  image_filter_size / 2) >> 
-                                  image_filter_shift;
-                        if(x_lr >= 0    && y_lr >= 0 &&
-                           x_lr <= maxx && y_lr <= maxy)
-                        {
-                            fg_ptr = (const value_type*)base_type::source_image().row(y_lr) + x_lr + x_lr + x_lr;
-                            fg[0]     += weight * *fg_ptr++;
-                            fg[1]     += weight * *fg_ptr++;
-                            fg[2]     += weight * *fg_ptr++;
-                            src_alpha += weight * base_mask;
-                        }
-                        else
-                        {
-                            fg[order_type::R] += back_r * weight;
-                            fg[order_type::G] += back_g * weight;
-                            fg[order_type::B] += back_b * weight;
-                            src_alpha         += back_a * weight;
-                        }
-
-                        x_lr--;
-                        y_lr++;
-
-                        weight = (weight_array[x_hr + image_subpixel_size] * 
-                                  weight_array[y_hr] + 
-                                  image_filter_size / 2) >> 
-                                  image_filter_shift;
-                        if(x_lr >= 0    && y_lr >= 0 &&
-                           x_lr <= maxx && y_lr <= maxy)
-                        {
-                            fg_ptr = (const value_type*)base_type::source_image().row(y_lr) + x_lr + x_lr + x_lr;
-                            fg[0] += weight * *fg_ptr++;
-                            fg[1] += weight * *fg_ptr++;
-                            fg[2] += weight * *fg_ptr++;
-                            src_alpha += weight * base_mask;
-                        }
-                        else
-                        {
-                            fg[order_type::R] += back_r * weight;
-                            fg[order_type::G] += back_g * weight;
-                            fg[order_type::B] += back_b * weight;
-                            src_alpha         += back_a * weight;
-                        }
-
-                        x_lr++;
+                unsigned weight;
+                fg[0] = fg[1] = fg[2] = image_filter_scale / 2;
 
-                        weight = (weight_array[x_hr] * 
-                                  weight_array[y_hr] + 
-                                  image_filter_size / 2) >> 
-                                  image_filter_shift;
-                        if(x_lr >= 0    && y_lr >= 0 &&
-                           x_lr <= maxx && y_lr <= maxy)
-                        {
-                            fg_ptr = (const value_type*)base_type::source_image().row(y_lr) + x_lr + x_lr + x_lr;
-                            fg[0] += weight * *fg_ptr++;
-                            fg[1] += weight * *fg_ptr++;
-                            fg[2] += weight * *fg_ptr++;
-                            src_alpha += weight * base_mask;
-                        }
-                        else
-                        {
-                            fg[order_type::R] += back_r * weight;
-                            fg[order_type::G] += back_g * weight;
-                            fg[order_type::B] += back_b * weight;
-                            src_alpha         += back_a * weight;
-                        }
+                x_hr &= image_subpixel_mask;
+                y_hr &= image_subpixel_mask;
 
-                        fg[0]     >>= image_filter_shift;
-                        fg[1]     >>= image_filter_shift;
-                        fg[2]     >>= image_filter_shift;
-                        src_alpha >>= image_filter_shift;
-
-                        if(src_alpha > base_mask) src_alpha = base_mask;
-                        if(fg[0] > src_alpha) fg[0] = src_alpha;
-                        if(fg[1] > src_alpha) fg[1] = src_alpha;
-                        if(fg[2] > src_alpha) fg[2] = src_alpha;
-                    }
-                }
+                fg_ptr = (const value_type*)base_type::source().span(x_lr, y_lr, 2);
+                weight = (weight_array[x_hr + image_subpixel_scale] * 
+                          weight_array[y_hr + image_subpixel_scale] + 
+                          image_filter_scale / 2) >> 
+                          image_filter_shift;
+                fg[0] += weight * *fg_ptr++;
+                fg[1] += weight * *fg_ptr++;
+                fg[2] += weight * *fg_ptr;
+
+                fg_ptr = (const value_type*)base_type::source().next_x();
+                weight = (weight_array[x_hr] * 
+                          weight_array[y_hr + image_subpixel_scale] + 
+                          image_filter_scale / 2) >> 
+                          image_filter_shift;
+                fg[0] += weight * *fg_ptr++;
+                fg[1] += weight * *fg_ptr++;
+                fg[2] += weight * *fg_ptr;
+
+                fg_ptr = (const value_type*)base_type::source().next_y();
+                weight = (weight_array[x_hr + image_subpixel_scale] * 
+                          weight_array[y_hr] + 
+                          image_filter_scale / 2) >> 
+                          image_filter_shift;
+                fg[0] += weight * *fg_ptr++;
+                fg[1] += weight * *fg_ptr++;
+                fg[2] += weight * *fg_ptr;
+
+                fg_ptr = (const value_type*)base_type::source().next_x();
+                weight = (weight_array[x_hr] * 
+                          weight_array[y_hr] + 
+                          image_filter_scale / 2) >> 
+                          image_filter_shift;
+                fg[0] += weight * *fg_ptr++;
+                fg[1] += weight * *fg_ptr++;
+                fg[2] += weight * *fg_ptr;
+
+                fg[0] >>= image_filter_shift;
+                fg[1] >>= image_filter_shift;
+                fg[2] >>= image_filter_shift;
+
+                if(fg[order_type::R] > base_mask) fg[order_type::R] = base_mask;
+                if(fg[order_type::G] > base_mask) fg[order_type::G] = base_mask;
+                if(fg[order_type::B] > base_mask) fg[order_type::B] = base_mask;
 
                 span->r = (value_type)fg[order_type::R];
                 span->g = (value_type)fg[order_type::G];
                 span->b = (value_type)fg[order_type::B];
-                span->a = (value_type)src_alpha;
+                span->a = base_mask;
+
                 ++span;
                 ++base_type::interpolator();
 
             } while(--len);
-
-            return base_type::allocator().span();
         }
     };
 
 
 
-
-
-
-
-    //=================================================span_image_filter_rgb
-    template<class ColorT,
-             class Order, 
-             class Interpolator, 
-             class Allocator = span_allocator<ColorT> > 
+    //===================================================span_image_filter_rgb
+    template<class Source, class Interpolator> 
     class span_image_filter_rgb : 
-    public span_image_filter<ColorT, Interpolator, Allocator>
+    public span_image_filter<Source, Interpolator>
     {
     public:
-        typedef ColorT color_type;
-        typedef Order order_type;
+        typedef Source source_type;
+        typedef typename source_type::color_type color_type;
+        typedef typename source_type::order_type order_type;
         typedef Interpolator interpolator_type;
-        typedef Allocator alloc_type;
-        typedef span_image_filter<color_type, interpolator_type, alloc_type> base_type;
+        typedef span_image_filter<source_type, interpolator_type> base_type;
         typedef typename color_type::value_type value_type;
         typedef typename color_type::calc_type calc_type;
-        enum
+        enum base_scale_e
         {
             base_shift = color_type::base_shift,
             base_mask  = color_type::base_mask
         };
 
         //--------------------------------------------------------------------
-        span_image_filter_rgb(alloc_type& alloc) : base_type(alloc) {}
-
-        //--------------------------------------------------------------------
-        span_image_filter_rgb(alloc_type& alloc,
-                               const rendering_buffer& src, 
-                               const color_type& back_color,
-                               interpolator_type& inter,
-                               const image_filter_lut& filter) :
-            base_type(alloc, src, back_color, inter, &filter) 
+        span_image_filter_rgb() {}
+        span_image_filter_rgb(source_type& src, 
+                              interpolator_type& inter,
+                              const image_filter_lut& filter) :
+            base_type(src, inter, &filter) 
         {}
 
         //--------------------------------------------------------------------
-        color_type* generate(int x, int y, unsigned len)
+        void generate(color_type* span, int x, int y, unsigned len)
         {
             base_type::interpolator().begin(x + base_type::filter_dx_dbl(), 
                                             y + base_type::filter_dy_dbl(), len);
 
             int fg[3];
-            int src_alpha;
-            value_type back_r = base_type::background_color().r;
-            value_type back_g = base_type::background_color().g;
-            value_type back_b = base_type::background_color().b;
-            value_type back_a = base_type::background_color().a;
-
-            const value_type* fg_ptr;
-
-            unsigned   diameter     = base_type::filter().diameter();
-            int        start        = base_type::filter().start();
-            int        start1       = start - 1;
-            const int16* weight_array = base_type::filter().weight_array();
-
-            unsigned step_back = diameter * 3;
-            color_type* span = base_type::allocator().span();
-
-            int maxx = base_type::source_image().width() + start - 2;
-            int maxy = base_type::source_image().height() + start - 2;
+            const value_type *fg_ptr;
 
-            int maxx2 = base_type::source_image().width() - start - 1;
-            int maxy2 = base_type::source_image().height() - start - 1;
+            unsigned     diameter     = base_type::filter().diameter();
+            int          start        = base_type::filter().start();
+            const int16* weight_array = base_type::filter().weight_array();
 
             int x_count; 
             int weight_y;
@@ -687,150 +578,311 @@ namespace agg
                 x -= base_type::filter_dx_int();
                 y -= base_type::filter_dy_int();
 
-                int x_hr = x;
-                int y_hr = y;
-            
+                int x_hr = x; 
+                int y_hr = y; 
+
                 int x_lr = x_hr >> image_subpixel_shift;
                 int y_lr = y_hr >> image_subpixel_shift;
 
-                fg[0] = fg[1] = fg[2] = image_filter_size / 2;
+                fg[0] = fg[1] = fg[2] = image_filter_scale / 2;
 
                 int x_fract = x_hr & image_subpixel_mask;
                 unsigned y_count = diameter;
 
-                if(x_lr >= -start && y_lr >= -start &&
-                   x_lr <= maxx   && y_lr <= maxy) 
+                y_hr = image_subpixel_mask - (y_hr & image_subpixel_mask);
+                fg_ptr = (const value_type*)base_type::source().span(x_lr + start, 
+                                                                     y_lr + start, 
+                                                                     diameter);
+                for(;;)
                 {
-                    y_hr = image_subpixel_mask - (y_hr & image_subpixel_mask);
-                    fg_ptr = (const value_type*)base_type::source_image().row(y_lr + start) + (x_lr + start) * 3;
-                    do
+                    x_count  = diameter;
+                    weight_y = weight_array[y_hr];
+                    x_hr = image_subpixel_mask - x_fract;
+                    for(;;)
                     {
-                        x_count = diameter;
-                        weight_y = weight_array[y_hr];
-                        x_hr = image_subpixel_mask - x_fract;
+                        int weight = (weight_y * weight_array[x_hr] + 
+                                     image_filter_scale / 2) >> 
+                                     image_filter_shift;
+
+                        fg[0] += weight * *fg_ptr++;
+                        fg[1] += weight * *fg_ptr++;
+                        fg[2] += weight * *fg_ptr;
+
+                        if(--x_count == 0) break;
+                        x_hr  += image_subpixel_scale;
+                        fg_ptr = (const value_type*)base_type::source().next_x();
+                    }
 
-                        do
-                        {
-                            int weight = (weight_y * weight_array[x_hr] + 
-                                         image_filter_size / 2) >> 
-                                         image_filter_shift;
-            
-                            fg[0] += *fg_ptr++ * weight;
-                            fg[1] += *fg_ptr++ * weight;
-                            fg[2] += *fg_ptr++ * weight;
-
-                            x_hr += image_subpixel_size;
-
-                        } while(--x_count);
-
-                        y_hr += image_subpixel_size;
-                        fg_ptr = (const value_type*)base_type::source_image().next_row(fg_ptr - step_back);
-
-                    } while(--y_count);
-
-                    fg[0] >>= image_filter_shift;
-                    fg[1] >>= image_filter_shift;
-                    fg[2] >>= image_filter_shift;
-
-                    if(fg[0] < 0) fg[0] = 0;
-                    if(fg[1] < 0) fg[1] = 0;
-                    if(fg[2] < 0) fg[2] = 0;
-
-                    if(fg[0] > base_mask) fg[0] = base_mask;
-                    if(fg[1] > base_mask) fg[1] = base_mask;
-                    if(fg[2] > base_mask) fg[2] = base_mask;
-                    src_alpha = base_mask;
+                    if(--y_count == 0) break;
+                    y_hr  += image_subpixel_scale;
+                    fg_ptr = (const value_type*)base_type::source().next_y();
                 }
-                else
+
+                fg[0] >>= image_filter_shift;
+                fg[1] >>= image_filter_shift;
+                fg[2] >>= image_filter_shift;
+
+                if(fg[0] < 0) fg[0] = 0;
+                if(fg[1] < 0) fg[1] = 0;
+                if(fg[2] < 0) fg[2] = 0;
+
+                if(fg[order_type::R] > base_mask) fg[order_type::R] = base_mask;
+                if(fg[order_type::G] > base_mask) fg[order_type::G] = base_mask;
+                if(fg[order_type::B] > base_mask) fg[order_type::B] = base_mask;
+
+                span->r = (value_type)fg[order_type::R];
+                span->g = (value_type)fg[order_type::G];
+                span->b = (value_type)fg[order_type::B];
+                span->a = base_mask;
+
+                ++span;
+                ++base_type::interpolator();
+
+            } while(--len);
+        }
+    };
+
+
+
+    //==========================================span_image_resample_rgb_affine
+    template<class Source> 
+    class span_image_resample_rgb_affine : 
+    public span_image_resample_affine<Source>
+    {
+    public:
+        typedef Source source_type;
+        typedef typename source_type::color_type color_type;
+        typedef typename source_type::order_type order_type;
+        typedef span_image_resample_affine<source_type> base_type;
+        typedef typename base_type::interpolator_type interpolator_type;
+        typedef typename color_type::value_type value_type;
+        typedef typename color_type::long_type long_type;
+        enum base_scale_e
+        {
+            base_shift      = color_type::base_shift,
+            base_mask       = color_type::base_mask,
+            downscale_shift = image_filter_shift
+        };
+
+        //--------------------------------------------------------------------
+        span_image_resample_rgb_affine() {}
+        span_image_resample_rgb_affine(source_type& src, 
+                                       interpolator_type& inter,
+                                       const image_filter_lut& filter) :
+            base_type(src, inter, filter) 
+        {}
+
+
+        //--------------------------------------------------------------------
+        void generate(color_type* span, int x, int y, unsigned len)
+        {
+            base_type::interpolator().begin(x + base_type::filter_dx_dbl(), 
+                                            y + base_type::filter_dy_dbl(), len);
+
+            long_type fg[3];
+
+            int diameter     = base_type::filter().diameter();
+            int filter_scale = diameter << image_subpixel_shift;
+            int radius_x     = (diameter * base_type::m_rx) >> 1;
+            int radius_y     = (diameter * base_type::m_ry) >> 1;
+            int len_x_lr     = 
+                (diameter * base_type::m_rx + image_subpixel_mask) >> 
+                    image_subpixel_shift;
+
+            const int16* weight_array = base_type::filter().weight_array();
+
+            do
+            {
+                base_type::interpolator().coordinates(&x, &y);
+
+                x += base_type::filter_dx_int() - radius_x;
+                y += base_type::filter_dy_int() - radius_y;
+
+                fg[0] = fg[1] = fg[2] = image_filter_scale / 2;
+
+                int y_lr = y >> image_subpixel_shift;
+                int y_hr = ((image_subpixel_mask - (y & image_subpixel_mask)) * 
+                                base_type::m_ry_inv) >> 
+                                    image_subpixel_shift;
+                int total_weight = 0;
+                int x_lr = x >> image_subpixel_shift;
+                int x_hr = ((image_subpixel_mask - (x & image_subpixel_mask)) * 
+                                base_type::m_rx_inv) >> 
+                                    image_subpixel_shift;
+
+                int x_hr2 = x_hr;
+                const value_type* fg_ptr = 
+                    (const value_type*)base_type::source().span(x_lr, y_lr, len_x_lr);
+                for(;;)
                 {
-                    if(x_lr < start1 || y_lr < start1 ||
-                       x_lr > maxx2  || y_lr > maxy2) 
+                    int weight_y = weight_array[y_hr];
+                    x_hr = x_hr2;
+                    for(;;)
                     {
-                        fg[order_type::R] = back_r;
-                        fg[order_type::G] = back_g;
-                        fg[order_type::B] = back_b;
-                        src_alpha         = back_a;
+                        int weight = (weight_y * weight_array[x_hr] + 
+                                     image_filter_scale / 2) >> 
+                                     downscale_shift;
+
+                        fg[0] += *fg_ptr++ * weight;
+                        fg[1] += *fg_ptr++ * weight;
+                        fg[2] += *fg_ptr   * weight;
+                        total_weight += weight;
+                        x_hr  += base_type::m_rx_inv;
+                        if(x_hr >= filter_scale) break;
+                        fg_ptr = (const value_type*)base_type::source().next_x();
                     }
-                    else
-                    {
-                        src_alpha = image_filter_size / 2;
-                        y_lr = (y >> image_subpixel_shift) + start;
-                        y_hr = image_subpixel_mask - (y_hr & image_subpixel_mask);
+                    y_hr += base_type::m_ry_inv;
+                    if(y_hr >= filter_scale) break;
+                    fg_ptr = (const value_type*)base_type::source().next_y();
+                }
 
-                        do
-                        {
-                            x_count = diameter;
-                            weight_y = weight_array[y_hr];
-                            x_lr = (x >> image_subpixel_shift) + start;
-                            x_hr = image_subpixel_mask - x_fract;
-
-                            do
-                            {
-                                int weight = (weight_y * weight_array[x_hr] + 
-                                             image_filter_size / 2) >> 
-                                             image_filter_shift;
-
-                                if(x_lr >= 0 && y_lr >= 0 && 
-                                   x_lr < int(base_type::source_image().width()) && 
-                                   y_lr < int(base_type::source_image().height()))
-                                {
-                                    fg_ptr = (const value_type*)base_type::source_image().row(y_lr) + x_lr * 3;
-                                    fg[0] += *fg_ptr++ * weight;
-                                    fg[1] += *fg_ptr++ * weight;
-                                    fg[2] += *fg_ptr++ * weight;
-                                    src_alpha += base_mask * weight;
-                                }
-                                else
-                                {
-                                    fg[order_type::R] += back_r * weight;
-                                    fg[order_type::G] += back_g * weight;
-                                    fg[order_type::B] += back_b * weight;
-                                    src_alpha         += back_a * weight;
-                                }
-                                x_hr += image_subpixel_size;
-                                x_lr++;
-
-                            } while(--x_count);
-
-                            y_hr += image_subpixel_size;
-                            y_lr++;
-
-                        } while(--y_count);
-
-
-                        fg[0] >>= image_filter_shift;
-                        fg[1] >>= image_filter_shift;
-                        fg[2] >>= image_filter_shift;
-                        src_alpha >>= image_filter_shift;
-
-                        if(fg[0] < 0) fg[0] = 0;
-                        if(fg[1] < 0) fg[1] = 0;
-                        if(fg[2] < 0) fg[2] = 0;
-                        if(src_alpha < 0) src_alpha = 0;
-
-                        if(src_alpha > base_mask) src_alpha = base_mask;
-                        if(fg[0] > src_alpha) fg[0] = src_alpha;
-                        if(fg[1] > src_alpha) fg[1] = src_alpha;
-                        if(fg[2] > src_alpha) fg[2] = src_alpha;
+                fg[0] /= total_weight;
+                fg[1] /= total_weight;
+                fg[2] /= total_weight;
+
+                if(fg[0] < 0) fg[0] = 0;
+                if(fg[1] < 0) fg[1] = 0;
+                if(fg[2] < 0) fg[2] = 0;
+
+                if(fg[order_type::R] > base_mask) fg[order_type::R] = base_mask;
+                if(fg[order_type::G] > base_mask) fg[order_type::G] = base_mask;
+                if(fg[order_type::B] > base_mask) fg[order_type::B] = base_mask;
+
+                span->r = (value_type)fg[order_type::R];
+                span->g = (value_type)fg[order_type::G];
+                span->b = (value_type)fg[order_type::B];
+                span->a = base_mask;
+
+                ++span;
+                ++base_type::interpolator();
+            } while(--len);
+        }
+    };
+
+
+
+    //=================================================span_image_resample_rgb
+    template<class Source, class Interpolator>
+    class span_image_resample_rgb : 
+    public span_image_resample<Source, Interpolator>
+    {
+    public:
+        typedef Source source_type;
+        typedef typename source_type::color_type color_type;
+        typedef typename source_type::order_type order_type;
+        typedef Interpolator interpolator_type;
+        typedef span_image_resample<source_type, interpolator_type> base_type;
+        typedef typename color_type::value_type value_type;
+        typedef typename color_type::long_type long_type;
+        enum base_scale_e
+        {
+            base_shift = color_type::base_shift,
+            base_mask  = color_type::base_mask,
+            downscale_shift = image_filter_shift
+        };
+
+        //--------------------------------------------------------------------
+        span_image_resample_rgb() {}
+        span_image_resample_rgb(source_type& src, 
+                                interpolator_type& inter,
+                                const image_filter_lut& filter) :
+            base_type(src, inter, filter)
+        {}
+
+        //--------------------------------------------------------------------
+        void generate(color_type* span, int x, int y, unsigned len)
+        {
+            base_type::interpolator().begin(x + base_type::filter_dx_dbl(), 
+                                            y + base_type::filter_dy_dbl(), len);
+            long_type fg[3];
+
+            int diameter = base_type::filter().diameter();
+            int filter_scale = diameter << image_subpixel_shift;
+
+            const int16* weight_array = base_type::filter().weight_array();
+            do
+            {
+                int rx;
+                int ry;
+                int rx_inv = image_subpixel_scale;
+                int ry_inv = image_subpixel_scale;
+                base_type::interpolator().coordinates(&x,  &y);
+                base_type::interpolator().local_scale(&rx, &ry);
+                base_type::adjust_scale(&rx, &ry);
+
+                rx_inv = image_subpixel_scale * image_subpixel_scale / rx;
+                ry_inv = image_subpixel_scale * image_subpixel_scale / ry;
+
+                int radius_x = (diameter * rx) >> 1;
+                int radius_y = (diameter * ry) >> 1;
+                int len_x_lr = 
+                    (diameter * rx + image_subpixel_mask) >> 
+                        image_subpixel_shift;
+
+                x += base_type::filter_dx_int() - radius_x;
+                y += base_type::filter_dy_int() - radius_y;
+
+                fg[0] = fg[1] = fg[2] = image_filter_scale / 2;
+
+                int y_lr = y >> image_subpixel_shift;
+                int y_hr = ((image_subpixel_mask - (y & image_subpixel_mask)) * 
+                               ry_inv) >> 
+                                   image_subpixel_shift;
+                int total_weight = 0;
+                int x_lr = x >> image_subpixel_shift;
+                int x_hr = ((image_subpixel_mask - (x & image_subpixel_mask)) * 
+                               rx_inv) >> 
+                                   image_subpixel_shift;
+                int x_hr2 = x_hr;
+                const value_type* fg_ptr = 
+                    (const value_type*)base_type::source().span(x_lr, y_lr, len_x_lr);
+
+                for(;;)
+                {
+                    int weight_y = weight_array[y_hr];
+                    x_hr = x_hr2;
+                    for(;;)
+                    {
+                        int weight = (weight_y * weight_array[x_hr] + 
+                                     image_filter_scale / 2) >> 
+                                     downscale_shift;
+                        fg[0] += *fg_ptr++ * weight;
+                        fg[1] += *fg_ptr++ * weight;
+                        fg[2] += *fg_ptr   * weight;
+                        total_weight += weight;
+                        x_hr  += rx_inv;
+                        if(x_hr >= filter_scale) break;
+                        fg_ptr = (const value_type*)base_type::source().next_x();
                     }
+                    y_hr += ry_inv;
+                    if(y_hr >= filter_scale) break;
+                    fg_ptr = (const value_type*)base_type::source().next_y();
                 }
 
+                fg[0] /= total_weight;
+                fg[1] /= total_weight;
+                fg[2] /= total_weight;
+
+                if(fg[0] < 0) fg[0] = 0;
+                if(fg[1] < 0) fg[1] = 0;
+                if(fg[2] < 0) fg[2] = 0;
+
+                if(fg[order_type::R] > base_mask) fg[order_type::R] = base_mask;
+                if(fg[order_type::G] > base_mask) fg[order_type::G] = base_mask;
+                if(fg[order_type::B] > base_mask) fg[order_type::B] = base_mask;
+
                 span->r = (value_type)fg[order_type::R];
                 span->g = (value_type)fg[order_type::G];
                 span->b = (value_type)fg[order_type::B];
-                span->a = (value_type)src_alpha;
+                span->a = base_mask;
 
                 ++span;
                 ++base_type::interpolator();
-
             } while(--len);
-
-            return base_type::allocator().span();
         }
     };
 
 
-
 }
 
 



Mime
View raw message