Anti-Grain Geometry - AGG (libagg)  2.5
agg-2.5/include/agg_span_image_filter_rgb.h
Go to the documentation of this file.
00001 //----------------------------------------------------------------------------
00002 // Anti-Grain Geometry (AGG) - Version 2.5
00003 // A high quality rendering engine for C++
00004 // Copyright (C) 2002-2006 Maxim Shemanarev
00005 // Contact: mcseem@antigrain.com
00006 //          mcseemagg@yahoo.com
00007 //          http://antigrain.com
00008 // 
00009 // AGG is free software; you can redistribute it and/or
00010 // modify it under the terms of the GNU General Public License
00011 // as published by the Free Software Foundation; either version 2
00012 // of the License, or (at your option) any later version.
00013 // 
00014 // AGG is distributed in the hope that it will be useful,
00015 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00016 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017 // GNU General Public License for more details.
00018 // 
00019 // You should have received a copy of the GNU General Public License
00020 // along with AGG; if not, write to the Free Software
00021 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
00022 // MA 02110-1301, USA.
00023 //----------------------------------------------------------------------------
00024 //
00025 // Adaptation for high precision colors has been sponsored by 
00026 // Liberty Technology Systems, Inc., visit http://lib-sys.com
00027 //
00028 // Liberty Technology Systems, Inc. is the provider of
00029 // PostScript and PDF technology for software developers.
00030 // 
00031 //----------------------------------------------------------------------------
00032 #ifndef AGG_SPAN_IMAGE_FILTER_RGB_INCLUDED
00033 #define AGG_SPAN_IMAGE_FILTER_RGB_INCLUDED
00034 
00035 #include "agg_basics.h"
00036 #include "agg_color_rgba.h"
00037 #include "agg_span_image_filter.h"
00038 
00039 
00040 namespace agg
00041 {
00042 
00043     //===============================================span_image_filter_rgb_nn
00044     template<class Source, class Interpolator> 
00045     class span_image_filter_rgb_nn : 
00046     public span_image_filter<Source, Interpolator>
00047     {
00048     public:
00049         typedef Source source_type;
00050         typedef typename source_type::color_type color_type;
00051         typedef typename source_type::order_type order_type;
00052         typedef Interpolator interpolator_type;
00053         typedef span_image_filter<source_type, interpolator_type> base_type;
00054         typedef typename color_type::value_type value_type;
00055         typedef typename color_type::calc_type calc_type;
00056         enum base_scale_e
00057         {
00058             base_shift = color_type::base_shift,
00059             base_mask  = color_type::base_mask
00060         };
00061 
00062         //--------------------------------------------------------------------
00063         span_image_filter_rgb_nn() {}
00064         span_image_filter_rgb_nn(source_type& src, 
00065                                  interpolator_type& inter) :
00066             base_type(src, inter, 0) 
00067         {}
00068 
00069         //--------------------------------------------------------------------
00070         void generate(color_type* span, int x, int y, unsigned len)
00071         {
00072             base_type::interpolator().begin(x + base_type::filter_dx_dbl(), 
00073                                             y + base_type::filter_dy_dbl(), len);
00074             do
00075             {
00076                 base_type::interpolator().coordinates(&x, &y);
00077                 const value_type* fg_ptr = (const value_type*)
00078                     base_type::source().span(x >> image_subpixel_shift, 
00079                                              y >> image_subpixel_shift, 
00080                                              1);
00081                 span->r = fg_ptr[order_type::R];
00082                 span->g = fg_ptr[order_type::G];
00083                 span->b = fg_ptr[order_type::B];
00084                 span->a = base_mask;
00085                 ++span;
00086                 ++base_type::interpolator();
00087 
00088             } while(--len);
00089         }
00090     };
00091 
00092 
00093 
00094     //==========================================span_image_filter_rgb_bilinear
00095     template<class Source, class Interpolator> 
00096     class span_image_filter_rgb_bilinear : 
00097     public span_image_filter<Source, Interpolator>
00098     {
00099     public:
00100         typedef Source source_type;
00101         typedef typename source_type::color_type color_type;
00102         typedef typename source_type::order_type order_type;
00103         typedef Interpolator interpolator_type;
00104         typedef span_image_filter<source_type, interpolator_type> base_type;
00105         typedef typename color_type::value_type value_type;
00106         typedef typename color_type::calc_type calc_type;
00107         enum base_scale_e
00108         {
00109             base_shift = color_type::base_shift,
00110             base_mask  = color_type::base_mask
00111         };
00112 
00113         //--------------------------------------------------------------------
00114         span_image_filter_rgb_bilinear() {}
00115         span_image_filter_rgb_bilinear(source_type& src, 
00116                                        interpolator_type& inter) :
00117             base_type(src, inter, 0) 
00118         {}
00119 
00120 
00121         //--------------------------------------------------------------------
00122         void generate(color_type* span, int x, int y, unsigned len)
00123         {
00124             base_type::interpolator().begin(x + base_type::filter_dx_dbl(), 
00125                                             y + base_type::filter_dy_dbl(), len);
00126             calc_type fg[3];
00127             const value_type *fg_ptr;
00128             do
00129             {
00130                 int x_hr;
00131                 int y_hr;
00132 
00133                 base_type::interpolator().coordinates(&x_hr, &y_hr);
00134 
00135                 x_hr -= base_type::filter_dx_int();
00136                 y_hr -= base_type::filter_dy_int();
00137 
00138                 int x_lr = x_hr >> image_subpixel_shift;
00139                 int y_lr = y_hr >> image_subpixel_shift;
00140 
00141                 unsigned weight;
00142 
00143                 fg[0] = 
00144                 fg[1] = 
00145                 fg[2] = image_subpixel_scale * image_subpixel_scale / 2;
00146 
00147                 x_hr &= image_subpixel_mask;
00148                 y_hr &= image_subpixel_mask;
00149 
00150                 fg_ptr = (const value_type*)base_type::source().span(x_lr, y_lr, 2);
00151                 weight = (image_subpixel_scale - x_hr) * 
00152                          (image_subpixel_scale - y_hr);
00153                 fg[0] += weight * *fg_ptr++;
00154                 fg[1] += weight * *fg_ptr++;
00155                 fg[2] += weight * *fg_ptr;
00156 
00157                 fg_ptr = (const value_type*)base_type::source().next_x();
00158                 weight = x_hr * (image_subpixel_scale - y_hr);
00159                 fg[0] += weight * *fg_ptr++;
00160                 fg[1] += weight * *fg_ptr++;
00161                 fg[2] += weight * *fg_ptr;
00162 
00163                 fg_ptr = (const value_type*)base_type::source().next_y();
00164                 weight = (image_subpixel_scale - x_hr) * y_hr;
00165                 fg[0] += weight * *fg_ptr++;
00166                 fg[1] += weight * *fg_ptr++;
00167                 fg[2] += weight * *fg_ptr;
00168 
00169                 fg_ptr = (const value_type*)base_type::source().next_x();
00170                 weight = x_hr * y_hr;
00171                 fg[0] += weight * *fg_ptr++;
00172                 fg[1] += weight * *fg_ptr++;
00173                 fg[2] += weight * *fg_ptr;
00174 
00175                 span->r = value_type(fg[order_type::R] >> (image_subpixel_shift * 2));
00176                 span->g = value_type(fg[order_type::G] >> (image_subpixel_shift * 2));
00177                 span->b = value_type(fg[order_type::B] >> (image_subpixel_shift * 2));
00178                 span->a = base_mask;
00179 
00180                 ++span;
00181                 ++base_type::interpolator();
00182 
00183             } while(--len);
00184         }
00185     };
00186 
00187 
00188 
00189     //=====================================span_image_filter_rgb_bilinear_clip
00190     template<class Source, class Interpolator> 
00191     class span_image_filter_rgb_bilinear_clip : 
00192     public span_image_filter<Source, Interpolator>
00193     {
00194     public:
00195         typedef Source source_type;
00196         typedef typename source_type::color_type color_type;
00197         typedef typename source_type::order_type order_type;
00198         typedef Interpolator interpolator_type;
00199         typedef span_image_filter<source_type, interpolator_type> base_type;
00200         typedef typename color_type::value_type value_type;
00201         typedef typename color_type::calc_type calc_type;
00202         enum base_scale_e
00203         {
00204             base_shift = color_type::base_shift,
00205             base_mask  = color_type::base_mask
00206         };
00207 
00208         //--------------------------------------------------------------------
00209         span_image_filter_rgb_bilinear_clip() {}
00210         span_image_filter_rgb_bilinear_clip(source_type& src, 
00211                                             const color_type& back_color,
00212                                             interpolator_type& inter) :
00213             base_type(src, inter, 0),
00214             m_back_color(back_color)
00215         {}
00216         const color_type& background_color() const { return m_back_color; }
00217         void background_color(const color_type& v)   { m_back_color = v; }
00218 
00219         //--------------------------------------------------------------------
00220         void generate(color_type* span, int x, int y, unsigned len)
00221         {
00222             base_type::interpolator().begin(x + base_type::filter_dx_dbl(), 
00223                                             y + base_type::filter_dy_dbl(), len);
00224             calc_type fg[3];
00225             calc_type src_alpha;
00226             value_type back_r = m_back_color.r;
00227             value_type back_g = m_back_color.g;
00228             value_type back_b = m_back_color.b;
00229             value_type back_a = m_back_color.a;
00230 
00231             const value_type *fg_ptr;
00232 
00233             int maxx = base_type::source().width() - 1;
00234             int maxy = base_type::source().height() - 1;
00235 
00236             do
00237             {
00238                 int x_hr;
00239                 int y_hr;
00240                 
00241                 base_type::interpolator().coordinates(&x_hr, &y_hr);
00242 
00243                 x_hr -= base_type::filter_dx_int();
00244                 y_hr -= base_type::filter_dy_int();
00245 
00246                 int x_lr = x_hr >> image_subpixel_shift;
00247                 int y_lr = y_hr >> image_subpixel_shift;
00248                 unsigned weight;
00249 
00250                 if(x_lr >= 0    && y_lr >= 0 &&
00251                    x_lr <  maxx && y_lr <  maxy) 
00252                 {
00253                     fg[0] = 
00254                     fg[1] = 
00255                     fg[2] = image_subpixel_scale * image_subpixel_scale / 2;
00256 
00257                     x_hr &= image_subpixel_mask;
00258                     y_hr &= image_subpixel_mask;
00259 
00260                     fg_ptr = (const value_type*)
00261                         base_type::source().row_ptr(y_lr) + x_lr + x_lr + x_lr;
00262 
00263                     weight = (image_subpixel_scale - x_hr) * 
00264                              (image_subpixel_scale - y_hr);
00265                     fg[0] += weight * *fg_ptr++;
00266                     fg[1] += weight * *fg_ptr++;
00267                     fg[2] += weight * *fg_ptr++;
00268 
00269                     weight = x_hr * (image_subpixel_scale - y_hr);
00270                     fg[0] += weight * *fg_ptr++;
00271                     fg[1] += weight * *fg_ptr++;
00272                     fg[2] += weight * *fg_ptr++;
00273 
00274                     ++y_lr;
00275                     fg_ptr = (const value_type*)
00276                         base_type::source().row_ptr(y_lr) + x_lr + x_lr + x_lr;
00277 
00278                     weight = (image_subpixel_scale - x_hr) * y_hr;
00279                     fg[0] += weight * *fg_ptr++;
00280                     fg[1] += weight * *fg_ptr++;
00281                     fg[2] += weight * *fg_ptr++;
00282 
00283                     weight = x_hr * y_hr;
00284                     fg[0] += weight * *fg_ptr++;
00285                     fg[1] += weight * *fg_ptr++;
00286                     fg[2] += weight * *fg_ptr++;
00287 
00288                     fg[0] >>= image_subpixel_shift * 2;
00289                     fg[1] >>= image_subpixel_shift * 2;
00290                     fg[2] >>= image_subpixel_shift * 2;
00291                     src_alpha = base_mask;
00292                 }
00293                 else
00294                 {
00295                     if(x_lr < -1   || y_lr < -1 ||
00296                        x_lr > maxx || y_lr > maxy)
00297                     {
00298                         fg[order_type::R] = back_r;
00299                         fg[order_type::G] = back_g;
00300                         fg[order_type::B] = back_b;
00301                         src_alpha         = back_a;
00302                     }
00303                     else
00304                     {
00305                         fg[0] = 
00306                         fg[1] = 
00307                         fg[2] = 
00308                         src_alpha = image_subpixel_scale * image_subpixel_scale / 2;
00309 
00310                         x_hr &= image_subpixel_mask;
00311                         y_hr &= image_subpixel_mask;
00312 
00313                         weight = (image_subpixel_scale - x_hr) * 
00314                                  (image_subpixel_scale - y_hr);
00315                         if(x_lr >= 0    && y_lr >= 0 &&
00316                            x_lr <= maxx && y_lr <= maxy)
00317                         {
00318                             fg_ptr = (const value_type*)
00319                                 base_type::source().row_ptr(y_lr) + x_lr + x_lr + x_lr;
00320 
00321                             fg[0] += weight * *fg_ptr++;
00322                             fg[1] += weight * *fg_ptr++;
00323                             fg[2] += weight * *fg_ptr++;
00324                             src_alpha += weight * base_mask;
00325                         }
00326                         else
00327                         {
00328                             fg[order_type::R] += back_r * weight;
00329                             fg[order_type::G] += back_g * weight;
00330                             fg[order_type::B] += back_b * weight;
00331                             src_alpha         += back_a * weight;
00332                         }
00333 
00334                         x_lr++;
00335 
00336                         weight = x_hr * (image_subpixel_scale - y_hr);
00337                         if(x_lr >= 0    && y_lr >= 0 &&
00338                            x_lr <= maxx && y_lr <= maxy)
00339                         {
00340                             fg_ptr = (const value_type*)
00341                                 base_type::source().row_ptr(y_lr) + x_lr + x_lr + x_lr;
00342 
00343                             fg[0]     += weight * *fg_ptr++;
00344                             fg[1]     += weight * *fg_ptr++;
00345                             fg[2]     += weight * *fg_ptr++;
00346                             src_alpha += weight * base_mask;
00347                         }
00348                         else
00349                         {
00350                             fg[order_type::R] += back_r * weight;
00351                             fg[order_type::G] += back_g * weight;
00352                             fg[order_type::B] += back_b * weight;
00353                             src_alpha         += back_a * weight;
00354                         }
00355 
00356                         x_lr--;
00357                         y_lr++;
00358 
00359                         weight = (image_subpixel_scale - x_hr) * y_hr;
00360                         if(x_lr >= 0    && y_lr >= 0 &&
00361                            x_lr <= maxx && y_lr <= maxy)
00362                         {
00363                             fg_ptr = (const value_type*)
00364                                 base_type::source().row_ptr(y_lr) + x_lr + x_lr + x_lr;
00365 
00366                             fg[0] += weight * *fg_ptr++;
00367                             fg[1] += weight * *fg_ptr++;
00368                             fg[2] += weight * *fg_ptr++;
00369                             src_alpha += weight * base_mask;
00370                         }
00371                         else
00372                         {
00373                             fg[order_type::R] += back_r * weight;
00374                             fg[order_type::G] += back_g * weight;
00375                             fg[order_type::B] += back_b * weight;
00376                             src_alpha         += back_a * weight;
00377                         }
00378 
00379                         x_lr++;
00380 
00381                         weight = x_hr * y_hr;
00382                         if(x_lr >= 0    && y_lr >= 0 &&
00383                            x_lr <= maxx && y_lr <= maxy)
00384                         {
00385                             fg_ptr = (const value_type*)
00386                                 base_type::source().row_ptr(y_lr) + x_lr + x_lr + x_lr;
00387 
00388                             fg[0] += weight * *fg_ptr++;
00389                             fg[1] += weight * *fg_ptr++;
00390                             fg[2] += weight * *fg_ptr++;
00391                             src_alpha += weight * base_mask;
00392                         }
00393                         else
00394                         {
00395                             fg[order_type::R] += back_r * weight;
00396                             fg[order_type::G] += back_g * weight;
00397                             fg[order_type::B] += back_b * weight;
00398                             src_alpha         += back_a * weight;
00399                         }
00400 
00401                         fg[0] >>= image_subpixel_shift * 2;
00402                         fg[1] >>= image_subpixel_shift * 2;
00403                         fg[2] >>= image_subpixel_shift * 2;
00404                         src_alpha >>= image_subpixel_shift * 2;
00405                     }
00406                 }
00407 
00408                 span->r = (value_type)fg[order_type::R];
00409                 span->g = (value_type)fg[order_type::G];
00410                 span->b = (value_type)fg[order_type::B];
00411                 span->a = (value_type)src_alpha;
00412                 ++span;
00413                 ++base_type::interpolator();
00414 
00415             } while(--len);
00416         }
00417     private:
00418         color_type m_back_color;
00419     };
00420 
00421 
00422 
00423     //===============================================span_image_filter_rgb_2x2
00424     template<class Source, class Interpolator> 
00425     class span_image_filter_rgb_2x2 : 
00426     public span_image_filter<Source, Interpolator>
00427     {
00428     public:
00429         typedef Source source_type;
00430         typedef typename source_type::color_type color_type;
00431         typedef typename source_type::order_type order_type;
00432         typedef Interpolator interpolator_type;
00433         typedef span_image_filter<source_type, interpolator_type> base_type;
00434         typedef typename color_type::value_type value_type;
00435         typedef typename color_type::calc_type calc_type;
00436         enum base_scale_e
00437         {
00438             base_shift = color_type::base_shift,
00439             base_mask  = color_type::base_mask
00440         };
00441 
00442         //--------------------------------------------------------------------
00443         span_image_filter_rgb_2x2() {}
00444         span_image_filter_rgb_2x2(source_type& src, 
00445                                   interpolator_type& inter,
00446                                   const image_filter_lut& filter) :
00447             base_type(src, inter, &filter) 
00448         {}
00449 
00450 
00451         //--------------------------------------------------------------------
00452         void generate(color_type* span, int x, int y, unsigned len)
00453         {
00454             base_type::interpolator().begin(x + base_type::filter_dx_dbl(), 
00455                                             y + base_type::filter_dy_dbl(), len);
00456 
00457             calc_type fg[3];
00458 
00459             const value_type *fg_ptr;
00460             const int16* weight_array = base_type::filter().weight_array() + 
00461                                         ((base_type::filter().diameter()/2 - 1) << 
00462                                           image_subpixel_shift);
00463             do
00464             {
00465                 int x_hr;
00466                 int y_hr;
00467 
00468                 base_type::interpolator().coordinates(&x_hr, &y_hr);
00469 
00470                 x_hr -= base_type::filter_dx_int();
00471                 y_hr -= base_type::filter_dy_int();
00472 
00473                 int x_lr = x_hr >> image_subpixel_shift;
00474                 int y_lr = y_hr >> image_subpixel_shift;
00475 
00476                 unsigned weight;
00477                 fg[0] = fg[1] = fg[2] = image_filter_scale / 2;
00478 
00479                 x_hr &= image_subpixel_mask;
00480                 y_hr &= image_subpixel_mask;
00481 
00482                 fg_ptr = (const value_type*)base_type::source().span(x_lr, y_lr, 2);
00483                 weight = (weight_array[x_hr + image_subpixel_scale] * 
00484                           weight_array[y_hr + image_subpixel_scale] + 
00485                           image_filter_scale / 2) >> 
00486                           image_filter_shift;
00487                 fg[0] += weight * *fg_ptr++;
00488                 fg[1] += weight * *fg_ptr++;
00489                 fg[2] += weight * *fg_ptr;
00490 
00491                 fg_ptr = (const value_type*)base_type::source().next_x();
00492                 weight = (weight_array[x_hr] * 
00493                           weight_array[y_hr + image_subpixel_scale] + 
00494                           image_filter_scale / 2) >> 
00495                           image_filter_shift;
00496                 fg[0] += weight * *fg_ptr++;
00497                 fg[1] += weight * *fg_ptr++;
00498                 fg[2] += weight * *fg_ptr;
00499 
00500                 fg_ptr = (const value_type*)base_type::source().next_y();
00501                 weight = (weight_array[x_hr + image_subpixel_scale] * 
00502                           weight_array[y_hr] + 
00503                           image_filter_scale / 2) >> 
00504                           image_filter_shift;
00505                 fg[0] += weight * *fg_ptr++;
00506                 fg[1] += weight * *fg_ptr++;
00507                 fg[2] += weight * *fg_ptr;
00508 
00509                 fg_ptr = (const value_type*)base_type::source().next_x();
00510                 weight = (weight_array[x_hr] * 
00511                           weight_array[y_hr] + 
00512                           image_filter_scale / 2) >> 
00513                           image_filter_shift;
00514                 fg[0] += weight * *fg_ptr++;
00515                 fg[1] += weight * *fg_ptr++;
00516                 fg[2] += weight * *fg_ptr;
00517 
00518                 fg[0] >>= image_filter_shift;
00519                 fg[1] >>= image_filter_shift;
00520                 fg[2] >>= image_filter_shift;
00521 
00522                 if(fg[order_type::R] > base_mask) fg[order_type::R] = base_mask;
00523                 if(fg[order_type::G] > base_mask) fg[order_type::G] = base_mask;
00524                 if(fg[order_type::B] > base_mask) fg[order_type::B] = base_mask;
00525 
00526                 span->r = (value_type)fg[order_type::R];
00527                 span->g = (value_type)fg[order_type::G];
00528                 span->b = (value_type)fg[order_type::B];
00529                 span->a = base_mask;
00530 
00531                 ++span;
00532                 ++base_type::interpolator();
00533 
00534             } while(--len);
00535         }
00536     };
00537 
00538 
00539 
00540     //===================================================span_image_filter_rgb
00541     template<class Source, class Interpolator> 
00542     class span_image_filter_rgb : 
00543     public span_image_filter<Source, Interpolator>
00544     {
00545     public:
00546         typedef Source source_type;
00547         typedef typename source_type::color_type color_type;
00548         typedef typename source_type::order_type order_type;
00549         typedef Interpolator interpolator_type;
00550         typedef span_image_filter<source_type, interpolator_type> base_type;
00551         typedef typename color_type::value_type value_type;
00552         typedef typename color_type::calc_type calc_type;
00553         enum base_scale_e
00554         {
00555             base_shift = color_type::base_shift,
00556             base_mask  = color_type::base_mask
00557         };
00558 
00559         //--------------------------------------------------------------------
00560         span_image_filter_rgb() {}
00561         span_image_filter_rgb(source_type& src, 
00562                               interpolator_type& inter,
00563                               const image_filter_lut& filter) :
00564             base_type(src, inter, &filter) 
00565         {}
00566 
00567         //--------------------------------------------------------------------
00568         void generate(color_type* span, int x, int y, unsigned len)
00569         {
00570             base_type::interpolator().begin(x + base_type::filter_dx_dbl(), 
00571                                             y + base_type::filter_dy_dbl(), len);
00572 
00573             int fg[3];
00574             const value_type *fg_ptr;
00575 
00576             unsigned     diameter     = base_type::filter().diameter();
00577             int          start        = base_type::filter().start();
00578             const int16* weight_array = base_type::filter().weight_array();
00579 
00580             int x_count; 
00581             int weight_y;
00582 
00583             do
00584             {
00585                 base_type::interpolator().coordinates(&x, &y);
00586 
00587                 x -= base_type::filter_dx_int();
00588                 y -= base_type::filter_dy_int();
00589 
00590                 int x_hr = x; 
00591                 int y_hr = y; 
00592 
00593                 int x_lr = x_hr >> image_subpixel_shift;
00594                 int y_lr = y_hr >> image_subpixel_shift;
00595 
00596                 fg[0] = fg[1] = fg[2] = image_filter_scale / 2;
00597 
00598                 int x_fract = x_hr & image_subpixel_mask;
00599                 unsigned y_count = diameter;
00600 
00601                 y_hr = image_subpixel_mask - (y_hr & image_subpixel_mask);
00602                 fg_ptr = (const value_type*)base_type::source().span(x_lr + start, 
00603                                                                      y_lr + start, 
00604                                                                      diameter);
00605                 for(;;)
00606                 {
00607                     x_count  = diameter;
00608                     weight_y = weight_array[y_hr];
00609                     x_hr = image_subpixel_mask - x_fract;
00610                     for(;;)
00611                     {
00612                         int weight = (weight_y * weight_array[x_hr] + 
00613                                      image_filter_scale / 2) >> 
00614                                      image_filter_shift;
00615 
00616                         fg[0] += weight * *fg_ptr++;
00617                         fg[1] += weight * *fg_ptr++;
00618                         fg[2] += weight * *fg_ptr;
00619 
00620                         if(--x_count == 0) break;
00621                         x_hr  += image_subpixel_scale;
00622                         fg_ptr = (const value_type*)base_type::source().next_x();
00623                     }
00624 
00625                     if(--y_count == 0) break;
00626                     y_hr  += image_subpixel_scale;
00627                     fg_ptr = (const value_type*)base_type::source().next_y();
00628                 }
00629 
00630                 fg[0] >>= image_filter_shift;
00631                 fg[1] >>= image_filter_shift;
00632                 fg[2] >>= image_filter_shift;
00633 
00634                 if(fg[0] < 0) fg[0] = 0;
00635                 if(fg[1] < 0) fg[1] = 0;
00636                 if(fg[2] < 0) fg[2] = 0;
00637 
00638                 if(fg[order_type::R] > base_mask) fg[order_type::R] = base_mask;
00639                 if(fg[order_type::G] > base_mask) fg[order_type::G] = base_mask;
00640                 if(fg[order_type::B] > base_mask) fg[order_type::B] = base_mask;
00641 
00642                 span->r = (value_type)fg[order_type::R];
00643                 span->g = (value_type)fg[order_type::G];
00644                 span->b = (value_type)fg[order_type::B];
00645                 span->a = base_mask;
00646 
00647                 ++span;
00648                 ++base_type::interpolator();
00649 
00650             } while(--len);
00651         }
00652     };
00653 
00654 
00655 
00656     //==========================================span_image_resample_rgb_affine
00657     template<class Source> 
00658     class span_image_resample_rgb_affine : 
00659     public span_image_resample_affine<Source>
00660     {
00661     public:
00662         typedef Source source_type;
00663         typedef typename source_type::color_type color_type;
00664         typedef typename source_type::order_type order_type;
00665         typedef span_image_resample_affine<source_type> base_type;
00666         typedef typename base_type::interpolator_type interpolator_type;
00667         typedef typename color_type::value_type value_type;
00668         typedef typename color_type::long_type long_type;
00669         enum base_scale_e
00670         {
00671             base_shift      = color_type::base_shift,
00672             base_mask       = color_type::base_mask,
00673             downscale_shift = image_filter_shift
00674         };
00675 
00676         //--------------------------------------------------------------------
00677         span_image_resample_rgb_affine() {}
00678         span_image_resample_rgb_affine(source_type& src, 
00679                                        interpolator_type& inter,
00680                                        const image_filter_lut& filter) :
00681             base_type(src, inter, filter) 
00682         {}
00683 
00684 
00685         //--------------------------------------------------------------------
00686         void generate(color_type* span, int x, int y, unsigned len)
00687         {
00688             base_type::interpolator().begin(x + base_type::filter_dx_dbl(), 
00689                                             y + base_type::filter_dy_dbl(), len);
00690 
00691             long_type fg[3];
00692 
00693             int diameter     = base_type::filter().diameter();
00694             int filter_scale = diameter << image_subpixel_shift;
00695             int radius_x     = (diameter * base_type::m_rx) >> 1;
00696             int radius_y     = (diameter * base_type::m_ry) >> 1;
00697             int len_x_lr     = 
00698                 (diameter * base_type::m_rx + image_subpixel_mask) >> 
00699                     image_subpixel_shift;
00700 
00701             const int16* weight_array = base_type::filter().weight_array();
00702 
00703             do
00704             {
00705                 base_type::interpolator().coordinates(&x, &y);
00706 
00707                 x += base_type::filter_dx_int() - radius_x;
00708                 y += base_type::filter_dy_int() - radius_y;
00709 
00710                 fg[0] = fg[1] = fg[2] = image_filter_scale / 2;
00711 
00712                 int y_lr = y >> image_subpixel_shift;
00713                 int y_hr = ((image_subpixel_mask - (y & image_subpixel_mask)) * 
00714                                 base_type::m_ry_inv) >> 
00715                                     image_subpixel_shift;
00716                 int total_weight = 0;
00717                 int x_lr = x >> image_subpixel_shift;
00718                 int x_hr = ((image_subpixel_mask - (x & image_subpixel_mask)) * 
00719                                 base_type::m_rx_inv) >> 
00720                                     image_subpixel_shift;
00721 
00722                 int x_hr2 = x_hr;
00723                 const value_type* fg_ptr = 
00724                     (const value_type*)base_type::source().span(x_lr, y_lr, len_x_lr);
00725                 for(;;)
00726                 {
00727                     int weight_y = weight_array[y_hr];
00728                     x_hr = x_hr2;
00729                     for(;;)
00730                     {
00731                         int weight = (weight_y * weight_array[x_hr] + 
00732                                      image_filter_scale / 2) >> 
00733                                      downscale_shift;
00734 
00735                         fg[0] += *fg_ptr++ * weight;
00736                         fg[1] += *fg_ptr++ * weight;
00737                         fg[2] += *fg_ptr   * weight;
00738                         total_weight += weight;
00739                         x_hr  += base_type::m_rx_inv;
00740                         if(x_hr >= filter_scale) break;
00741                         fg_ptr = (const value_type*)base_type::source().next_x();
00742                     }
00743                     y_hr += base_type::m_ry_inv;
00744                     if(y_hr >= filter_scale) break;
00745                     fg_ptr = (const value_type*)base_type::source().next_y();
00746                 }
00747 
00748                 fg[0] /= total_weight;
00749                 fg[1] /= total_weight;
00750                 fg[2] /= total_weight;
00751 
00752                 if(fg[0] < 0) fg[0] = 0;
00753                 if(fg[1] < 0) fg[1] = 0;
00754                 if(fg[2] < 0) fg[2] = 0;
00755 
00756                 if(fg[order_type::R] > base_mask) fg[order_type::R] = base_mask;
00757                 if(fg[order_type::G] > base_mask) fg[order_type::G] = base_mask;
00758                 if(fg[order_type::B] > base_mask) fg[order_type::B] = base_mask;
00759 
00760                 span->r = (value_type)fg[order_type::R];
00761                 span->g = (value_type)fg[order_type::G];
00762                 span->b = (value_type)fg[order_type::B];
00763                 span->a = base_mask;
00764 
00765                 ++span;
00766                 ++base_type::interpolator();
00767             } while(--len);
00768         }
00769     };
00770 
00771 
00772 
00773     //=================================================span_image_resample_rgb
00774     template<class Source, class Interpolator>
00775     class span_image_resample_rgb : 
00776     public span_image_resample<Source, Interpolator>
00777     {
00778     public:
00779         typedef Source source_type;
00780         typedef typename source_type::color_type color_type;
00781         typedef typename source_type::order_type order_type;
00782         typedef Interpolator interpolator_type;
00783         typedef span_image_resample<source_type, interpolator_type> base_type;
00784         typedef typename color_type::value_type value_type;
00785         typedef typename color_type::long_type long_type;
00786         enum base_scale_e
00787         {
00788             base_shift = color_type::base_shift,
00789             base_mask  = color_type::base_mask,
00790             downscale_shift = image_filter_shift
00791         };
00792 
00793         //--------------------------------------------------------------------
00794         span_image_resample_rgb() {}
00795         span_image_resample_rgb(source_type& src, 
00796                                 interpolator_type& inter,
00797                                 const image_filter_lut& filter) :
00798             base_type(src, inter, filter)
00799         {}
00800 
00801         //--------------------------------------------------------------------
00802         void generate(color_type* span, int x, int y, unsigned len)
00803         {
00804             base_type::interpolator().begin(x + base_type::filter_dx_dbl(), 
00805                                             y + base_type::filter_dy_dbl(), len);
00806             long_type fg[3];
00807 
00808             int diameter = base_type::filter().diameter();
00809             int filter_scale = diameter << image_subpixel_shift;
00810 
00811             const int16* weight_array = base_type::filter().weight_array();
00812             do
00813             {
00814                 int rx;
00815                 int ry;
00816                 int rx_inv = image_subpixel_scale;
00817                 int ry_inv = image_subpixel_scale;
00818                 base_type::interpolator().coordinates(&x,  &y);
00819                 base_type::interpolator().local_scale(&rx, &ry);
00820                 base_type::adjust_scale(&rx, &ry);
00821 
00822                 rx_inv = image_subpixel_scale * image_subpixel_scale / rx;
00823                 ry_inv = image_subpixel_scale * image_subpixel_scale / ry;
00824 
00825                 int radius_x = (diameter * rx) >> 1;
00826                 int radius_y = (diameter * ry) >> 1;
00827                 int len_x_lr = 
00828                     (diameter * rx + image_subpixel_mask) >> 
00829                         image_subpixel_shift;
00830 
00831                 x += base_type::filter_dx_int() - radius_x;
00832                 y += base_type::filter_dy_int() - radius_y;
00833 
00834                 fg[0] = fg[1] = fg[2] = image_filter_scale / 2;
00835 
00836                 int y_lr = y >> image_subpixel_shift;
00837                 int y_hr = ((image_subpixel_mask - (y & image_subpixel_mask)) * 
00838                                ry_inv) >> 
00839                                    image_subpixel_shift;
00840                 int total_weight = 0;
00841                 int x_lr = x >> image_subpixel_shift;
00842                 int x_hr = ((image_subpixel_mask - (x & image_subpixel_mask)) * 
00843                                rx_inv) >> 
00844                                    image_subpixel_shift;
00845                 int x_hr2 = x_hr;
00846                 const value_type* fg_ptr = 
00847                     (const value_type*)base_type::source().span(x_lr, y_lr, len_x_lr);
00848 
00849                 for(;;)
00850                 {
00851                     int weight_y = weight_array[y_hr];
00852                     x_hr = x_hr2;
00853                     for(;;)
00854                     {
00855                         int weight = (weight_y * weight_array[x_hr] + 
00856                                      image_filter_scale / 2) >> 
00857                                      downscale_shift;
00858                         fg[0] += *fg_ptr++ * weight;
00859                         fg[1] += *fg_ptr++ * weight;
00860                         fg[2] += *fg_ptr   * weight;
00861                         total_weight += weight;
00862                         x_hr  += rx_inv;
00863                         if(x_hr >= filter_scale) break;
00864                         fg_ptr = (const value_type*)base_type::source().next_x();
00865                     }
00866                     y_hr += ry_inv;
00867                     if(y_hr >= filter_scale) break;
00868                     fg_ptr = (const value_type*)base_type::source().next_y();
00869                 }
00870 
00871                 fg[0] /= total_weight;
00872                 fg[1] /= total_weight;
00873                 fg[2] /= total_weight;
00874 
00875                 if(fg[0] < 0) fg[0] = 0;
00876                 if(fg[1] < 0) fg[1] = 0;
00877                 if(fg[2] < 0) fg[2] = 0;
00878 
00879                 if(fg[order_type::R] > base_mask) fg[order_type::R] = base_mask;
00880                 if(fg[order_type::G] > base_mask) fg[order_type::G] = base_mask;
00881                 if(fg[order_type::B] > base_mask) fg[order_type::B] = base_mask;
00882 
00883                 span->r = (value_type)fg[order_type::R];
00884                 span->g = (value_type)fg[order_type::G];
00885                 span->b = (value_type)fg[order_type::B];
00886                 span->a = base_mask;
00887 
00888                 ++span;
00889                 ++base_type::interpolator();
00890             } while(--len);
00891         }
00892     };
00893 
00894 
00895 }
00896 
00897 
00898 #endif
00899 
00900 
00901 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines