c_integer_math_ops.c

Go to the documentation of this file.
00001 /*!@file Image/c_integer_math_ops.c Fixed-point integer math versions of some of our floating-point Image functions */
00002 
00003 // //////////////////////////////////////////////////////////////////// //
00004 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2000-2005   //
00005 // by the University of Southern California (USC) and the iLab at USC.  //
00006 // See http://iLab.usc.edu for information about this project.          //
00007 // //////////////////////////////////////////////////////////////////// //
00008 // Major portions of the iLab Neuromorphic Vision Toolkit are protected //
00009 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency //
00010 // in Visual Environments, and Applications'' by Christof Koch and      //
00011 // Laurent Itti, California Institute of Technology, 2001 (patent       //
00012 // pending; application number 09/912,225 filed July 23, 2001; see      //
00013 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status).     //
00014 // //////////////////////////////////////////////////////////////////// //
00015 // This file is part of the iLab Neuromorphic Vision C++ Toolkit.       //
00016 //                                                                      //
00017 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can   //
00018 // redistribute it and/or modify it under the terms of the GNU General  //
00019 // Public License as published by the Free Software Foundation; either  //
00020 // version 2 of the License, or (at your option) any later version.     //
00021 //                                                                      //
00022 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope  //
00023 // that it will be useful, but WITHOUT ANY WARRANTY; without even the   //
00024 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      //
00025 // PURPOSE.  See the GNU General Public License for more details.       //
00026 //                                                                      //
00027 // You should have received a copy of the GNU General Public License    //
00028 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write   //
00029 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,   //
00030 // Boston, MA 02111-1307 USA.                                           //
00031 // //////////////////////////////////////////////////////////////////// //
00032 //
00033 // Primary maintainer for this file: Rob Peters <rjpeters at usc dot edu>
00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Image/c_integer_math_ops.c $
00035 // $Id: c_integer_math_ops.c 7848 2007-02-07 17:46:06Z rjpeters $
00036 //
00037 
00038 #ifndef IMAGE_C_INTEGER_MATH_OPS_C_DEFINED
00039 #define IMAGE_C_INTEGER_MATH_OPS_C_DEFINED
00040 
00041 #include "Image/c_integer_math_ops.h"
00042 
00043 #include "Util/Assert.H"
00044 
00045 // ######################################################################
00046 void c_intg_low_pass_5_x_dec_x_manybits(const int* src,
00047                                          const int w, const int h,
00048                                          int* dst,
00049                                          const int w2)
00050 {
00051   if (w == 2) //////////////////////////////////////////////////
00052     for (int j = 0; j < h; ++j)
00053       {
00054         // leftmost point  [ (6^) 4 ] / 10
00055         *dst++ = (src[0] / 10) * 6 + (src[1] / 10) * 4;
00056 
00057         src += 2;  // src back to same position as dst
00058       }
00059   else if (w == 3) //////////////////////////////////////////////////
00060     for (int j = 0; j < h; ++j)
00061       {
00062         // need the left most point in any case
00063         // leftmost point  [ (6^) 4 1 ] / 11
00064         *dst++ =
00065           (src[0] / 11) * 6 +
00066           (src[1] / 11) * 4 +
00067           (src[2] / 11) * 1;
00068 
00069         src += 3;  // src back to same position as dst
00070       }
00071   else  ////////////////////////////// general case for width() >= 4
00072         // *** unfolded version (all particular cases treated) for
00073         // max speed.
00074         // notations: in () is the position of dest ptr, and ^ is src ptr
00075         // ########## horizontal pass
00076     for (int j = 0; j < h; ++j)
00077       {
00078         int i1 = 0, i2 = 0;
00079         const int* src2 = src;
00080 
00081         // leftmost point  [ (6^) 4 1 ] / 11
00082         *dst++ =
00083           (src2[0] / 11) * 6 +
00084           (src2[1] / 11) * 4 +
00085           (src2[2] / 11) * 1;
00086         ++i2;
00087         i1 += 2;
00088 
00089         // skip second point
00090 
00091         // rest of the line except last 2 points  [ 1^ 4 (6) 4 1 ] / 16.0
00092         while ((i1 < (w-2)) && (i2 < w2))
00093           {
00094             *dst++ =
00095               ((src2[0] >> 4) + (src2[4] >> 4)) * 1 +
00096               ((src2[1] >> 4) + (src2[3] >> 4)) * 4 +
00097               (src2[2] >> 4) * 6;
00098             i1 += 2; src2 += 2;
00099             ++i2;
00100           }
00101 
00102         // need special case for second to last point?
00103         if ((i2 < w2) && (i1 == (w-2)))
00104           {
00105             src2 = src + w - 4;
00106             // before last point [ 1^ 4 (6) 4 ] / 15
00107             *dst++ =
00108               (src2[0] / 15) * 1 +
00109               (src2[1] / 15 + src2[3] / 15) * 4 +
00110               (src2[2] / 15) * 6;
00111             i1 += 2;
00112             ++i2;
00113           }
00114 
00115         // need special case for last point?
00116         if ((i2 < w2) && (i1 == (w-1)))
00117           {
00118             src2 = src + w - 3;
00119             // last point [ 1^ 4 (6) ] / 11
00120             *dst++ =
00121               (src2[0] / 11) * 1 +
00122               (src2[1] / 11) * 4 +
00123               (src2[2] / 11) * 6;
00124             ++i2;
00125           }
00126         src += w;
00127       }
00128 }
00129 
00130 // ######################################################################
00131 void c_intg_low_pass_5_y_dec_y_manybits(const int* src,
00132                                          const int w, const int h,
00133                                          int* dst,
00134                                          const int h2)
00135 {
00136   const int* const src_end = src + w*h;
00137 
00138   // ########## vertical pass  (even though we scan horiz for speedup)
00139   const int w2 = w * 2, w3 = w * 3, w4 = w * 4; // speedup
00140 
00141   if (h == 2) //////////////////////////////////////////////////
00142     {
00143       // topmost points  ( [ (6^) 4 ] / 10 )^T
00144       for (int i = 0; i < w; ++i)
00145         {
00146           *dst++ =
00147             (src[0] / 10) * 6 +
00148             (src[w] / 10) * 4;
00149           src++;
00150         }
00151       src -= w;  // go back to top-left
00152     }
00153   else if (h == 3) //////////////////////////////////////////////////
00154     {
00155       // topmost points  ( [ (6^) 4 1 ] / 11 )^T
00156       for (int i = 0; i < w; ++i)
00157         {
00158           *dst++ =
00159             (src[ 0] / 11) * 6 +
00160             (src[ w] / 11) * 4 +
00161             (src[w2] / 11) * 1;
00162           src++;
00163         }
00164       src -= w;  // go back to top-left
00165     }
00166   else  ///////////////////////////////// general case for height >= 4
00167     {
00168       int i1 = 0, i2 = 0;
00169 
00170       // topmost points  ( [ (6^) 4 1 ] / 11 )^T
00171       for (int i = 0; i < w; ++i)
00172         {
00173           *dst++ =
00174             (src[ 0] / 11) * 6 +
00175             (src[ w] / 11) * 4 +
00176             (src[w2] / 11) * 1;
00177           src++;
00178         }
00179       src -= w;  // go back to top-left
00180       ++i2;
00181       i1 += 2;
00182 
00183       // second point skipped
00184 
00185       // rest of the column except last 2 points ( [ 1^ 4 (6) 4 1 ] / 16 )T
00186       while ((i1 < (h-2)) && (i2 < h2))
00187         {
00188           for (int i = 0; i < w; ++i)
00189             {
00190               *dst++ =
00191                 ((src[ 0] >> 4) + (src[w4] >> 4)) * 1 +
00192                 ((src[ w] >> 4) + (src[w3] >> 4)) * 4 +
00193                 (src[w2] >> 4) * 6;
00194               src++;
00195             }
00196           src += w;
00197           i1 += 2;
00198           ++ i2;
00199         }
00200 
00201       // need special case for second to last point?
00202       if ((i2 < h2) && (i1 == (h-2)))
00203         {
00204           src = src_end - w4;
00205           // before last points ( [ 1^ 4 (6) 4 ] / 15 )T
00206           for (int i = 0; i < w; ++i)
00207             {
00208               *dst++ =
00209                 (src[ 0] / 15) * 1 +
00210                 (src[ w] / 15 + src[w3] / 15) * 4 +
00211                 (src[w2] / 15) * 6;
00212               src++;
00213             }
00214           i1 += 2;
00215           ++i2;
00216         }
00217 
00218       // need special case for last point?
00219       if ((i2 < h2) && (i1 == (h-1)))
00220         {
00221           src = src_end - w3;
00222           // last points ( [ 1^ 4 (6) ] / 11 )T
00223           for (int i = 0; i < w; ++i)
00224             {
00225               *dst++ =
00226                 (src[ 0] / 11) * 1 +
00227                 (src[ w] / 11) * 4 +
00228                 (src[w2] / 11) * 6;
00229               src++;
00230             }
00231         }
00232     }
00233 }
00234 
00235 // ######################################################################
00236 void c_intg_low_pass_5_x_dec_x_fewbits(const int* src,
00237                                          const int w, const int h,
00238                                          int* dst,
00239                                          const int w2)
00240 {
00241   if (w == 2) //////////////////////////////////////////////////
00242     for (int j = 0; j < h; ++j)
00243       {
00244         // leftmost point  [ (6^) 4 ] / 10
00245         *dst++ =
00246           (src[0] * 6 +
00247            src[1] * 4
00248            ) / 10;
00249 
00250         src += 2;  // src back to same position as dst
00251       }
00252   else if (w == 3) //////////////////////////////////////////////////
00253     for (int j = 0; j < h; ++j)
00254       {
00255         // need the left most point in any case
00256         // leftmost point  [ (6^) 4 1 ] / 11
00257         *dst++ =
00258           (src[0] * 6 +
00259            src[1] * 4 +
00260            src[2] * 1
00261            ) / 11;
00262 
00263         src += 3;  // src back to same position as dst
00264       }
00265   else  ////////////////////////////// general case for width() >= 4
00266         // *** unfolded version (all particular cases treated) for
00267         // max speed.
00268         // notations: in () is the position of dest ptr, and ^ is src ptr
00269         // ########## horizontal pass
00270     for (int j = 0; j < h; ++j)
00271       {
00272         int i1 = 0, i2 = 0;
00273         const int* src2 = src;
00274 
00275         // leftmost point  [ (6^) 4 1 ] / 11
00276         *dst++ =
00277           (src2[0] * 6 +
00278            src2[1] * 4 +
00279            src2[2] * 1
00280            ) / 11;
00281         ++i2;
00282         i1 += 2;
00283 
00284         // skip second point
00285 
00286         // rest of the line except last 2 points  [ 1^ 4 (6) 4 1 ] / 16.0
00287         while ((i1 < (w-2)) && (i2 < w2))
00288           {
00289             *dst++ =
00290               ((src2[0] + src2[4]) * 1 +
00291                (src2[1] + src2[3]) * 4 +
00292                src2[2] * 6
00293                ) >> 4;
00294             i1 += 2; src2 += 2;
00295             ++i2;
00296           }
00297 
00298         // need special case for second to last point?
00299         if ((i2 < w2) && (i1 == (w-2)))
00300           {
00301             src2 = src + w - 4;
00302             // before last point [ 1^ 4 (6) 4 ] / 15
00303             *dst++ =
00304               (src2[0] * 1 +
00305                (src2[1] + src2[3]) * 4 +
00306                src2[2] * 6
00307                ) / 15;
00308             i1 += 2;
00309             ++i2;
00310           }
00311 
00312         // need special case for last point?
00313         if ((i2 < w2) && (i1 == (w-1)))
00314           {
00315             src2 = src + w - 3;
00316             // last point [ 1^ 4 (6) ] / 11
00317             *dst++ =
00318               (src2[0] * 1 +
00319                src2[1] * 4 +
00320                src2[2] * 6
00321                ) / 11;
00322             ++i2;
00323           }
00324         src += w;
00325       }
00326 }
00327 
00328 // ######################################################################
00329 void c_intg_low_pass_5_y_dec_y_fewbits(const int* src,
00330                                          const int w, const int h,
00331                                          int* dst,
00332                                          const int h2)
00333 {
00334   const int* const src_end = src + w*h;
00335 
00336   // ########## vertical pass  (even though we scan horiz for speedup)
00337   const int w2 = w * 2, w3 = w * 3, w4 = w * 4; // speedup
00338 
00339   if (h == 2) //////////////////////////////////////////////////
00340     {
00341       // topmost points  ( [ (6^) 4 ] / 10 )^T
00342       for (int i = 0; i < w; ++i)
00343         {
00344           *dst++ =
00345             (src[0] * 6 +
00346              src[w] * 4
00347              ) / 10;
00348           src++;
00349         }
00350       src -= w;  // go back to top-left
00351     }
00352   else if (h == 3) //////////////////////////////////////////////////
00353     {
00354       // topmost points  ( [ (6^) 4 1 ] / 11 )^T
00355       for (int i = 0; i < w; ++i)
00356         {
00357           *dst++ =
00358             (src[ 0] * 6 +
00359              src[ w] * 4 +
00360              src[w2] * 1
00361              ) / 11;
00362           src++;
00363         }
00364       src -= w;  // go back to top-left
00365     }
00366   else  ///////////////////////////////// general case for height >= 4
00367     {
00368       int i1 = 0, i2 = 0;
00369 
00370       // topmost points  ( [ (6^) 4 1 ] / 11 )^T
00371       for (int i = 0; i < w; ++i)
00372         {
00373           *dst++ =
00374             (src[ 0] * 6 +
00375              src[ w] * 4 +
00376              src[w2] * 1
00377              ) / 11;
00378           src++;
00379         }
00380       src -= w;  // go back to top-left
00381       ++i2;
00382       i1 += 2;
00383 
00384       // second point skipped
00385 
00386       // rest of the column except last 2 points ( [ 1^ 4 (6) 4 1 ] / 16 )T
00387       while ((i1 < (h-2)) && (i2 < h2))
00388         {
00389           for (int i = 0; i < w; ++i)
00390             {
00391               *dst++ =
00392                 ((src[ 0] + src[w4]) * 1 +
00393                  (src[ w] + src[w3]) * 4 +
00394                  src[w2] * 6
00395                  ) >> 4;
00396               src++;
00397             }
00398           src += w;
00399           i1 += 2;
00400           ++ i2;
00401         }
00402 
00403       // need special case for second to last point?
00404       if ((i2 < h2) && (i1 == (h-2)))
00405         {
00406           src = src_end - w4;
00407           // before last points ( [ 1^ 4 (6) 4 ] / 15 )T
00408           for (int i = 0; i < w; ++i)
00409             {
00410               *dst++ =
00411                 (src[ 0] * 1 +
00412                  (src[ w] + src[w3]) * 4 +
00413                  src[w2] * 6
00414                  ) / 15;
00415               src++;
00416             }
00417           i1 += 2;
00418           ++i2;
00419         }
00420 
00421       // need special case for last point?
00422       if ((i2 < h2) && (i1 == (h-1)))
00423         {
00424           src = src_end - w3;
00425           // last points ( [ 1^ 4 (6) ] / 11 )T
00426           for (int i = 0; i < w; ++i)
00427             {
00428               *dst++ =
00429                 (src[ 0] * 1 +
00430                  src[ w] * 4 +
00431                  src[w2] * 6
00432                  ) / 11;
00433               src++;
00434             }
00435         }
00436     }
00437 }
00438 
00439 #define LP5_APPROX_LEVEL 0
00440 
00441 #if LP5_APPROX_LEVEL == 0
00442 
00443 #  define LP5_APPROX_2_3 2
00444 #  define LP5_APPROX_1_3 1
00445 #  define LP5_DIV_3              / 3
00446 
00447 #elif LP5_APPROX_LEVEL == 1
00448 
00449 #  define LP5_APPROX_2_3 1
00450 #  define LP5_APPROX_1_3 1
00451 #  define LP5_DIV_3              / 2
00452 
00453 #else
00454 #error bogus LP5_APPROX_LEVEL (must be 0 or 1)
00455 #endif
00456 
00457 // ######################################################################
00458 void c_intg_low_pass_5_x_dec_x_fewbits_optim(const int* src,
00459                                          const int w, const int h,
00460                                          int* dst,
00461                                          const int w2)
00462 {
00463   ASSERT(w2 == w/2);
00464 
00465   if (w == 2) //////////////////////////////////////////////////
00466     for (int j = 0; j < h; ++j)
00467       {
00468         // leftmost point  [ (6^) 4 ] / 10
00469         *dst++ =
00470           (src[0] * 3 +
00471            src[1] * 2
00472            ) / 5;
00473 
00474         src += 2;  // src back to same position as dst
00475       }
00476   else if (w == 3) //////////////////////////////////////////////////
00477     for (int j = 0; j < h; ++j)
00478       {
00479         // need the left most point in any case
00480         // leftmost point  [ (6^) 4 1 ] / 11
00481         *dst++ =
00482           (src[0] * 6 +
00483            src[1] * 4 +
00484            src[2] * 1
00485            ) / 11;
00486 
00487         src += 3;  // src back to same position as dst
00488       }
00489   else  ////////////////////////////// general case for width() >= 4
00490         // *** unfolded version (all particular cases treated) for
00491         // max speed.
00492         // notations: in () is the position of dest ptr, and ^ is src ptr
00493         // ########## horizontal pass
00494     for (int j = 0; j < h; ++j)
00495       {
00496         const int* src2 = src;
00497 
00498         // leftmost point  [ (8^) 4 ] / 12
00499         *dst++ =
00500           (src2[0] * LP5_APPROX_2_3 +
00501            src2[1] * LP5_APPROX_1_3
00502            ) LP5_DIV_3;
00503 
00504         // skip second point
00505 
00506         // rest of the line except last 2 points  [ .^ 4 (8) 4 ] / 16
00507         for (int i = 0; i < w-3; i += 2)
00508           {
00509             *dst++ =
00510               ((src2[1] + src2[3]) +
00511                src2[2] * 2
00512                ) >> 2;
00513             src2 += 2;
00514           }
00515 
00516         src += w;
00517       }
00518 }
00519 
00520 // ######################################################################
00521 void c_intg_low_pass_5_y_dec_y_fewbits_optim(const int* src,
00522                                          const int w, const int h,
00523                                          int* dst,
00524                                          const int h2)
00525 {
00526   ASSERT(h2 == h/2);
00527 
00528   // ########## vertical pass  (even though we scan horiz for speedup)
00529   const int w2 = w * 2, w3 = w * 3; // speedup
00530 
00531   if (h == 2) //////////////////////////////////////////////////
00532     {
00533       // topmost points  ( [ (6^) 4 ] / 10 )^T
00534       for (int i = 0; i < w; ++i)
00535         {
00536           *dst++ =
00537             (src[0] * 3 +
00538              src[w] * 2
00539              ) / 5;
00540           src++;
00541         }
00542       src -= w;  // go back to top-left
00543     }
00544   else if (h == 3) //////////////////////////////////////////////////
00545     {
00546       // topmost points  ( [ (6^) 4 1 ] / 11 )^T
00547       for (int i = 0; i < w; ++i)
00548         {
00549           *dst++ =
00550             (src[ 0] * 6 +
00551              src[ w] * 4 +
00552              src[w2] * 1
00553              ) / 11;
00554           src++;
00555         }
00556       src -= w;  // go back to top-left
00557     }
00558   else  ///////////////////////////////// general case for height >= 4
00559     {
00560       // topmost points  ( [ (8^) 4 ] / 12 )^T
00561       for (int k = 0; k < w; ++k)
00562         {
00563           *dst++ =
00564             (src[ 0] * LP5_APPROX_2_3 +
00565              src[ w] * LP5_APPROX_1_3
00566              ) LP5_DIV_3;
00567           src++;
00568         }
00569       src -= w;  // go back to top-left
00570 
00571       // second point skipped
00572 
00573       // rest of the column except last 2 points ( [ .^ 4 (8) 4 ] / 16 )T
00574       for (int i = 0; i < h-3; i += 2)
00575         {
00576           for (int k = 0; k < w; ++k)
00577             {
00578               *dst++ =
00579                 ((src[ w] + src[w3]) +
00580                  src[w2] * 2
00581                  ) >> 2;
00582               src++;
00583             }
00584           src += w;
00585         }
00586     }
00587 }
00588 
00589 // ######################################################################
00590 void c_intg_low_pass_9_x_manybits(const int* src,
00591                                    const int w, const int h,
00592                                    int* dst)
00593 {
00594   ASSERT(w >= 9);
00595 
00596   // boundary conditions: truncated filter
00597   for (int j = 0; j < h; ++j)
00598     {
00599       // leftmost points
00600       *dst++ =
00601         (src[0] / 163) * 70 +
00602         (src[1] / 163) * 56 +
00603         (src[2] / 163) * 28 +
00604         (src[3] / 163) *  8 +
00605         (src[4] / 163) *  1;
00606       *dst++ =
00607         (src[0] / 219 + src[2] / 219) * 56 +
00608         (src[1] / 219) * 70 +
00609         (src[3] / 219) * 28 +
00610         (src[4] / 219) *  8 +
00611         (src[5] / 219) *  1;
00612       *dst++ =
00613         (src[0] / 247 + src[4] / 247) * 28 +
00614         (src[1] / 247 + src[3] / 247) * 56 +
00615         (src[2] / 247) * 70 +
00616         (src[5] / 247) *  8 +
00617         (src[6] / 247) *  1;
00618       *dst++ =
00619         (src[0] / 255 + src[6] / 255) *  8 +
00620         (src[1] / 255 + src[5] / 255) * 28 +
00621         (src[2] / 255 + src[4] / 255) * 56 +
00622         (src[3] / 255) * 70 +
00623         (src[7] / 255) *  1;
00624 
00625       // far from the borders
00626       for (int i = 0; i < w - 8; ++i)
00627         {
00628           *dst++ =
00629             ((src[0] >> 8) + (src[8] >> 8)) *  1 +
00630             ((src[1] >> 8) + (src[7] >> 8)) *  8 +
00631             ((src[2] >> 8) + (src[6] >> 8)) * 28 +
00632             ((src[3] >> 8) + (src[5] >> 8)) * 56 +
00633             (src[4] >> 8) * 70;
00634           ++src;
00635         }
00636 
00637       // rightmost points
00638       *dst++ =
00639         (src[0] / 255) *  1 +
00640         (src[1] / 255 + src[7] / 255) *  8 +
00641         (src[2] / 255 + src[6] / 255) * 28 +
00642         (src[3] / 255 + src[5] / 255) * 56 +
00643         (src[4] / 255) * 70;
00644       ++src;
00645       *dst++ =
00646         (src[0] / 247) *  1 +
00647         (src[1] / 247) *  8 +
00648         (src[2] / 247 + src[6] / 247) * 28 +
00649         (src[3] / 247 + src[5] / 247) * 56 +
00650         (src[4] / 247) * 70;
00651       ++src;
00652       *dst++ =
00653         (src[0] / 219) *  1 +
00654         (src[1] / 219) *  8 +
00655         (src[2] / 219) * 28 +
00656         (src[3] / 219 + src[5] / 219) * 56 +
00657         (src[4] / 219) * 70;
00658       ++src;
00659       *dst++ =
00660         (src[0] / 163) *  1 +
00661         (src[1] / 163) *  8 +
00662         (src[2] / 163) * 28 +
00663         (src[3] / 163) * 56 +
00664         (src[4] / 163) * 70;
00665       src += 5;  // src back to same as dst (start of next line)
00666     }
00667 }
00668 
00669 // ######################################################################
00670 void c_intg_low_pass_9_y_manybits(const int* src,
00671                                    const int w, const int h,
00672                                    int* dst)
00673 {
00674   ASSERT(h >= 9);
00675 
00676   // *** vertical pass ***
00677   const int w2 = w + w, w3 = w2 + w, w4 = w3 + w, w5 = w4 + w, w6 = w5 + w,
00678     w7 = w6 + w,  w8 = w7 + w;  // index computation speedup
00679   for (int i = 0; i < w; ++i)
00680     {
00681       *dst++ =
00682         (src[ 0] / 163) * 70 +
00683         (src[ w] / 163) * 56 +
00684         (src[w2] / 163) * 28 +
00685         (src[w3] / 163) *  8 +
00686         (src[w4] / 163) *  1;
00687       ++src;
00688     }
00689   src -= w; // back to top-left
00690   for (int i = 0; i < w; ++i)
00691     {
00692       *dst++ =
00693         (src[ 0] / 219 + src[w2] / 219) * 56 +
00694         (src[ w] / 219) * 70 +
00695         (src[w3] / 219) * 28 +
00696         (src[w4] / 219) *  8 +
00697         (src[w5] / 219) *  1;
00698       ++src;
00699     }
00700   src -= w; // back to top-left
00701   for (int i = 0; i < w; ++i)
00702     {
00703       *dst++ =
00704         (src[ 0] / 247 + src[w4] / 247) * 28 +
00705         (src[ w] / 247 + src[w3] / 247) * 56 +
00706         (src[w2] / 247) * 70 +
00707         (src[w5] / 247) *  8 +
00708         (src[w6] / 247) *  1;
00709       ++src;
00710     }
00711   src -= w; // back to top-left
00712   for (int i = 0; i < w; ++i)
00713     {
00714       *dst++ =
00715         (src[ 0] / 255 + src[w6] / 255) *  8 +
00716         (src[ w] / 255 + src[w5] / 255) * 28 +
00717         (src[w2] / 255 + src[w4] / 255) * 56 +
00718         (src[w3] / 255) * 70 +
00719         (src[w7] / 255) *  1;
00720       ++src;
00721     }
00722   src -= w;   // back to top-left
00723   for (int j = 0; j < h - 8; j ++)
00724     for (int i = 0; i < w; ++i)
00725       {
00726         *dst++ =
00727           ((src[ 0] >> 8) + (src[w8] >> 8)) *  1 +
00728           ((src[ w] >> 8) + (src[w7] >> 8)) *  8 +
00729           ((src[w2] >> 8) + (src[w6] >> 8)) * 28 +
00730           ((src[w3] >> 8) + (src[w5] >> 8)) * 56 +
00731           (src[w4] >> 8)  * 70;
00732         ++src;
00733       }
00734   for (int i = 0; i < w; ++i)
00735     {
00736       *dst++ =
00737         (src[ 0] / 255) *  1 +
00738         (src[ w] / 255 + src[w7] / 255) *  8 +
00739         (src[w2] / 255 + src[w6] / 255) * 28 +
00740         (src[w3] / 255 + src[w5] / 255) * 56 +
00741         (src[w4] / 255) * 70;
00742       ++src;
00743     }
00744   for (int i = 0; i < w; ++i)
00745     {
00746       *dst++ =
00747         (src[ 0] / 247) *  1 +
00748         (src[ w] / 247) *  8 +
00749         (src[w2] / 247 + src[w6] / 247) * 28 +
00750         (src[w3] / 247 + src[w5] / 247) * 56 +
00751         (src[w4] / 247) * 70;
00752       ++src;
00753     }
00754   for (int i = 0; i < w; ++i)
00755     {
00756       *dst++ =
00757         (src[ 0] / 219) *  1 +
00758         (src[ w] / 219) *  8 +
00759         (src[w2] / 219) * 28 +
00760         (src[w3] / 219 + src[w5] / 219) * 56 +
00761         (src[w4] / 219) * 70;
00762       ++src;
00763     }
00764   for (int i = 0; i < w; ++i)
00765     {
00766       *dst++ =
00767         (src[ 0] / 163) *  1 +
00768         (src[ w] / 163) *  8 +
00769         (src[w2] / 163) * 28 +
00770         (src[w3] / 163) * 56 +
00771         (src[w4] / 163) * 70;
00772       ++src;
00773     }
00774 }
00775 
00776 // ######################################################################
00777 void c_intg_low_pass_9_x_fewbits(const int* src,
00778                                    const int w, const int h,
00779                                    int* dst)
00780 {
00781   ASSERT(w >= 9);
00782 
00783   // boundary conditions: truncated filter
00784   for (int j = 0; j < h; ++j)
00785     {
00786       // leftmost points
00787       *dst++ =
00788         (src[0] * 70 +
00789          src[1] * 56 +
00790          src[2] * 28 +
00791          src[3] *  8 +
00792          src[4] *  1
00793          ) / 163;
00794       *dst++ =
00795         ((src[0] + src[2]) * 56 +
00796          src[1] * 70 +
00797          src[3] * 28 +
00798          src[4] *  8 +
00799          src[5] *  1
00800          ) / 219;
00801       *dst++ =
00802         ((src[0] + src[4]) * 28 +
00803          (src[1] + src[3]) * 56 +
00804          src[2] * 70 +
00805          src[5] *  8 +
00806          src[6] *  1
00807          ) / 247;
00808       *dst++ =
00809         ((src[0] + src[6]) *  8 +
00810          (src[1] + src[5]) * 28 +
00811          (src[2] + src[4]) * 56 +
00812          src[3] * 70 +
00813          src[7] *  1
00814          ) / 255;
00815 
00816       // far from the borders
00817       for (int i = 0; i < w - 8; ++i)
00818         {
00819           *dst++ =
00820             ((src[0] + src[8]) *  1 +
00821              (src[1] + src[7]) *  8 +
00822              (src[2] + src[6]) * 28 +
00823              (src[3] + src[5]) * 56 +
00824              src[4] * 70
00825              ) >> 8;
00826           ++src;
00827         }
00828 
00829       // rightmost points
00830       *dst++ =
00831         (src[0] *  1 +
00832          (src[1] + src[7]) *  8 +
00833          (src[2] + src[6]) * 28 +
00834          (src[3] + src[5]) * 56 +
00835          src[4] * 70
00836          ) / 255;
00837       ++src;
00838       *dst++ =
00839         (src[0] *  1 +
00840          src[1] *  8 +
00841          (src[2] + src[6]) * 28 +
00842          (src[3] + src[5]) * 56 +
00843          src[4] * 70
00844          ) / 247;
00845       ++src;
00846       *dst++ =
00847         (src[0] *  1 +
00848          src[1] *  8 +
00849          src[2] * 28 +
00850          (src[3] + src[5]) * 56 +
00851          src[4] * 70
00852          ) / 219;
00853       ++src;
00854       *dst++ =
00855         (src[0] *  1 +
00856          src[1] *  8 +
00857          src[2] * 28 +
00858          src[3] * 56 +
00859          src[4] * 70
00860          ) / 163;
00861       src += 5;  // src back to same as dst (start of next line)
00862     }
00863 }
00864 
00865 // ######################################################################
00866 void c_intg_low_pass_9_y_fewbits(const int* src,
00867                                    const int w, const int h,
00868                                    int* dst)
00869 {
00870   ASSERT(h >= 9);
00871 
00872   // *** vertical pass ***
00873   const int w2 = w + w, w3 = w2 + w, w4 = w3 + w, w5 = w4 + w, w6 = w5 + w,
00874     w7 = w6 + w,  w8 = w7 + w;  // index computation speedup
00875   for (int i = 0; i < w; ++i)
00876     {
00877       *dst++ =
00878         (src[ 0] * 70 +
00879          src[ w] * 56 +
00880          src[w2] * 28 +
00881          src[w3] *  8 +
00882          src[w4] *  1
00883          ) / 163;
00884       ++src;
00885     }
00886   src -= w; // back to top-left
00887   for (int i = 0; i < w; ++i)
00888     {
00889       *dst++ =
00890         ((src[ 0] + src[w2]) * 56 +
00891          src[ w] * 70 +
00892          src[w3] * 28 +
00893          src[w4] *  8 +
00894          src[w5] *  1
00895          ) / 219;
00896       ++src;
00897     }
00898   src -= w; // back to top-left
00899   for (int i = 0; i < w; ++i)
00900     {
00901       *dst++ =
00902         ((src[ 0] + src[w4]) * 28 +
00903          (src[ w] + src[w3]) * 56 +
00904          src[w2] * 70 +
00905          src[w5] *  8 +
00906          src[w6] *  1
00907          ) / 247;
00908       ++src;
00909     }
00910   src -= w; // back to top-left
00911   for (int i = 0; i < w; ++i)
00912     {
00913       *dst++ =
00914         ((src[ 0] + src[w6]) *  8 +
00915          (src[ w] + src[w5]) * 28 +
00916          (src[w2] + src[w4]) * 56 +
00917          src[w3] * 70 +
00918          src[w7] *  1
00919          ) / 255;
00920       ++src;
00921     }
00922   src -= w;   // back to top-left
00923   for (int j = 0; j < h - 8; j ++)
00924     for (int i = 0; i < w; ++i)
00925       {
00926         *dst++ =
00927           ((src[ 0] + src[w8]) *  1 +
00928            (src[ w] + src[w7]) *  8 +
00929            (src[w2] + src[w6]) * 28 +
00930            (src[w3] + src[w5]) * 56 +
00931            src[w4]  * 70
00932            ) >> 8;
00933         ++src;
00934       }
00935   for (int i = 0; i < w; ++i)
00936     {
00937       *dst++ =
00938         (src[ 0] *  1 +
00939          (src[ w] + src[w7]) *  8 +
00940          (src[w2] + src[w6]) * 28 +
00941          (src[w3] + src[w5]) * 56 +
00942          src[w4] * 70
00943          ) / 255;
00944       ++src;
00945     }
00946   for (int i = 0; i < w; ++i)
00947     {
00948       *dst++ =
00949         (src[ 0] *  1 +
00950          src[ w] *  8 +
00951          (src[w2] + src[w6]) * 28 +
00952          (src[w3] + src[w5]) * 56 +
00953          src[w4] * 70
00954          ) / 247;
00955       ++src;
00956     }
00957   for (int i = 0; i < w; ++i)
00958     {
00959       *dst++ =
00960         (src[ 0] *  1 +
00961          src[ w] *  8 +
00962          src[w2] * 28 +
00963          (src[w3] + src[w5]) * 56 +
00964          src[w4] * 70
00965          ) / 219;
00966       ++src;
00967     }
00968   for (int i = 0; i < w; ++i)
00969     {
00970       *dst++ =
00971         (src[ 0] *  1 +
00972          src[ w] *  8 +
00973          src[w2] * 28 +
00974          src[w3] * 56 +
00975          src[w4] * 70
00976          ) / 163;
00977       ++src;
00978     }
00979 }
00980 
00981 #define LP9_APPROX_LEVEL 0
00982 
00983 #if LP9_APPROX_LEVEL == 0
00984 
00985 #  define LP9_APPROX_72_164  72
00986 #  define LP9_APPROX_56_164  56
00987 #  define LP9_APPROX_28_164  28
00988 #  define LP9_APPROX_8_164   8
00989 #  define LP9_DIV_164            / 164
00990 
00991 #  define LP9_APPROX_72_220  72
00992 #  define LP9_APPROX_56_220  56
00993 #  define LP9_APPROX_28_220  28
00994 #  define LP9_APPROX_8_220   8
00995 #  define LP9_DIV_220            / 220
00996 
00997 #  define LP9_APPROX_72_248  72
00998 #  define LP9_APPROX_56_248  56
00999 #  define LP9_APPROX_28_248  28
01000 #  define LP9_APPROX_8_248   8
01001 #  define LP9_DIV_248            / 248
01002 
01003 #elif LP9_APPROX_LEVEL == 1
01004 
01005 #  define LP9_APPROX_72_164  28
01006 #  define LP9_APPROX_56_164  22
01007 #  define LP9_APPROX_28_164  11
01008 #  define LP9_APPROX_8_164    3
01009 #  define LP9_DIV_164             >> 6
01010 
01011 #  define LP9_APPROX_72_220  22
01012 #  define LP9_APPROX_56_220  16
01013 #  define LP9_APPROX_28_220   8
01014 #  define LP9_APPROX_8_220    2
01015 #  define LP9_DIV_220             >> 6
01016 
01017 #  define LP9_APPROX_72_248  20
01018 #  define LP9_APPROX_56_248  14
01019 #  define LP9_APPROX_28_248   7
01020 #  define LP9_APPROX_8_248    2
01021 #  define LP9_DIV_248             >> 6
01022 
01023 #elif LP9_APPROX_LEVEL == 2
01024 
01025 #  define LP9_APPROX_72_164  8
01026 #  define LP9_APPROX_56_164  (4+1)
01027 #  define LP9_APPROX_28_164  2
01028 #  define LP9_APPROX_8_164   1
01029 #  define LP9_DIV_164             >> 4
01030 
01031 #  define LP9_APPROX_72_220  (4+1)
01032 #  define LP9_APPROX_56_220  4
01033 #  define LP9_APPROX_28_220  2
01034 #  define LP9_APPROX_8_220   1
01035 #  define LP9_DIV_220             >> 4
01036 
01037 #  define LP9_APPROX_72_248  (4+1)
01038 #  define LP9_APPROX_56_248  3
01039 #  define LP9_APPROX_28_248  2
01040 #  define LP9_APPROX_8_248   1
01041 #  define LP9_DIV_248             >> 4
01042 
01043 #elif LP9_APPROX_LEVEL == 3
01044 
01045 #  define LP9_APPROX_72_164  0
01046 #  define LP9_APPROX_56_164  0
01047 #  define LP9_APPROX_28_164  0
01048 #  define LP9_APPROX_8_164   0
01049 #  define LP9_DIV_164
01050 
01051 #  define LP9_APPROX_72_220  0
01052 #  define LP9_APPROX_56_220  0
01053 #  define LP9_APPROX_28_220  0
01054 #  define LP9_APPROX_8_220   0
01055 #  define LP9_DIV_220
01056 
01057 #  define LP9_APPROX_72_248  0
01058 #  define LP9_APPROX_56_248  0
01059 #  define LP9_APPROX_28_248  0
01060 #  define LP9_APPROX_8_248   0
01061 #  define LP9_DIV_248
01062 
01063 #  define LP9_APPROX_SHIFTR  0
01064 
01065 #else
01066 #error bogus LP9_APPROX_LEVEL (must be 0, 1, 2, or 3)
01067 #endif
01068 
01069 // ######################################################################
01070 void c_intg_low_pass_9_x_fewbits_optim(const int* src,
01071                                    const int w, const int h,
01072                                    int* dst)
01073 {
01074   ASSERT(w >= 9);
01075 
01076   // boundary conditions: truncated filter
01077   for (int j = 0; j < h; ++j)
01078     {
01079       // leftmost points
01080       *dst++ =                  // [ (72^) 56 28 8 ]
01081         (src[0] * LP9_APPROX_72_164 +
01082          src[1] * LP9_APPROX_56_164 +
01083          src[2] * LP9_APPROX_28_164 +
01084          src[3] * LP9_APPROX_8_164
01085          ) LP9_DIV_164;
01086       *dst++ =                  // [ 56^ (72) 56 28 8 ]
01087         ((src[0] + src[2]) * LP9_APPROX_56_220 +
01088          src[1] * LP9_APPROX_72_220 +
01089          src[3] * LP9_APPROX_28_220 +
01090          src[4] * LP9_APPROX_8_220
01091          ) LP9_DIV_220;
01092       *dst++ =                  // [ 28^ 56 (72) 56 28 8 ]
01093         ((src[0] + src[4]) * LP9_APPROX_28_248 +
01094          (src[1] + src[3]) * LP9_APPROX_56_248 +
01095          src[2] * LP9_APPROX_72_248 +
01096          src[5] * LP9_APPROX_8_248
01097          ) LP9_DIV_248;
01098 
01099       // far from the borders
01100       for (int i = 0; i < w - 6; ++i)
01101         {
01102           *dst++ =              // [ 8^ 28 56 (72) 56 28 8 ]
01103             ((src[0] + src[6]) *  8 +
01104              (src[1] + src[5]) * 28 +
01105              (src[2] + src[4]) * 56 +
01106              src[3] * 72
01107              ) >> 8;
01108           ++src;
01109         }
01110 
01111       // rightmost points
01112       *dst++ =                  // [ 8^ 28 56 (72) 56 28 ]
01113         (src[0] *  LP9_APPROX_8_248 +
01114          (src[1] + src[5]) * LP9_APPROX_28_248 +
01115          (src[2] + src[4]) * LP9_APPROX_56_248 +
01116          src[3] * LP9_APPROX_72_248
01117          ) LP9_DIV_248;
01118       ++src;
01119       *dst++ =                  // [ 8^ 28 56 (72) 56 ]
01120         (src[0] * LP9_APPROX_8_220 +
01121          src[1] * LP9_APPROX_28_220 +
01122          (src[2] + src[4]) * LP9_APPROX_56_220 +
01123          src[3] * LP9_APPROX_72_220
01124          ) LP9_DIV_220;
01125       ++src;
01126       *dst++ =                  // [ 8^ 28 56 (72) ]
01127         (src[0] * LP9_APPROX_8_164 +
01128          src[1] * LP9_APPROX_28_164 +
01129          src[2] * LP9_APPROX_56_164 +
01130          src[3] * LP9_APPROX_72_164
01131          ) LP9_DIV_164;
01132       src += 4;  // src back to same as dst (start of next line)
01133     }
01134 }
01135 
01136 // ######################################################################
01137 void c_intg_low_pass_9_y_fewbits_optim(const int* src,
01138                                    const int w, const int h,
01139                                    int* dst)
01140 {
01141   ASSERT(h >= 9);
01142 
01143   // index computation speedup:
01144   const int w2 = w + w, w3 = w2 + w, w4 = w3 + w, w5 = w4 + w, w6 = w5 + w;
01145 
01146   // *** vertical pass ***
01147   for (int i = 0; i < w; ++i)
01148     {
01149       *dst++ =
01150         (src[ 0] * LP9_APPROX_72_164 +
01151          src[ w] * LP9_APPROX_56_164 +
01152          src[w2] * LP9_APPROX_28_164 +
01153          src[w3] * LP9_APPROX_8_164
01154          ) LP9_DIV_164;
01155       ++src;
01156     }
01157   src -= w; // back to top-left
01158   for (int i = 0; i < w; ++i)
01159     {
01160       *dst++ =
01161         ((src[ 0] + src[w2]) * LP9_APPROX_56_220 +
01162          src[ w] * LP9_APPROX_72_220 +
01163          src[w3] * LP9_APPROX_28_220 +
01164          src[w4] * LP9_APPROX_8_220
01165          ) LP9_DIV_220;
01166       ++src;
01167     }
01168   src -= w; // back to top-left
01169   for (int i = 0; i < w; ++i)
01170     {
01171       *dst++ =
01172         ((src[ 0] + src[w4]) * LP9_APPROX_28_248 +
01173          (src[ w] + src[w3]) * LP9_APPROX_56_248 +
01174          src[w2] * LP9_APPROX_72_248 +
01175          src[w5] * LP9_APPROX_8_248
01176          ) LP9_DIV_248;
01177       ++src;
01178     }
01179   src -= w; // back to top-left
01180 
01181   for (int j = 0; j < h - 6; j ++)
01182     for (int i = 0; i < w; ++i)
01183       {
01184         *dst++ =
01185           ((src[ 0] + src[w6]) *  8 +
01186            (src[ w] + src[w5]) * 28 +
01187            (src[w2] + src[w4]) * 56 +
01188            src[w3]  * 72
01189            ) >> 8;
01190         ++src;
01191       }
01192 
01193   for (int i = 0; i < w; ++i)
01194     {
01195       *dst++ =
01196         (src[ 0] * LP9_APPROX_8_248 +
01197          (src[ w] + src[w5]) * LP9_APPROX_28_248 +
01198          (src[w2] + src[w4]) * LP9_APPROX_56_248 +
01199          src[w3] * LP9_APPROX_72_248
01200          ) LP9_DIV_248;
01201       ++src;
01202     }
01203   for (int i = 0; i < w; ++i)
01204     {
01205       *dst++ =
01206         (src[ 0] * LP9_APPROX_8_220 +
01207          src[ w] * LP9_APPROX_28_220 +
01208          (src[w2] + src[w4]) * LP9_APPROX_56_220 +
01209          src[w3] * LP9_APPROX_72_220
01210          ) LP9_DIV_220;
01211       ++src;
01212     }
01213   for (int i = 0; i < w; ++i)
01214     {
01215       *dst++ =
01216         (src[ 0] * LP9_APPROX_8_164 +
01217          src[ w] * LP9_APPROX_28_164 +
01218          src[w2] * LP9_APPROX_56_164 +
01219          src[w3] * LP9_APPROX_72_164
01220          ) LP9_DIV_164;
01221       ++src;
01222     }
01223 }
01224 
01225 // ######################################################################
01226 void c_intg_x_filter_clean_manybits(const int* src,
01227                                      const int w, const int h,
01228                                      const int* hf_flipped, const int hfs,
01229                                      const int shiftbits,
01230                                      int* dst)
01231 {
01232   ASSERT(w >= hfs);
01233   ASSERT(hfs > 0);
01234 
01235   ASSERT(hfs & 1);
01236   const int hfs2 = (hfs - 1) / 2;
01237 
01238   for (int jj = 0; jj < h; ++jj)
01239     {
01240       // leftmost points:
01241       for (int j = hfs2; j < hfs - 1; ++j)
01242         {
01243           const int fp = hfs - 1 - j;
01244           int sum = 0;
01245           for (int k = 0; k <= j; k ++)
01246             sum += hf_flipped[fp + k];
01247 
01248           int val = 0;
01249           for (int k = 0; k <= j; k ++)
01250             val += (src[k] / sum) * hf_flipped[fp + k];
01251 
01252           *dst++ = val;
01253         }
01254 
01255       // bulk (far from the borders):
01256       for (int i = 0; i < w - hfs + 1; ++i)
01257         {
01258           int val = 0;
01259           for (int k = 0; k < hfs; k ++)
01260             val += (src[k] >> shiftbits) * hf_flipped[k];
01261           *dst++ = val;
01262           src++;
01263         }
01264 
01265       // rightmost points:
01266       for (int j = hfs - 2; j >= hfs2; j --)
01267         {
01268           int sum = 0;
01269           for (int k = 0; k <= j; k ++)
01270             sum += hf_flipped[k];
01271 
01272           int val = 0;
01273           for (int k = 0; k <= j; k ++)
01274             val += (src[k] / sum) * hf_flipped[k];
01275 
01276           *dst++ = val;
01277           src++;
01278         }
01279       src += hfs2;  // src back to same as dst (start of next line)
01280     }
01281 }
01282 
01283 // ######################################################################
01284 void c_intg_x_filter_clean_fewbits(const int* src,
01285                                      const int w, const int h,
01286                                      const int* hf_flipped, const int hfs,
01287                                      const int shiftbits,
01288                                      int* dst)
01289 {
01290   ASSERT(w >= hfs);
01291   ASSERT(hfs > 0);
01292 
01293   ASSERT(hfs & 1);
01294   const int hfs2 = (hfs - 1) / 2;
01295 
01296   for (int jj = 0; jj < h; ++jj)
01297     {
01298       // leftmost points:
01299       for (int j = hfs2; j < hfs - 1; ++j)
01300         {
01301           const int fp = hfs - 1 - j;
01302           int sum = 0;
01303           int val = 0;
01304           for (int k = 0; k <= j; k ++)
01305             {
01306               val += src[k] * hf_flipped[fp + k];
01307               sum += hf_flipped[fp + k];
01308             }
01309 
01310           *dst++ = val / sum;
01311         }
01312 
01313       // bulk (far from the borders):
01314       for (int i = 0; i < w - hfs + 1; ++i)
01315         {
01316           int val = 0;
01317           for (int k = 0; k < hfs; k ++)
01318             val += src[k] * hf_flipped[k];
01319           *dst++ = (val >> shiftbits);
01320           src++;
01321         }
01322 
01323       // rightmost points:
01324       for (int j = hfs - 2; j >= hfs2; j --)
01325         {
01326           int sum = 0;
01327           int val = 0;
01328           for (int k = 0; k <= j; k ++)
01329             {
01330               val += src[k] * hf_flipped[k];
01331               sum += hf_flipped[k];
01332             }
01333 
01334           *dst++ = val / sum;
01335           src++;
01336         }
01337       src += hfs2;  // src back to same as dst (start of next line)
01338     }
01339 }
01340 
01341 // ######################################################################
01342 void c_intg_x_filter_clean_small_manybits(const int* src,
01343                                            const int w, const int h,
01344                                            const int* hf_flipped, const int hfs,
01345                                            const int shiftbits,
01346                                            int* dst)
01347 {
01348   ASSERT(w < hfs);
01349   ASSERT(hfs > 0);
01350 
01351   ASSERT(hfs & 1);
01352   const int hfs2 = (hfs - 1) / 2;
01353 
01354   for (int j = 0; j < h; ++j)
01355     for (int i = 0; i < w; ++i)
01356       {
01357         int sum = 0;
01358         for (int k = 0; k < hfs; k ++)
01359           if (i + k - hfs2 >= 0 && i + k - hfs2 < w)
01360             sum += hf_flipped[k];
01361 
01362         int val = 0;
01363         for (int k = 0; k < hfs; k ++)
01364           if (i + k - hfs2 >= 0 && i + k - hfs2 < w)
01365             val += (src[k - hfs2] / sum) * hf_flipped[k];
01366 
01367         *dst++ = val;
01368         src ++;
01369       }
01370 }
01371 
01372 // ######################################################################
01373 void c_intg_x_filter_clean_small_fewbits(const int* src,
01374                                            const int w, const int h,
01375                                            const int* hf_flipped, const int hfs,
01376                                            const int shiftbits,
01377                                            int* dst)
01378 {
01379   ASSERT(w < hfs);
01380   ASSERT(hfs > 0);
01381 
01382   ASSERT(hfs & 1);
01383   const int hfs2 = (hfs - 1) / 2;
01384 
01385   for (int j = 0; j < h; ++j)
01386     for (int i = 0; i < w; ++i)
01387       {
01388         int sum = 0;
01389         int val = 0;
01390         for (int k = 0; k < hfs; k ++)
01391           if (i + k - hfs2 >= 0 && i + k - hfs2 < w)
01392             {
01393               val += src[k - hfs2] * hf_flipped[k];
01394               sum += hf_flipped[k];
01395             }
01396 
01397         *dst++ = val / sum;
01398         src ++;
01399       }
01400 }
01401 
01402 // ######################################################################
01403 void c_intg_y_filter_clean_manybits(const int* src,
01404                                      const int w, const int h,
01405                                      const int* vf_flipped, const int vfs,
01406                                      const int shiftbits,
01407                                      int* dst)
01408 {
01409   ASSERT(h >= vfs);
01410   ASSERT(vfs > 0);
01411 
01412   ASSERT(vfs & 1);
01413   const int vfs2 = (vfs - 1) / 2;
01414 
01415   int ww[vfs]; // precompute row offsets
01416   for (int x = 0; x < vfs; x ++)
01417     ww[x] = w * x;
01418 
01419   // top points:
01420   for (int j = vfs2; j < vfs - 1; ++j)
01421     {
01422       int fp = vfs - 1 - j;
01423       for (int i = 0; i < w; ++i)  // scan all points of given horiz
01424         {
01425           int sum = 0;
01426           for (int k = 0; k <= j; k ++)
01427             sum += vf_flipped[fp + k];
01428 
01429           int val = 0;
01430           for (int k = 0; k <= j; k ++)
01431             val += (src[ww[k]] / sum) * vf_flipped[fp + k];
01432 
01433           *dst++ = val;
01434           src++;
01435         }
01436       src -= w;   // back to top-left corner
01437     }
01438 
01439   // bulk (far from edges):
01440   for (int j = 0; j < h - vfs + 1; ++j)
01441     for (int i = 0; i < w; ++i)
01442       {
01443         int val = 0;
01444         for (int k = 0; k < vfs; k ++)
01445           val += (src[ww[k]] >> shiftbits) * vf_flipped[k];
01446         *dst++ = val;
01447         src++;
01448       }
01449 
01450   // bottommost points:
01451   for (int j = vfs - 2; j >= vfs2; j --)
01452     for (int i = 0; i < w; ++i)
01453       {
01454         int sum = 0;
01455         for (int k = 0; k <= j; k ++)
01456           sum += vf_flipped[k];
01457 
01458         int val = 0;
01459         for (int k = 0; k <= j; k ++)
01460           val += (src[ww[k]] / sum) * vf_flipped[k];
01461 
01462         *dst++ = val;
01463         ++src;
01464       }
01465 }
01466 
01467 // ######################################################################
01468 void c_intg_y_filter_clean_fewbits(const int* src,
01469                                      const int w, const int h,
01470                                      const int* vf_flipped, const int vfs,
01471                                      const int shiftbits,
01472                                      int* dst)
01473 {
01474   ASSERT(h >= vfs);
01475   ASSERT(vfs > 0);
01476 
01477   ASSERT(vfs & 1);
01478   const int vfs2 = (vfs - 1) / 2;
01479 
01480   int ww[vfs]; // precompute row offsets
01481   for (int x = 0; x < vfs; x ++)
01482     ww[x] = w * x;
01483 
01484   // top points:
01485   for (int j = vfs2; j < vfs - 1; ++j)
01486     {
01487       int fp = vfs - 1 - j;
01488       for (int i = 0; i < w; ++i)  // scan all points of given horiz
01489         {
01490           int sum = 0;
01491           int val = 0;
01492           for (int k = 0; k <= j; k ++)
01493             {
01494               val += src[ww[k]] * vf_flipped[fp + k];
01495               sum += vf_flipped[fp + k];
01496             }
01497 
01498           *dst++ = val / sum;
01499           src++;
01500         }
01501       src -= w;   // back to top-left corner
01502     }
01503 
01504   // bulk (far from edges):
01505   for (int j = 0; j < h - vfs + 1; ++j)
01506     for (int i = 0; i < w; ++i)
01507       {
01508         int val = 0;
01509         for (int k = 0; k < vfs; k ++)
01510           val += src[ww[k]] * vf_flipped[k];
01511         *dst++ = (val >> shiftbits);
01512         src++;
01513       }
01514 
01515   // bottommost points:
01516   for (int j = vfs - 2; j >= vfs2; j --)
01517     for (int i = 0; i < w; ++i)
01518       {
01519         int sum = 0;
01520         int val = 0;
01521         for (int k = 0; k <= j; k ++)
01522           {
01523             val += src[ww[k]] * vf_flipped[k];
01524             sum += vf_flipped[k];
01525           }
01526 
01527         *dst++ = val / sum;
01528         ++src;
01529       }
01530 }
01531 
01532 // ######################################################################
01533 void c_intg_y_filter_clean_small_manybits(const int* src,
01534                                            const int w, const int h,
01535                                            const int* vf_flipped, const int vfs,
01536                                            const int shiftbits,
01537                                            int* dst)
01538 {
01539   ASSERT(h < vfs);
01540   ASSERT(vfs > 0);
01541 
01542   ASSERT(vfs & 1);
01543   const int vfs2 = (vfs - 1) / 2;
01544 
01545   for (int j = 0; j < h; ++j)
01546     for (int i = 0; i < w; ++i)
01547       {
01548         int sum = 0;
01549         for (int k = 0; k < vfs; k ++)
01550           if (j + k - vfs2 >= 0 && j + k - vfs2 < h)
01551             sum += vf_flipped[k];
01552 
01553         int val = 0;
01554         for (int k = 0; k < vfs; k ++)
01555           if (j + k - vfs2 >= 0 && j + k - vfs2 < h)
01556             val += (src[w * (k - vfs2)] / sum) * vf_flipped[k];
01557 
01558         *dst++ = val;
01559         ++src;
01560       }
01561 }
01562 
01563 // ######################################################################
01564 void c_intg_y_filter_clean_small_fewbits(const int* src,
01565                                            const int w, const int h,
01566                                            const int* vf_flipped, const int vfs,
01567                                            const int shiftbits,
01568                                            int* dst)
01569 {
01570   ASSERT(h < vfs);
01571   ASSERT(vfs > 0);
01572 
01573   ASSERT(vfs & 1);
01574   const int vfs2 = (vfs - 1) / 2;
01575 
01576   for (int j = 0; j < h; ++j)
01577     for (int i = 0; i < w; ++i)
01578       {
01579         int sum = 0;
01580         int val = 0;
01581         for (int k = 0; k < vfs; k ++)
01582           if (j + k - vfs2 >= 0 && j + k - vfs2 < h)
01583             {
01584               val += src[w * (k - vfs2)] * vf_flipped[k];
01585               sum += vf_flipped[k];
01586             }
01587 
01588         *dst++ = val / sum;
01589         ++src;
01590       }
01591 }
01592 
01593 // ######################################################################
01594 /* So things look consistent in everyone's emacs... */
01595 /* Local Variables: */
01596 /* mode: c++ */
01597 /* indent-tabs-mode: nil */
01598 /* End: */
01599 
01600 #endif // IMAGE_C_INTEGER_MATH_OPS_C_DEFINED
Generated on Sun May 8 08:05:05 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3