Anti-Grain Geometry - AGG (libagg)  2.5
agg-2.5/include/agg_span_image_filter_gray.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_GRAY_INCLUDED
00033 #define AGG_SPAN_IMAGE_FILTER_GRAY_INCLUDED
00034 
00035 #include "agg_basics.h"
00036 #include "agg_color_gray.h"
00037 #include "agg_span_image_filter.h"
00038 
00039 
00040 namespace agg
00041 {
00042 
00043     //==============================================span_image_filter_gray_nn
00044     template<class Source, class Interpolator> 
00045     class span_image_filter_gray_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 Interpolator interpolator_type;
00052         typedef span_image_filter<source_type, interpolator_type> base_type;
00053         typedef typename color_type::value_type value_type;
00054         typedef typename color_type::calc_type calc_type;
00055         enum base_scale_e
00056         {
00057             base_shift = color_type::base_shift,
00058             base_mask  = color_type::base_mask
00059         };
00060 
00061         //--------------------------------------------------------------------
00062         span_image_filter_gray_nn() {}
00063         span_image_filter_gray_nn(source_type& src, 
00064                                   interpolator_type& inter) :
00065             base_type(src, inter, 0) 
00066         {}
00067 
00068         //--------------------------------------------------------------------
00069         void generate(color_type* span, int x, int y, unsigned len)
00070         {
00071             base_type::interpolator().begin(x + base_type::filter_dx_dbl(), 
00072                                             y + base_type::filter_dy_dbl(), len);
00073             do
00074             {
00075                 base_type::interpolator().coordinates(&x, &y);
00076                 span->v = *(const value_type*)
00077                     base_type::source().span(x >> image_subpixel_shift, 
00078                                              y >> image_subpixel_shift, 
00079                                              1);
00080                 span->a = base_mask;
00081                 ++span;
00082                 ++base_type::interpolator();
00083             } while(--len);
00084         }
00085     };
00086 
00087 
00088 
00089     //=========================================span_image_filter_gray_bilinear
00090     template<class Source, class Interpolator> 
00091     class span_image_filter_gray_bilinear : 
00092     public span_image_filter<Source, Interpolator>
00093     {
00094     public:
00095         typedef Source source_type;
00096         typedef typename source_type::color_type color_type;
00097         typedef Interpolator interpolator_type;
00098         typedef span_image_filter<source_type, interpolator_type> base_type;
00099         typedef typename color_type::value_type value_type;
00100         typedef typename color_type::calc_type calc_type;
00101         enum base_scale_e
00102         {
00103             base_shift = color_type::base_shift,
00104             base_mask  = color_type::base_mask
00105         };
00106 
00107         //--------------------------------------------------------------------
00108         span_image_filter_gray_bilinear() {}
00109         span_image_filter_gray_bilinear(source_type& src, 
00110                                         interpolator_type& inter) :
00111             base_type(src, inter, 0) 
00112         {}
00113 
00114 
00115         //--------------------------------------------------------------------
00116         void generate(color_type* span, int x, int y, unsigned len)
00117         {
00118             base_type::interpolator().begin(x + base_type::filter_dx_dbl(), 
00119                                             y + base_type::filter_dy_dbl(), len);
00120             calc_type fg;
00121             const value_type *fg_ptr;
00122             do
00123             {
00124                 int x_hr;
00125                 int y_hr;
00126 
00127                 base_type::interpolator().coordinates(&x_hr, &y_hr);
00128 
00129                 x_hr -= base_type::filter_dx_int();
00130                 y_hr -= base_type::filter_dy_int();
00131 
00132                 int x_lr = x_hr >> image_subpixel_shift;
00133                 int y_lr = y_hr >> image_subpixel_shift;
00134 
00135                 fg = image_subpixel_scale * image_subpixel_scale / 2;
00136 
00137                 x_hr &= image_subpixel_mask;
00138                 y_hr &= image_subpixel_mask;
00139 
00140                 fg_ptr = (const value_type*)base_type::source().span(x_lr, y_lr, 2);
00141                 fg    += *fg_ptr * (image_subpixel_scale - x_hr) * (image_subpixel_scale - y_hr);
00142 
00143                 fg_ptr = (const value_type*)base_type::source().next_x();
00144                 fg    += *fg_ptr * x_hr * (image_subpixel_scale - y_hr);
00145 
00146                 fg_ptr = (const value_type*)base_type::source().next_y();
00147                 fg    += *fg_ptr * (image_subpixel_scale - x_hr) * y_hr;
00148 
00149                 fg_ptr = (const value_type*)base_type::source().next_x();
00150                 fg    += *fg_ptr * x_hr * y_hr;
00151 
00152                 span->v = value_type(fg >> (image_subpixel_shift * 2));
00153                 span->a = base_mask;
00154                 ++span;
00155                 ++base_type::interpolator();
00156 
00157             } while(--len);
00158         }
00159     };
00160 
00161 
00162     //====================================span_image_filter_gray_bilinear_clip
00163     template<class Source, class Interpolator> 
00164     class span_image_filter_gray_bilinear_clip : 
00165     public span_image_filter<Source, Interpolator>
00166     {
00167     public:
00168         typedef Source source_type;
00169         typedef typename source_type::color_type color_type;
00170         typedef Interpolator interpolator_type;
00171         typedef span_image_filter<source_type, interpolator_type> base_type;
00172         typedef typename color_type::value_type value_type;
00173         typedef typename color_type::calc_type calc_type;
00174         enum base_scale_e
00175         {
00176             base_shift = color_type::base_shift,
00177             base_mask  = color_type::base_mask
00178         };
00179 
00180         //--------------------------------------------------------------------
00181         span_image_filter_gray_bilinear_clip() {}
00182         span_image_filter_gray_bilinear_clip(source_type& src, 
00183                                              const color_type& back_color,
00184                                              interpolator_type& inter) :
00185             base_type(src, inter, 0), 
00186             m_back_color(back_color)
00187         {}
00188         const color_type& background_color() const { return m_back_color; }
00189         void background_color(const color_type& v)   { m_back_color = v; }
00190 
00191         //--------------------------------------------------------------------
00192         void generate(color_type* span, int x, int y, unsigned len)
00193         {
00194             base_type::interpolator().begin(x + base_type::filter_dx_dbl(), 
00195                                             y + base_type::filter_dy_dbl(), len);
00196             calc_type fg;
00197             calc_type src_alpha;
00198             value_type back_v = m_back_color.v;
00199             value_type back_a = m_back_color.a;
00200 
00201             const value_type *fg_ptr;
00202 
00203             int maxx = base_type::source().width() - 1;
00204             int maxy = base_type::source().height() - 1;
00205 
00206             do
00207             {
00208                 int x_hr;
00209                 int y_hr;
00210                 
00211                 base_type::interpolator().coordinates(&x_hr, &y_hr);
00212 
00213                 x_hr -= base_type::filter_dx_int();
00214                 y_hr -= base_type::filter_dy_int();
00215 
00216                 int x_lr = x_hr >> image_subpixel_shift;
00217                 int y_lr = y_hr >> image_subpixel_shift;
00218 
00219                 if(x_lr >= 0    && y_lr >= 0 &&
00220                    x_lr <  maxx && y_lr <  maxy) 
00221                 {
00222                     fg = image_subpixel_scale * image_subpixel_scale / 2;
00223 
00224                     x_hr &= image_subpixel_mask;
00225                     y_hr &= image_subpixel_mask;
00226                     fg_ptr = (const value_type*)base_type::source().row_ptr(y_lr) + x_lr;
00227 
00228                     fg += *fg_ptr++ * (image_subpixel_scale - x_hr) * (image_subpixel_scale - y_hr);
00229                     fg += *fg_ptr++ * (image_subpixel_scale - y_hr) * x_hr;
00230 
00231                     ++y_lr;
00232                     fg_ptr = (const value_type*)base_type::source().row_ptr(y_lr) + x_lr;
00233 
00234                     fg += *fg_ptr++ * (image_subpixel_scale - x_hr) * y_hr;
00235                     fg += *fg_ptr++ * x_hr * y_hr;
00236 
00237                     fg >>= image_subpixel_shift * 2;
00238                     src_alpha = base_mask;
00239                 }
00240                 else
00241                 {
00242                     unsigned weight;
00243                     if(x_lr < -1   || y_lr < -1 ||
00244                        x_lr > maxx || y_lr > maxy)
00245                     {
00246                         fg        = back_v;
00247                         src_alpha = back_a;
00248                     }
00249                     else
00250                     {
00251                         fg = 
00252                         src_alpha = image_subpixel_scale * image_subpixel_scale / 2;
00253 
00254                         x_hr &= image_subpixel_mask;
00255                         y_hr &= image_subpixel_mask;
00256 
00257                         weight = (image_subpixel_scale - x_hr) * 
00258                                  (image_subpixel_scale - y_hr);
00259                         if(x_lr >= 0    && y_lr >= 0 &&
00260                            x_lr <= maxx && y_lr <= maxy)
00261                         {
00262                             fg += weight * 
00263                                 *((const value_type*)base_type::source().row_ptr(y_lr) + x_lr);
00264                             src_alpha += weight * base_mask;
00265                         }
00266                         else
00267                         {
00268                             fg        += back_v * weight;
00269                             src_alpha += back_a * weight;
00270                         }
00271 
00272                         x_lr++;
00273 
00274                         weight = x_hr * (image_subpixel_scale - y_hr);
00275                         if(x_lr >= 0    && y_lr >= 0 &&
00276                            x_lr <= maxx && y_lr <= maxy)
00277                         {
00278                             fg += weight * 
00279                                 *((const value_type*)base_type::source().row_ptr(y_lr) + x_lr);
00280                             src_alpha += weight * base_mask;
00281                         }
00282                         else
00283                         {
00284                             fg        += back_v * weight;
00285                             src_alpha += back_a * weight;
00286                         }
00287 
00288                         x_lr--;
00289                         y_lr++;
00290 
00291                         weight = (image_subpixel_scale - x_hr) * y_hr;
00292                         if(x_lr >= 0    && y_lr >= 0 &&
00293                            x_lr <= maxx && y_lr <= maxy)
00294                         {
00295                             fg += weight * 
00296                                 *((const value_type*)base_type::source().row_ptr(y_lr) + x_lr);
00297                             src_alpha += weight * base_mask;
00298                         }
00299                         else
00300                         {
00301                             fg        += back_v * weight;
00302                             src_alpha += back_a * weight;
00303                         }
00304 
00305                         x_lr++;
00306 
00307                         weight = x_hr * y_hr;
00308                         if(x_lr >= 0    && y_lr >= 0 &&
00309                            x_lr <= maxx && y_lr <= maxy)
00310                         {
00311                             fg += weight * 
00312                                 *((const value_type*)base_type::source().row_ptr(y_lr) + x_lr);
00313                             src_alpha += weight * base_mask;
00314                         }
00315                         else
00316                         {
00317                             fg        += back_v * weight;
00318                             src_alpha += back_a * weight;
00319                         }
00320 
00321                         fg        >>= image_subpixel_shift * 2;
00322                         src_alpha >>= image_subpixel_shift * 2;
00323                     }
00324                 }
00325 
00326                 span->v = (value_type)fg;
00327                 span->a = (value_type)src_alpha;
00328                 ++span;
00329                 ++base_type::interpolator();
00330 
00331             } while(--len);
00332         }
00333     private:
00334         color_type m_back_color;
00335     };
00336 
00337 
00338 
00339     //==============================================span_image_filter_gray_2x2
00340     template<class Source, class Interpolator> 
00341     class span_image_filter_gray_2x2 : 
00342     public span_image_filter<Source, Interpolator>
00343     {
00344     public:
00345         typedef Source source_type;
00346         typedef typename source_type::color_type color_type;
00347         typedef Interpolator interpolator_type;
00348         typedef span_image_filter<source_type, interpolator_type> base_type;
00349         typedef typename color_type::value_type value_type;
00350         typedef typename color_type::calc_type calc_type;
00351         enum base_scale_e
00352         {
00353             base_shift = color_type::base_shift,
00354             base_mask  = color_type::base_mask
00355         };
00356 
00357         //--------------------------------------------------------------------
00358         span_image_filter_gray_2x2() {}
00359         span_image_filter_gray_2x2(source_type& src, 
00360                                    interpolator_type& inter,
00361                                    const image_filter_lut& filter) :
00362             base_type(src, inter, &filter) 
00363         {}
00364 
00365 
00366         //--------------------------------------------------------------------
00367         void generate(color_type* span, int x, int y, unsigned len)
00368         {
00369             base_type::interpolator().begin(x + base_type::filter_dx_dbl(), 
00370                                             y + base_type::filter_dy_dbl(), len);
00371 
00372             calc_type fg;
00373 
00374             const value_type *fg_ptr;
00375             const int16* weight_array = base_type::filter().weight_array() + 
00376                                         ((base_type::filter().diameter()/2 - 1) << 
00377                                           image_subpixel_shift);
00378             do
00379             {
00380                 int x_hr;
00381                 int y_hr;
00382 
00383                 base_type::interpolator().coordinates(&x_hr, &y_hr);
00384 
00385                 x_hr -= base_type::filter_dx_int();
00386                 y_hr -= base_type::filter_dy_int();
00387 
00388                 int x_lr = x_hr >> image_subpixel_shift;
00389                 int y_lr = y_hr >> image_subpixel_shift;
00390 
00391                 unsigned weight;
00392                 fg = image_filter_scale / 2;
00393 
00394                 x_hr &= image_subpixel_mask;
00395                 y_hr &= image_subpixel_mask;
00396 
00397                 fg_ptr = (const value_type*)base_type::source().span(x_lr, y_lr, 2);
00398                 weight = (weight_array[x_hr + image_subpixel_scale] * 
00399                           weight_array[y_hr + image_subpixel_scale] + 
00400                           image_filter_scale / 2) >> 
00401                           image_filter_shift;
00402                 fg += weight * *fg_ptr;
00403 
00404                 fg_ptr = (const value_type*)base_type::source().next_x();
00405                 weight = (weight_array[x_hr] * 
00406                           weight_array[y_hr + image_subpixel_scale] + 
00407                           image_filter_scale / 2) >> 
00408                           image_filter_shift;
00409                 fg += weight * *fg_ptr;
00410 
00411                 fg_ptr = (const value_type*)base_type::source().next_y();
00412                 weight = (weight_array[x_hr + image_subpixel_scale] * 
00413                           weight_array[y_hr] + 
00414                           image_filter_scale / 2) >> 
00415                           image_filter_shift;
00416                 fg += weight * *fg_ptr;
00417 
00418                 fg_ptr = (const value_type*)base_type::source().next_x();
00419                 weight = (weight_array[x_hr] * 
00420                           weight_array[y_hr] + 
00421                           image_filter_scale / 2) >> 
00422                           image_filter_shift;
00423                 fg += weight * *fg_ptr;
00424 
00425                 fg >>= image_filter_shift;
00426                 if(fg > base_mask) fg = base_mask;
00427 
00428                 span->v = (value_type)fg;
00429                 span->a = base_mask;
00430                 ++span;
00431                 ++base_type::interpolator();
00432             } while(--len);
00433         }
00434     };
00435 
00436 
00437 
00438     //==================================================span_image_filter_gray
00439     template<class Source, class Interpolator> 
00440     class span_image_filter_gray : 
00441     public span_image_filter<Source, Interpolator>
00442     {
00443     public:
00444         typedef Source source_type;
00445         typedef typename source_type::color_type color_type;
00446         typedef Interpolator interpolator_type;
00447         typedef span_image_filter<source_type, interpolator_type> base_type;
00448         typedef typename color_type::value_type value_type;
00449         typedef typename color_type::calc_type calc_type;
00450         enum base_scale_e
00451         {
00452             base_shift = color_type::base_shift,
00453             base_mask  = color_type::base_mask
00454         };
00455 
00456         //--------------------------------------------------------------------
00457         span_image_filter_gray() {}
00458         span_image_filter_gray(source_type& src, 
00459                                interpolator_type& inter,
00460                                const image_filter_lut& filter) :
00461             base_type(src, inter, &filter) 
00462         {}
00463 
00464         //--------------------------------------------------------------------
00465         void generate(color_type* span, int x, int y, unsigned len)
00466         {
00467             base_type::interpolator().begin(x + base_type::filter_dx_dbl(), 
00468                                             y + base_type::filter_dy_dbl(), len);
00469 
00470             int fg;
00471             const value_type *fg_ptr;
00472 
00473             unsigned     diameter     = base_type::filter().diameter();
00474             int          start        = base_type::filter().start();
00475             const int16* weight_array = base_type::filter().weight_array();
00476 
00477             int x_count; 
00478             int weight_y;
00479 
00480             do
00481             {
00482                 base_type::interpolator().coordinates(&x, &y);
00483 
00484                 x -= base_type::filter_dx_int();
00485                 y -= base_type::filter_dy_int();
00486 
00487                 int x_hr = x; 
00488                 int y_hr = y; 
00489 
00490                 int x_lr = x_hr >> image_subpixel_shift;
00491                 int y_lr = y_hr >> image_subpixel_shift;
00492 
00493                 fg = image_filter_scale / 2;
00494 
00495                 int x_fract = x_hr & image_subpixel_mask;
00496                 unsigned y_count = diameter;
00497 
00498                 y_hr = image_subpixel_mask - (y_hr & image_subpixel_mask);
00499                 fg_ptr = (const value_type*)base_type::source().span(x_lr + start, 
00500                                                                      y_lr + start, 
00501                                                                      diameter);
00502                 for(;;)
00503                 {
00504                     x_count  = diameter;
00505                     weight_y = weight_array[y_hr];
00506                     x_hr = image_subpixel_mask - x_fract;
00507                     for(;;)
00508                     {
00509                         fg += *fg_ptr * 
00510                               ((weight_y * weight_array[x_hr] + 
00511                                 image_filter_scale / 2) >> 
00512                                 image_filter_shift);
00513                         if(--x_count == 0) break;
00514                         x_hr  += image_subpixel_scale;
00515                         fg_ptr = (const value_type*)base_type::source().next_x();
00516                     }
00517 
00518                     if(--y_count == 0) break;
00519                     y_hr  += image_subpixel_scale;
00520                     fg_ptr = (const value_type*)base_type::source().next_y();
00521                 }
00522 
00523                 fg >>= image_filter_shift;
00524                 if(fg < 0) fg = 0;
00525                 if(fg > base_mask) fg = base_mask;
00526                 span->v = (value_type)fg;
00527                 span->a = base_mask;
00528 
00529                 ++span;
00530                 ++base_type::interpolator();
00531 
00532             } while(--len);
00533         }
00534     };
00535 
00536 
00537 
00538     //=========================================span_image_resample_gray_affine
00539     template<class Source> 
00540     class span_image_resample_gray_affine : 
00541     public span_image_resample_affine<Source>
00542     {
00543     public:
00544         typedef Source source_type;
00545         typedef typename source_type::color_type color_type;
00546         typedef span_image_resample_affine<source_type> base_type;
00547         typedef typename base_type::interpolator_type interpolator_type;
00548         typedef typename color_type::value_type value_type;
00549         typedef typename color_type::long_type long_type;
00550         enum base_scale_e
00551         {
00552             base_shift      = color_type::base_shift,
00553             base_mask       = color_type::base_mask,
00554             downscale_shift = image_filter_shift
00555         };
00556 
00557         //--------------------------------------------------------------------
00558         span_image_resample_gray_affine() {}
00559         span_image_resample_gray_affine(source_type& src, 
00560                                         interpolator_type& inter,
00561                                         const image_filter_lut& filter) :
00562             base_type(src, inter, filter) 
00563         {}
00564 
00565 
00566         //--------------------------------------------------------------------
00567         void generate(color_type* span, int x, int y, unsigned len)
00568         {
00569             base_type::interpolator().begin(x + base_type::filter_dx_dbl(), 
00570                                             y + base_type::filter_dy_dbl(), len);
00571 
00572             long_type fg;
00573 
00574             int diameter     = base_type::filter().diameter();
00575             int filter_scale = diameter << image_subpixel_shift;
00576             int radius_x     = (diameter * base_type::m_rx) >> 1;
00577             int radius_y     = (diameter * base_type::m_ry) >> 1;
00578             int len_x_lr     = 
00579                 (diameter * base_type::m_rx + image_subpixel_mask) >> 
00580                     image_subpixel_shift;
00581 
00582             const int16* weight_array = base_type::filter().weight_array();
00583 
00584             do
00585             {
00586                 base_type::interpolator().coordinates(&x, &y);
00587 
00588                 x += base_type::filter_dx_int() - radius_x;
00589                 y += base_type::filter_dy_int() - radius_y;
00590 
00591                 fg = image_filter_scale / 2;
00592 
00593                 int y_lr = y >> image_subpixel_shift;
00594                 int y_hr = ((image_subpixel_mask - (y & image_subpixel_mask)) * 
00595                                 base_type::m_ry_inv) >> 
00596                                     image_subpixel_shift;
00597                 int total_weight = 0;
00598                 int x_lr = x >> image_subpixel_shift;
00599                 int x_hr = ((image_subpixel_mask - (x & image_subpixel_mask)) * 
00600                                 base_type::m_rx_inv) >> 
00601                                     image_subpixel_shift;
00602 
00603                 int x_hr2 = x_hr;
00604                 const value_type* fg_ptr = 
00605                     (const value_type*)base_type::source().span(x_lr, y_lr, len_x_lr);
00606                 for(;;)
00607                 {
00608                     int weight_y = weight_array[y_hr];
00609                     x_hr = x_hr2;
00610                     for(;;)
00611                     {
00612                         int weight = (weight_y * weight_array[x_hr] + 
00613                                      image_filter_scale / 2) >> 
00614                                      downscale_shift;
00615 
00616                         fg += *fg_ptr * weight;
00617                         total_weight += weight;
00618                         x_hr  += base_type::m_rx_inv;
00619                         if(x_hr >= filter_scale) break;
00620                         fg_ptr = (const value_type*)base_type::source().next_x();
00621                     }
00622                     y_hr += base_type::m_ry_inv;
00623                     if(y_hr >= filter_scale) break;
00624                     fg_ptr = (const value_type*)base_type::source().next_y();
00625                 }
00626 
00627                 fg /= total_weight;
00628                 if(fg < 0) fg = 0;
00629                 if(fg > base_mask) fg = base_mask;
00630 
00631                 span->v = (value_type)fg;
00632                 span->a = base_mask;
00633 
00634                 ++span;
00635                 ++base_type::interpolator();
00636             } while(--len);
00637         }
00638     };
00639 
00640 
00641 
00642     //================================================span_image_resample_gray
00643     template<class Source, class Interpolator>
00644     class span_image_resample_gray : 
00645     public span_image_resample<Source, Interpolator>
00646     {
00647     public:
00648         typedef Source source_type;
00649         typedef typename source_type::color_type color_type;
00650         typedef Interpolator interpolator_type;
00651         typedef span_image_resample<source_type, interpolator_type> base_type;
00652         typedef typename color_type::value_type value_type;
00653         typedef typename color_type::long_type long_type;
00654         enum base_scale_e
00655         {
00656             base_shift = color_type::base_shift,
00657             base_mask  = color_type::base_mask,
00658             downscale_shift = image_filter_shift
00659         };
00660 
00661         //--------------------------------------------------------------------
00662         span_image_resample_gray() {}
00663         span_image_resample_gray(source_type& src, 
00664                                  interpolator_type& inter,
00665                                  const image_filter_lut& filter) :
00666             base_type(src, inter, filter)
00667         {}
00668 
00669         //--------------------------------------------------------------------
00670         void generate(color_type* span, int x, int y, unsigned len)
00671         {
00672             base_type::interpolator().begin(x + base_type::filter_dx_dbl(), 
00673                                             y + base_type::filter_dy_dbl(), len);
00674             long_type fg;
00675 
00676             int diameter = base_type::filter().diameter();
00677             int filter_scale = diameter << image_subpixel_shift;
00678 
00679             const int16* weight_array = base_type::filter().weight_array();
00680             do
00681             {
00682                 int rx;
00683                 int ry;
00684                 int rx_inv = image_subpixel_scale;
00685                 int ry_inv = image_subpixel_scale;
00686                 base_type::interpolator().coordinates(&x,  &y);
00687                 base_type::interpolator().local_scale(&rx, &ry);
00688                 base_type::adjust_scale(&rx, &ry);
00689 
00690                 rx_inv = image_subpixel_scale * image_subpixel_scale / rx;
00691                 ry_inv = image_subpixel_scale * image_subpixel_scale / ry;
00692 
00693                 int radius_x = (diameter * rx) >> 1;
00694                 int radius_y = (diameter * ry) >> 1;
00695                 int len_x_lr = 
00696                     (diameter * rx + image_subpixel_mask) >> 
00697                         image_subpixel_shift;
00698 
00699                 x += base_type::filter_dx_int() - radius_x;
00700                 y += base_type::filter_dy_int() - radius_y;
00701 
00702                 fg = image_filter_scale / 2;
00703 
00704                 int y_lr = y >> image_subpixel_shift;
00705                 int y_hr = ((image_subpixel_mask - (y & image_subpixel_mask)) * 
00706                                ry_inv) >> 
00707                                    image_subpixel_shift;
00708                 int total_weight = 0;
00709                 int x_lr = x >> image_subpixel_shift;
00710                 int x_hr = ((image_subpixel_mask - (x & image_subpixel_mask)) * 
00711                                rx_inv) >> 
00712                                    image_subpixel_shift;
00713                 int x_hr2 = x_hr;
00714                 const value_type* fg_ptr = 
00715                     (const value_type*)base_type::source().span(x_lr, y_lr, len_x_lr);
00716 
00717                 for(;;)
00718                 {
00719                     int weight_y = weight_array[y_hr];
00720                     x_hr = x_hr2;
00721                     for(;;)
00722                     {
00723                         int weight = (weight_y * weight_array[x_hr] + 
00724                                      image_filter_scale / 2) >> 
00725                                      downscale_shift;
00726                         fg += *fg_ptr * weight;
00727                         total_weight += weight;
00728                         x_hr  += rx_inv;
00729                         if(x_hr >= filter_scale) break;
00730                         fg_ptr = (const value_type*)base_type::source().next_x();
00731                     }
00732                     y_hr += ry_inv;
00733                     if(y_hr >= filter_scale) break;
00734                     fg_ptr = (const value_type*)base_type::source().next_y();
00735                 }
00736 
00737                 fg /= total_weight;
00738                 if(fg < 0) fg = 0;
00739                 if(fg > base_mask) fg = base_mask;
00740 
00741                 span->v = (value_type)fg;
00742                 span->a = base_mask;
00743 
00744                 ++span;
00745                 ++base_type::interpolator();
00746             } while(--len);
00747         }
00748     };
00749 
00750 
00751 }
00752 
00753 
00754 #endif
00755 
00756 
00757 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines