whitebox-Image.C

Go to the documentation of this file.
00001 /*!@file TestSuite/whitebox-Image.C Test Image class */
00002 
00003 // //////////////////////////////////////////////////////////////////// //
00004 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2001 by the //
00005 // 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@klab.caltech.edu>
00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/TestSuite/whitebox-Image.C $
00035 // $Id: whitebox-Image.C 14376 2011-01-11 02:44:34Z pez $
00036 //
00037 
00038 #include "Util/log.H"
00039 
00040 #include "Image/ColorOps.H"
00041 #include "Image/Convolver.H"
00042 #include "Image/Coords.H"    // for Dims operators
00043 #include "Image/CutPaste.H"  // for crop() etc.
00044 #include "Image/DrawOps.H"   // for warp3D() etc.
00045 #include "Image/FilterOps.H" // for lowPass9() etc.
00046 #include "Image/FourierEngine.H"
00047 #include "Image/Hash.H"      // for sha1byte(), sha256byte()
00048 #include "Image/IO.H"
00049 #include "Image/Image.H"
00050 #include "Image/Kernels.H"   // for binomialKernel()
00051 #include "Image/Layout.H"
00052 #include "Image/LinearAlgebra.H" // for svd(), naiveUnstablePseudoInv()
00053 #include "Image/MathOps.H"   // for quadEnergy() etc.
00054 #include "Image/MatrixOps.H" // for matrixMult(), matrixInv(), etc
00055 #include "Image/Pixels.H"
00056 #include "Image/Range.H"
00057 #include "Image/ShapeOps.H"  // for zoomXY() etc.
00058 #include "Image/Transforms.H" // for zoomXY() etc.
00059 #include "Image/Point2D.H"
00060 #include "TestSuite/TestSuite.H"
00061 #include "rutz/rand.h"
00062 
00063 #include <cstdlib>
00064 #include <cstring>
00065 
00066 namespace
00067 {
00068   struct Counter
00069   {
00070     Counter(int cc = 0, int ss = 1) : c(cc), s(ss) {}
00071 
00072     int operator()() { const int r = c; c+=s; return r; }
00073 
00074     int c;
00075     int s;
00076   };
00077 
00078   template <class T, class F>
00079   Image<T> generateImage(const Dims& d, F func)
00080   {
00081     Image<T> result(d, NO_INIT);
00082 
00083     fill(result, func);
00084 
00085     return result;
00086   }
00087 
00088   template <class T, class F>
00089   inline Image<T> generateImage(int w, int h, F func)
00090   { return generateImage<T>(Dims(w, h), func); }
00091 }
00092 
00093 struct InstanceCounter
00094 {
00095   static int numCreated;
00096   static int numDestroyed;
00097 
00098   static void reset() { numCreated = numDestroyed = 0; }
00099 
00100   InstanceCounter() { ++numCreated; }
00101 
00102   ~InstanceCounter() { ++numDestroyed; }
00103 
00104   InstanceCounter(const InstanceCounter&) { ++numCreated; }
00105 
00106   InstanceCounter& operator=(const InstanceCounter&) { return *this; }
00107 };
00108 
00109 int InstanceCounter::numCreated = 0;
00110 int InstanceCounter::numDestroyed = 0;
00111 
00112 ///////////////////////////////////////////////////////////////////////
00113 //
00114 // Test functions
00115 //
00116 // note that these funny _xx_'s are just used as a hierarchical separator
00117 // (since double-underscore __ is not legal in C/C++ identifiers); the _xx_ is
00118 // expected to be replaced by something prettier, like "--", by the test
00119 // driver script.
00120 //
00121 ///////////////////////////////////////////////////////////////////////
00122 
00123 //---------------------------------------------------------------------
00124 //
00125 // Rectangle
00126 //
00127 //---------------------------------------------------------------------
00128 
00129 static void Rectangle_xx_getOverlap_xx_1(TestSuite& suite)
00130 {
00131   // assume the original range is [0,10[, now if we merge that with a
00132   // range of [lo,hi[ then we expect to get either a range of
00133   // [newlo,newhi[ if valid is true, or else a null range if valid is
00134   // false:
00135 
00136   struct TestRange { int lo; int hi; int newlo; int newhi; bool valid; };
00137 
00138   const TestRange offsets[] =
00139     {
00140       // 'a' contained within original range
00141       // 'b' contained within second range
00142       // 'X' contained within overlap of the two ranges
00143 
00144       //     -1         0         1         2
00145       // 54321098765432101234567890123456789012345
00146       //                aaaaaaaaaa                 <----- original range
00147 
00148       /* bbbbbbbbbb                                */ { -15, -5, 0,  0, false },
00149       /*      bbbbbbbbbb                           */ { -10,  0, 0,  0, false },
00150       /*               b                           */ {  -1,  0, 0,  0, false },
00151       /*                X                          */ {   0,  1, 0,  1, true },
00152       /*           bbbbbXXXXX                      */ {  -5,  5, 0,  5, true },
00153       /*                XXXXX                      */ {   0,  5, 0,  5, true },
00154       /*                XXXXXXXXXX                 */ {   0, 10, 0, 10, true },
00155       /*                  XXXXXX                   */ {   2,  8, 2,  8, true },
00156       /*                     XXXXX                 */ {   5, 10, 5, 10, true },
00157       /*                     XXXXXbbbbb            */ {   5, 15, 5, 10, true },
00158       /*                         X                 */ {   9, 10, 9, 10, true },
00159       /*                          b                */ {  10, 11, 0,  0, false },
00160       /*                          bbbbbbbbbb       */ {  10, 20, 0,  0, false },
00161       /*                               bbbbbbbbbb  */ {  15, 25, 0,  0, false }
00162     };
00163 
00164   const int left = 10;
00165   const int top = -5;
00166 
00167   const Rectangle r1(Point2D<int>(left, top), Dims(10, 10));
00168 
00169   for (size_t xoff = 0; xoff < sizeof(offsets) / sizeof(offsets[0]); ++xoff)
00170     for (size_t yoff = 0; yoff < sizeof(offsets) / sizeof(offsets[0]); ++yoff)
00171       {
00172         const Rectangle r2(Point2D<int>(left + offsets[xoff].lo,
00173                                    top  + offsets[yoff].lo),
00174                            Dims(offsets[xoff].hi - offsets[xoff].lo,
00175                                 offsets[yoff].hi - offsets[yoff].lo));
00176 
00177         const Rectangle r12 = r1.getOverlap(r2);
00178         const Rectangle r21 = r2.getOverlap(r1);
00179 
00180         REQUIRE_EQ_USERTYPE(r12, r21);
00181 
00182         if (!offsets[xoff].valid || !offsets[yoff].valid)
00183           REQUIRE(r12.isValid() == false);
00184         else
00185           {
00186             const Rectangle r3(Point2D<int>(left + offsets[xoff].newlo,
00187                                        top  + offsets[yoff].newlo),
00188                                Dims(offsets[xoff].newhi - offsets[xoff].newlo,
00189                                     offsets[yoff].newhi - offsets[yoff].newlo));
00190 
00191             REQUIRE_EQ_USERTYPE(r12, r3);
00192           }
00193       }
00194 }
00195 
00196 static void Rectangle_xx_constrain_xx_1(TestSuite& suite)
00197 {
00198   REQUIRE_EQ_USERTYPE(constrainRect
00199                       (Rectangle(Point2D<int>(-2, -3), Dims(5, 15)),
00200                        Rectangle(Point2D<int>(0, 0), Dims(10, 10)),
00201                        7, 9),
00202                       Rectangle(Point2D<int>(0, 0), Dims(7, 9)));
00203 
00204   REQUIRE_EQ_USERTYPE(constrainRect
00205                       (Rectangle(Point2D<int>(-2, -3), Dims(5, 15)),
00206                        Rectangle(Point2D<int>(0, 0), Dims(10, 10)),
00207                        7, 12),
00208                       Rectangle(Point2D<int>(0, 0), Dims(7, 10)));
00209 }
00210 
00211 //---------------------------------------------------------------------
00212 //
00213 // Constructors & Destructors
00214 //
00215 //---------------------------------------------------------------------
00216 
00217 static void Image_xx_construct_from_array_xx_1(TestSuite& suite)
00218 {
00219   byte array[6] = { 3, 5, 7, 9, 11, 13 };
00220 
00221   Image<byte> a(&array[0], 3, 2);
00222 
00223   REQUIRE_EQ(a.getWidth(), 3);
00224   REQUIRE_EQ(a.getHeight(), 2);
00225   REQUIRE_EQ_USERTYPE(a.getDims(), Dims(3,2));
00226   REQUIRE_EQ_USERTYPE(a.getBounds(), Rectangle::tlbrI(0, 0, 1, 2));
00227   REQUIRE_EQ((int)a.getVal(2,0), 7);
00228   REQUIRE_EQ((int)a.getVal(0,1), 9);
00229 }
00230 
00231 static void Image_xx_construct_UDT_xx_1(TestSuite& suite)
00232 {
00233   InstanceCounter::reset();
00234 
00235   {
00236     // We are testing that, even though we request NO_INIT, InstanceCounter
00237     // objects should still get constructed+destructed since they don't
00238     // satisfy TypeTraits<T>::isTrivial.
00239     Image<InstanceCounter> a(5, 5, NO_INIT);
00240   }
00241 
00242   // might create more than 25 objects if there were copies
00243   REQUIRE(InstanceCounter::numCreated >= 25);
00244   REQUIRE_EQ(InstanceCounter::numCreated, InstanceCounter::numDestroyed);
00245 }
00246 
00247 static void Image_xx_construct_and_clear_xx_1(TestSuite& suite)
00248 {
00249   Image<float> a(3, 4, ZEROS);
00250 
00251   REQUIRE_EQ(a.getWidth(), 3);
00252   REQUIRE_EQ(a.getHeight(), 4);
00253   REQUIRE_EQ_USERTYPE(a.getDims(), Dims(3,4));
00254   REQUIRE_EQ_USERTYPE(a.getBounds(), Rectangle::tlbrI(0, 0, 3, 2));
00255   REQUIRE_EQ(a.getVal(0,0), 0.0f);
00256   REQUIRE_EQ(a.getVal(2,3), 0.0f);
00257 }
00258 
00259 static void Image_xx_default_construct_xx_1(TestSuite& suite)
00260 {
00261   Image<byte> a;
00262 
00263   REQUIRE_EQ(a.getWidth(), 0);
00264   REQUIRE_EQ(a.getHeight(), 0);
00265   REQUIRE_EQ_USERTYPE(a.getDims(), Dims());
00266   REQUIRE_EQ_USERTYPE(a.getBounds(), Rectangle::tlbrI(0, 0, -1, -1));
00267   REQUIRE(a.begin() == a.end());
00268 }
00269 
00270 static void Image_xx_swap_xx_1(TestSuite& suite)
00271 {
00272   Image<byte> a(3, 3, NO_INIT); a.setVal(2,2,100);
00273   Image<byte> b(4, 4, NO_INIT); b.setVal(3,3,50);
00274 
00275   a.swap(b);
00276 
00277   REQUIRE_EQ(a.getHeight(), 4);
00278   REQUIRE_EQ(a.getWidth(), 4);
00279   REQUIRE_EQ(b.getHeight(), 3);
00280   REQUIRE_EQ(b.getWidth(), 3);
00281   REQUIRE_EQ((int)a.getVal(3,3), 50);
00282   REQUIRE_EQ((int)b.getVal(2,2), 100);
00283 }
00284 
00285 static void Image_xx_copy_xx_1(TestSuite& suite)
00286 {
00287   Image<float> a(2, 2, NO_INIT);
00288   a.setVal(0,0, 3.0);
00289 
00290   Image<float> b = a;
00291 
00292   REQUIRE_EQ(b.getVal(0,0), 3.0f);
00293 }
00294 
00295 static void Image_xx_copy_on_write_xx_1(TestSuite& suite)
00296 {
00297   Image<float> a(3, 3, NO_INIT);
00298   a.setVal(1,1,2.5);
00299 
00300   Image<float> b = a;
00301   b.setVal(1,1,5.5);
00302 
00303   REQUIRE_EQ(a.getVal(1,1), 2.5f);
00304   REQUIRE(!a.hasSameData(b));
00305 }
00306 
00307 static void Image_xx_copy_on_write_xx_2(TestSuite& suite)
00308 {
00309   Image<byte> a(3, 3, NO_INIT);
00310 
00311   Image<byte> b( a );
00312 
00313   // make sure that we didn't do an expensive data copy; i.e. check that the
00314   // ref-counting actually worked:
00315   REQUIRE(a.hasSameData(b));
00316 }
00317 
00318 static void Image_xx_copy_on_write_xx_3(TestSuite& suite)
00319 {
00320   Image<byte> a(3, 3, NO_INIT);
00321 
00322   Image<byte> b;
00323 
00324   b = a;
00325 
00326   // like the previous test, but with assignment instead of copy-construct
00327   REQUIRE(a.hasSameData(b));
00328 }
00329 
00330 static void Image_xx_assignment_to_self_xx_1(TestSuite& suite)
00331 {
00332   Image<byte> a(4, 4, NO_INIT); a.setVal(1,1,50);
00333 
00334   a = a;
00335 
00336   REQUIRE_EQ(a.refCount(), long(1));
00337   REQUIRE_EQ((int)a.getVal(1,1), 50);
00338 }
00339 
00340 static void Image_xx_reshape_xx_1(TestSuite& suite)
00341 {
00342   const byte dat[] =
00343     {
00344       1, 5, 9, 13,
00345       2, 6, 10, 14,
00346       3, 7, 11, 15,
00347       4, 8, 12, 16
00348     };
00349 
00350   Image<byte> a(&dat[0], 4, 4);
00351 
00352   REQUIRE_EQ(reshape(a, Dims(16,1)), Image<byte>(&dat[0], 16, 1));
00353 }
00354 
00355 static void Image_xx_indexing_xx_1(TestSuite& suite)
00356 {
00357   short array[9] = { 12570, -9, 11,
00358                      257,    0, 4999,
00359                      5353, -1701, 1 };
00360 
00361   Image<short> a(array, 3, 3);
00362 
00363   REQUIRE_EQ(a[0],             12570);
00364   REQUIRE_EQ(a.getVal(1, 1),   0);
00365   REQUIRE_EQ(a[Point2D<int>(2,1)], 4999);
00366   REQUIRE_EQ(a[Point2D<int>(1,2)], -1701);
00367 
00368   a[Point2D<int>(0,2)] = 12345;
00369 
00370   REQUIRE_EQ(a[6], 12345);
00371 }
00372 
00373 static void Image_xx_type_convert_xx_1(TestSuite& suite)
00374 {
00375   float array[4] = { -10.9, 3.2, 254.7, 267.3 };
00376 
00377   Image<float> f(array, 4, 1);
00378 
00379   Image<byte> b = f;
00380 
00381   REQUIRE_EQ((int)b.getVal(0), 0); // clamped
00382   REQUIRE_EQ((int)b.getVal(1), 3);
00383   REQUIRE_EQ((int)b.getVal(2), 254);
00384   REQUIRE_EQ((int)b.getVal(3), 255); // clamped
00385 }
00386 
00387 static void Image_xx_type_convert_xx_2(TestSuite& suite)
00388 {
00389   byte array[4] = { 0, 52, 107, 255 };
00390 
00391   Image<byte> b(array, 4, 1);
00392 
00393   Image<float> f = b;
00394 
00395   REQUIRE_EQ(f.getVal(0), 0.0f);
00396   REQUIRE_EQ(f.getVal(1), 52.0f);
00397   REQUIRE_EQ(f.getVal(2), 107.0f);
00398   REQUIRE_EQ(f.getVal(3), 255.0f);
00399 }
00400 
00401 static void Image_xx_type_convert_xx_3(TestSuite& suite)
00402 {
00403   byte array[4] = { 0, 52, 107, 255 };
00404 
00405   Image<byte> b(array, 4, 1);
00406 
00407   // promotions:   (int)    (int)    and promote to float
00408   Image<float> f = (b * 5 - 100);
00409 
00410   REQUIRE_EQ(f.getVal(0), -100.0f);
00411   REQUIRE_EQ(f.getVal(1), 160.0f);
00412   REQUIRE_EQ(f.getVal(2), 435.0f);
00413   REQUIRE_EQ(f.getVal(3), 1175.0f);
00414 
00415   // promotions:   (int)    and cast back to byte with clamping
00416   Image<byte> bb = b * 2;
00417 
00418   REQUIRE_EQ(bb.getVal(0), 0);
00419   REQUIRE_EQ(bb.getVal(1), 104);
00420   REQUIRE_EQ(bb.getVal(2), 214);
00421   REQUIRE_EQ(bb.getVal(3), 255);
00422 
00423   //  (float)
00424   f = (b - 100.0F) / 2.0F;
00425   REQUIRE_EQ(f.getVal(0), -50.0f);
00426   REQUIRE_EQ(f.getVal(1), -24.0f);
00427   REQUIRE_EQ(f.getVal(2), 3.5f);
00428   REQUIRE_EQ(f.getVal(3), 77.5f);
00429 
00430   //  (double) and cast back to float with clamping
00431   f = (b - 100.0) / 2.0;
00432   REQUIRE_EQ(f.getVal(0), -50.0f);
00433   REQUIRE_EQ(f.getVal(1), -24.0f);
00434   REQUIRE_EQ(f.getVal(2), 3.5f);
00435   REQUIRE_EQ(f.getVal(3), 77.5f);
00436 }
00437 
00438 static void Image_xx_attach_detach_xx_1(TestSuite& suite)
00439 {
00440   Image<float> a;
00441 
00442   float array[4] = { 2.0, 4.0, 6.0, 8.0 };
00443 
00444   a.attach(&array[0], 2, 2);
00445 
00446   REQUIRE_EQ(a.getVal(1,0), 4.0f);
00447   REQUIRE_EQ(a.getVal(0,1), 6.0f);
00448 
00449   // Make sure that if we modify the Image, that we "write through" to the
00450   // underlying float array
00451   a.setVal(1,1,3.5);
00452 
00453   REQUIRE_EQ(array[3], 3.5f);
00454 
00455   // Make sure that if we make a copy of the attach'ed array, that we DON'T
00456   // write through to the original float array
00457   Image<float> b = a.deepcopy();
00458 
00459   REQUIRE_EQ(b.getVal(1,1), 3.5f);
00460 
00461   b.setVal(0,0, -1.0f);
00462 
00463   REQUIRE_EQ(array[0], 2.0f);
00464 
00465   a.detach();
00466 }
00467 
00468 static void Image_xx_destruct_xx_1(TestSuite& suite)
00469 {
00470   Image<float> a(5, 5, NO_INIT);
00471 
00472   REQUIRE_EQ(a.refCount(), long(1));
00473 
00474   {
00475     Image<float> b = a;
00476 
00477     REQUIRE_EQ(a.refCount(), long(2)); // make sure the count went up...
00478   }
00479 
00480   REQUIRE_EQ(a.refCount(), long(1)); // ... and back down again here
00481 }
00482 
00483 //---------------------------------------------------------------------
00484 //
00485 // Iterators
00486 //
00487 //---------------------------------------------------------------------
00488 
00489 static void Image_xx_begin_end_xx_1(TestSuite& suite)
00490 {
00491   Image<float> a(135, 1, NO_INIT);
00492 
00493   REQUIRE_EQ((int)(a.end() - a.begin()), 135);
00494   REQUIRE_EQ(*(a.begin()), a.getVal(0,0));
00495 }
00496 
00497 static void Image_xx_beginw_endw_xx_1(TestSuite& suite)
00498 {
00499   Image<byte> b(20, 17, NO_INIT);
00500 
00501   b.setVal(0,0,1);
00502 
00503   Image<byte> c = b;
00504 
00505   REQUIRE(b.hasSameData(c));
00506 
00507   Image<byte>::iterator itr = c.beginw(), stop = c.endw();
00508 
00509   REQUIRE(!b.hasSameData(c));
00510 
00511   REQUIRE_EQ((int)(stop - itr), 20*17);
00512 
00513   REQUIRE_EQ(int(c.getVal(0)), 1);
00514 
00515   *itr = 49;
00516 
00517   REQUIRE_EQ(int(c.getVal(0)), 49);
00518   REQUIRE_EQ(int(b.getVal(0)), 1);
00519 }
00520 
00521 //---------------------------------------------------------------------
00522 //
00523 // Access functions
00524 //
00525 //---------------------------------------------------------------------
00526 
00527 static void Image_xx_getMean_xx_1(TestSuite& suite)
00528 {
00529   Image<float> img = generateImage<float>(100,100,Counter(0));
00530 
00531   REQUIRE_EQ(mean(img), 4999.5);
00532 }
00533 
00534 //---------------------------------------------------------------------
00535 //
00536 // Basic image manipulations
00537 //
00538 //---------------------------------------------------------------------
00539 
00540 static void Image_xx_clear_xx_1(TestSuite& suite)
00541 {
00542   Image<float> img(100, 100, NO_INIT);
00543 
00544   img.clear(1.5F);
00545 
00546   REQUIRE_EQ(mean(img), 1.5);
00547   REQUIRE_EQ(img.getVal(0,0), 1.5f);
00548   REQUIRE_EQ(img.getVal(99,99), 1.5f);
00549 }
00550 
00551 static void Image_xx_plus_eq_scalar_xx_1(TestSuite& suite)
00552 {
00553   Image<float> img = generateImage<float>(100,100,Counter(0));
00554 
00555   REQUIRE_EQ(mean(img), 4999.5);
00556 
00557   img += 1.0F;
00558 
00559   REQUIRE_EQ(mean(img), 5000.5);
00560   REQUIRE_EQ(img.getVal(0), 1.0f);
00561   REQUIRE_EQ(img.getVal(img.getSize()-1), float(100*100));
00562 
00563   byte array[4] = { 0, 52, 107, 255 };
00564   Image<byte> b(array, 4, 1);
00565 
00566   b += 100;
00567 
00568   REQUIRE_EQ(b.getVal(0), 100);
00569   REQUIRE_EQ(b.getVal(1), 152);
00570   REQUIRE_EQ(b.getVal(2), 207);
00571   REQUIRE_EQ(b.getVal(3), 255);   // clamp
00572 }
00573 
00574 static void Image_xx_minus_eq_scalar_xx_1(TestSuite& suite)
00575 {
00576   Image<float> img = generateImage<float>(100,100,Counter(0));
00577 
00578   REQUIRE_EQ(mean(img), 4999.5F);
00579 
00580   img -= 1.0F;
00581 
00582   REQUIRE_EQ(mean(img), 4998.5F);
00583   REQUIRE_EQ(img.getVal(0), -1.0f);
00584   REQUIRE_EQ(img.getVal(img.getSize()-1), float(100*100-2));
00585 
00586   byte array[4] = { 0, 52, 107, 255 };
00587   Image<byte> b(array, 4, 1);
00588 
00589   b -= 100;
00590 
00591   REQUIRE_EQ(b.getVal(0), 0);  // clamp
00592   REQUIRE_EQ(b.getVal(1), 0);  // clamp
00593   REQUIRE_EQ(b.getVal(2), 7);
00594   REQUIRE_EQ(b.getVal(3), 155);
00595 }
00596 
00597 static void Image_xx_mul_eq_scalar_xx_1(TestSuite& suite)
00598 {
00599   Image<float> img = generateImage<float>(100,100,Counter(0));
00600 
00601   REQUIRE_EQ(mean(img), 4999.5);
00602 
00603   img *= 2.0f;
00604 
00605   REQUIRE_EQ(mean(img), 9999.0);
00606   REQUIRE_EQ(img.getVal(1), 2.0f);
00607   REQUIRE_EQ(img.getVal(img.getSize()-1), float((100*100-1)*2));
00608 
00609   byte array[4] = { 0, 52, 107, 255 };
00610   Image<byte> b(array, 4, 1);
00611 
00612   b *= 3;
00613 
00614   REQUIRE_EQ(b.getVal(0), 0);
00615   REQUIRE_EQ(b.getVal(1), 156);
00616   REQUIRE_EQ(b.getVal(2), 255);  // clamp
00617   REQUIRE_EQ(b.getVal(3), 255);  // clamp
00618 }
00619 
00620 static void Image_xx_div_eq_scalar_xx_1(TestSuite& suite)
00621 {
00622   Image<float> img = generateImage<float>(100,100,Counter(0));
00623 
00624   REQUIRE_EQ(mean(img), 4999.5);
00625 
00626   img /= 2.0f;
00627 
00628   REQUIRE_EQ(mean(img), 2499.75);
00629   REQUIRE_EQ(img.getVal(1), 0.5f);
00630   REQUIRE_EQ(img.getVal(img.getSize()-1), float((100*100-1)/2.0));
00631 
00632 
00633   byte array[4] = { 0, 52, 107, 255 };
00634   Image<byte> b(array, 4, 1);
00635 
00636   b /= 3;
00637 
00638   REQUIRE_EQ(b.getVal(0), 0);
00639   REQUIRE_EQ(b.getVal(1), 17);
00640   REQUIRE_EQ(b.getVal(2), 35);
00641   REQUIRE_EQ(b.getVal(3), 85);
00642 }
00643 
00644 static void Image_xx_lshift_eq_scalar_xx_1(TestSuite& suite)
00645 {
00646   byte barray[4] = { 0, 52, 107, 255 };
00647   Image<byte> b(barray, 4, 1);
00648 
00649   b <<= 1;
00650 
00651   REQUIRE_EQ(b.getVal(0), 0);
00652   REQUIRE_EQ(b.getVal(1), 104);
00653   REQUIRE_EQ(b.getVal(2), 214);
00654   REQUIRE_EQ(b.getVal(3), 254);
00655 
00656   int iarray[4] = { -37, -1, 297, 65535 };
00657   Image<int> i(iarray, 4, 1);
00658 
00659   i <<= 3;
00660 
00661   REQUIRE_EQ(i.getVal(0), -296);
00662   REQUIRE_EQ(i.getVal(1), -8);
00663   REQUIRE_EQ(i.getVal(2), 2376);
00664   REQUIRE_EQ(i.getVal(3), 524280);
00665 }
00666 
00667 static void Image_xx_rshift_eq_scalar_xx_1(TestSuite& suite)
00668 {
00669   byte barray[4] = { 0, 52, 107, 255 };
00670   Image<byte> b(barray, 4, 1);
00671 
00672   b >>= 3;
00673 
00674   REQUIRE_EQ(b.getVal(0), 0);
00675   REQUIRE_EQ(b.getVal(1), 6);
00676   REQUIRE_EQ(b.getVal(2), 13);
00677   REQUIRE_EQ(b.getVal(3), 31);
00678 
00679   int iarray[4] = { -37, -1, 297, 65535 };
00680   Image<int> i(iarray, 4, 1);
00681 
00682   i >>= 3;
00683 
00684   REQUIRE_EQ(i.getVal(0), -5);
00685   REQUIRE_EQ(i.getVal(1), -1);
00686   REQUIRE_EQ(i.getVal(2), 37);
00687   REQUIRE_EQ(i.getVal(3), 8191);
00688 }
00689 
00690 static void Image_xx_plus_eq_array_xx_1(TestSuite& suite)
00691 {
00692   Image<float> img1 = generateImage<float>(1000, 1000, Counter(0));
00693 
00694   Image<float> img2 = generateImage<float>(1000, 1000, Counter(1));
00695 
00696   REQUIRE_EQ(mean(img1), 499999.5);
00697 
00698   img1 += img2;
00699 
00700   REQUIRE_EQ(mean(img1), 1000000.0);
00701   REQUIRE_EQ(img1.getVal(0), 1.0f);
00702   REQUIRE_EQ(img1.getVal(img1.getSize()-1), float(1000*1000 - 1 + 1000*1000));
00703 
00704   byte array[4] = { 0, 52, 107, 255 }, array2[4] = { 201, 23, 56, 5 };
00705   Image<byte> b(array, 4, 1), bb(array2, 4, 1);
00706 
00707   b += bb;
00708 
00709   REQUIRE_EQ(b.getVal(0), 201);
00710   REQUIRE_EQ(b.getVal(1), 75);
00711   REQUIRE_EQ(b.getVal(2), 163);
00712   REQUIRE_EQ(b.getVal(3), 255); // clamp
00713 }
00714 
00715 static void Image_xx_minus_eq_array_xx_1(TestSuite& suite)
00716 {
00717   Image<float> img1 = generateImage<float>(1000, 1000, Counter(1));
00718 
00719   Image<float> img2 = generateImage<float>(1000, 1000, Counter(0));
00720 
00721   REQUIRE_EQ(mean(img1), 500000.5);
00722 
00723   img1 -= img2;
00724 
00725   REQUIRE_EQ(mean(img1), 1.0);
00726   REQUIRE_EQ(img1.getVal(0), 1.0f);
00727   REQUIRE_EQ(img1.getVal(img1.getSize()-1), 1.0f);
00728 
00729   byte array[4] = { 0, 52, 107, 255 }, array2[4] = { 201, 23, 56, 5 };
00730   Image<byte> b(array, 4, 1), bb(array2, 4, 1);
00731 
00732   b -= bb;
00733 
00734   REQUIRE_EQ(b.getVal(0), 0); // clamp
00735   REQUIRE_EQ(b.getVal(1), 29);
00736   REQUIRE_EQ(b.getVal(2), 51);
00737   REQUIRE_EQ(b.getVal(3), 250);
00738 }
00739 
00740 static void Image_xx_mul_eq_array_xx_1(TestSuite& suite)
00741 {
00742   Image<float> img1 = generateImage<float>(1000, 1000, Counter(0));
00743 
00744   Image<float> img2(1000, 1000, NO_INIT); img2.clear(2.0f);
00745 
00746   REQUIRE_EQ(mean(img1), 499999.5);
00747 
00748   img1 *= img2;
00749 
00750   REQUIRE_EQ(mean(img1), 999999.0);
00751   REQUIRE_EQ(img1.getVal(1), 2.0f);
00752   REQUIRE_EQ(img1.getVal(img1.getSize()-1), float((1000*1000-1)*2));
00753 
00754   byte array[4] = { 0, 52, 107, 255 }, array2[4] = { 201, 3, 56, 5 };
00755   Image<byte> b(array, 4, 1), bb(array2, 4, 1);
00756 
00757   b *= bb;
00758 
00759   REQUIRE_EQ(b.getVal(0), 0);
00760   REQUIRE_EQ(b.getVal(1), 156);
00761   REQUIRE_EQ(b.getVal(2), 255); // clamp
00762   REQUIRE_EQ(b.getVal(3), 255); // clamp
00763 }
00764 
00765 static void Image_xx_div_eq_array_xx_1(TestSuite& suite)
00766 {
00767   Image<float> img1 = generateImage<float>(1000,1000,Counter(0));
00768 
00769   Image<float> img2(1000, 1000, NO_INIT); img2.clear(2.0f);
00770 
00771   REQUIRE_EQ(mean(img1), 499999.5);
00772 
00773   img1 /= img2;
00774 
00775   REQUIRE_EQ(mean(img1), 249999.75);
00776   REQUIRE_EQ(img1.getVal(1), 0.5f);
00777   REQUIRE_EQ(img1.getVal(img1.getSize()-1), 499999.5f);
00778 
00779   byte array[4] = { 0, 52, 107, 255 }, array2[4] = { 201, 3, 56, 5 };
00780   Image<byte> b(array, 4, 1), bb(array2, 4, 1);
00781 
00782   b /= bb;
00783 
00784   REQUIRE_EQ(b.getVal(0), 0);
00785   REQUIRE_EQ(b.getVal(1), 17);
00786   REQUIRE_EQ(b.getVal(2), 1);
00787   REQUIRE_EQ(b.getVal(3), 51);
00788 }
00789 
00790 static void Image_xx_plus_scalar_xx_1(TestSuite& suite)
00791 {
00792   Image<float> img = generateImage<float>(200,500,Counter(0));
00793 
00794   REQUIRE_EQ(mean(img), 49999.5f);
00795 
00796   Image<float> img2 = img + 1.0f;
00797 
00798   REQUIRE_EQ(mean(img2), 50000.5f);
00799   REQUIRE_EQ(img2.getVal(0), 1.0f);
00800   REQUIRE_EQ(img2.getVal(img2.getSize()-1), float(200*500));
00801 }
00802 
00803 static void Image_xx_minus_scalar_xx_1(TestSuite& suite)
00804 {
00805   Image<float> img = generateImage<float>(200,500,Counter(0));
00806 
00807   REQUIRE_EQ(mean(img), 49999.5F);
00808 
00809   Image<float> img2 = img - 1.0F;
00810 
00811   REQUIRE_EQ(mean(img2), 49998.5F);
00812   REQUIRE_EQ(img2.getVal(0), -1.0f);
00813   REQUIRE_EQ(img2.getVal(img2.getSize()-1), float(200*500-2));
00814 }
00815 
00816 static void Image_xx_mul_scalar_xx_1(TestSuite& suite)
00817 {
00818   Image<float> img = generateImage<float>(200,500,Counter(0));
00819 
00820   REQUIRE_EQ(mean(img), 49999.5f);
00821 
00822   Image<float> img2 = img * 2.0f;
00823 
00824   REQUIRE_EQ(mean(img2), 99999.0f);
00825   REQUIRE_EQ(img2.getVal(1), 2.0f);
00826   REQUIRE_EQ(img2.getVal(img2.getSize()-1), float((200*500-1)*2));
00827 }
00828 
00829 static void Image_xx_div_scalar_xx_1(TestSuite& suite)
00830 {
00831   Image<float> img = generateImage<float>(200,500,Counter(0));
00832 
00833   REQUIRE_EQ(mean(img), 49999.5f);
00834 
00835   Image<float> img2 = img / 2.0f;
00836 
00837   REQUIRE_EQ(mean(img2), 24999.75f);
00838   REQUIRE_EQ(img2.getVal(1), 0.5f);
00839   REQUIRE_EQ(img2.getVal(img2.getSize()-1), float((200*500-1)/2.0));
00840 }
00841 
00842 static void Image_xx_lshift_scalar_xx_1(TestSuite& suite)
00843 {
00844   byte barray[4] = { 0, 52, 107, 255 };
00845   const Image<byte> b1(barray, 4, 1);
00846 
00847   const Image<byte> b = (b1 << 2);
00848 
00849   REQUIRE_EQ(b.getVal(0), 0);
00850   REQUIRE_EQ(b.getVal(1), 208);
00851   REQUIRE_EQ(b.getVal(2), 172);
00852   REQUIRE_EQ(b.getVal(3), 252);
00853 
00854   int iarray[4] = { -37, -1, 297, 65535 };
00855   const Image<int> i1(iarray, 4, 1);
00856 
00857   const Image<int> i = (i1 << 2);
00858 
00859   REQUIRE_EQ(i.getVal(0), -148);
00860   REQUIRE_EQ(i.getVal(1), -4);
00861   REQUIRE_EQ(i.getVal(2), 1188);
00862   REQUIRE_EQ(i.getVal(3), 262140);
00863 }
00864 
00865 static void Image_xx_rshift_scalar_xx_1(TestSuite& suite)
00866 {
00867   byte barray[4] = { 0, 52, 107, 255 };
00868   const Image<byte> b1(barray, 4, 1);
00869 
00870   const Image<byte> b = (b1 >> 2);
00871 
00872   REQUIRE_EQ(b.getVal(0), 0);
00873   REQUIRE_EQ(b.getVal(1), 13);
00874   REQUIRE_EQ(b.getVal(2), 26);
00875   REQUIRE_EQ(b.getVal(3), 63);
00876 
00877   int iarray[4] = { -37, -1, 297, 65535 };
00878   const Image<int> i1(iarray, 4, 1);
00879 
00880   const Image<int> i = (i1 >> 2);
00881 
00882   REQUIRE_EQ(i.getVal(0), -10);
00883   REQUIRE_EQ(i.getVal(1), -1);
00884   REQUIRE_EQ(i.getVal(2), 74);
00885   REQUIRE_EQ(i.getVal(3), 16383);
00886 }
00887 
00888 static void Image_xx_plus_array_xx_1(TestSuite& suite)
00889 {
00890   Image<float> img1 = generateImage<float>(100, 100, Counter(0));
00891 
00892   Image<float> img2 = generateImage<float>(100, 100, Counter(1));
00893 
00894   Image<float> img3 = img1 + img2;
00895 
00896   REQUIRE_EQ(mean(img3), 10000.0f);
00897   REQUIRE_EQ(img3.getVal(0), 1.0f);
00898   REQUIRE_EQ(img3.getVal(img3.getSize()-1), float(100*100 - 1 + 100*100));
00899 }
00900 
00901 static void Image_xx_minus_array_xx_1(TestSuite& suite)
00902 {
00903   Image<float> img1 = generateImage<float>(100, 100, Counter(1));
00904 
00905   Image<float> img2 = generateImage<float>(100, 100, Counter(0));
00906 
00907   Image<float> img3 = img1 - img2;
00908 
00909   REQUIRE_EQ(mean(img3), 1.0f);
00910   REQUIRE_EQ(img3.getVal(0), 1.0f);
00911   REQUIRE_EQ(img3.getVal(img3.getSize()-1), 1.0f);
00912 }
00913 
00914 static void Image_xx_minus_array_xx_2(TestSuite& suite)
00915 {
00916   const byte a1data[] = { 0, 1, 2, 3 };
00917   const byte a2data[] = { 3, 2, 1, 0 };
00918 
00919   // make sure that the promotions happen as we expect: the byte
00920   // values should get converted to signed int as a part of the
00921   // subtraction operation (otherwise 0u-3u would be undefined)
00922   const int diffdata[] = { -3, -1, 1, 3 };
00923 
00924   Image<byte> a1(&a1data[0], 4, 1);
00925   Image<byte> a2(&a2data[0], 4, 1);
00926   Image<int> diff(&diffdata[0], 4, 1);
00927 
00928   REQUIRE_EQ(a1 - a2, diff);
00929 }
00930 
00931 static void Image_xx_mul_array_xx_1(TestSuite& suite)
00932 {
00933   Image<float> img1 = generateImage<float>(100, 100, Counter(0));
00934 
00935   Image<float> img2(100, 100, NO_INIT); img2.clear(2.0f);
00936 
00937   Image<float> img3 = img1 * img2;
00938 
00939   REQUIRE_EQ(mean(img3), 9999.0f);
00940   REQUIRE_EQ(img3.getVal(1), 2.0f);
00941   REQUIRE_EQ(img3.getVal(img3.getSize()-1), float((100*100-1)*2));
00942 }
00943 
00944 static void Image_xx_div_array_xx_1(TestSuite& suite)
00945 {
00946   Image<float> img1 = generateImage<float>(100, 100, Counter(0));
00947 
00948   Image<float> img2(100, 100, NO_INIT); img2.clear(2.0f);
00949 
00950   Image<float> img3 = img1 / img2;
00951 
00952   REQUIRE_EQ(mean(img3), 2499.75);
00953   REQUIRE_EQ(img3.getVal(1), 0.5f);
00954   REQUIRE_EQ(img3.getVal(img3.getSize()-1), 4999.5f);
00955 }
00956 
00957 static void Image_xx_row_ops_xx_1(TestSuite& suite)
00958 {
00959   const float Mdat[]  = { 2.0f, 4.0f, 6.0f, 8.0f,
00960                           6.0f, 12.0f, 18.0f, 24.0f };
00961 
00962   const Image<float> M(&Mdat[0], 4, 2);
00963 
00964   {
00965     const float dat[] = { 4.0f, 8.0f, 12.0f, 16.0f };
00966     REQUIRE_EQFP(meanRow(M), Image<float>(&dat[0], 4, 1), 1e-5);
00967   }
00968 
00969   const float vdat[] = { 1.0f, 2.0f, 3.0f, 4.0f };
00970 
00971   const Image<float> v(&vdat[0], 4, 1);
00972 
00973   {
00974     const float dat[] = { 3.0f, 6.0f, 9.0f, 12.0f,
00975                           7.0f, 14.0f, 21.0f, 28.0f };
00976     REQUIRE_EQFP(addRow(M, v), Image<float>(&dat[0], 4, 2), 1e-5);
00977   }
00978 
00979   {
00980     const float dat[] = { 1.0f, 2.0f, 3.0f, 4.0f,
00981                           5.0f, 10.0f, 15.0f, 20.0f };
00982     REQUIRE_EQFP(subtractRow(M, v), Image<float>(&dat[0], 4, 2), 1e-5);
00983   }
00984 
00985   {
00986     const float dat[] = { 2.0f, 8.0f, 18.0f, 32.0f,
00987                           6.0f, 24.0f, 54.0f, 96.0f };
00988     REQUIRE_EQFP(multiplyRow(M, v), Image<float>(&dat[0], 4, 2), 1e-5);
00989   }
00990 
00991   {
00992     const float dat[] = { 2.0f, 2.0f, 2.0f, 2.0f,
00993                           6.0f, 6.0f, 6.0f, 6.0f };
00994     REQUIRE_EQFP(divideRow(M, v), Image<float>(&dat[0], 4, 2), 1e-5);
00995   }
00996 
00997 }
00998 
00999 //---------------------------------------------------------------------
01000 //
01001 // Drawing functions
01002 //
01003 //---------------------------------------------------------------------
01004 
01005 static void Image_xx_emptyArea_xx_1(TestSuite& suite)
01006 {
01007   Image<byte> img(100, 100, NO_INIT);
01008 
01009   // fill with [0..2]
01010   Image<byte>::iterator itr = img.beginw(), stop = img.endw();
01011   int val = 0;
01012   while (itr != stop) *itr++ = (val++) % 3;
01013 
01014   REQUIRE_EQ(emptyArea(img), 3334);
01015 }
01016 
01017 //---------------------------------------------------------------------
01018 //
01019 // MathOps
01020 //
01021 //---------------------------------------------------------------------
01022 
01023 static void Image_xx_mean_xx_1(TestSuite& suite)
01024 {
01025   Image<byte> img = generateImage<byte>(10, 10, Counter(0));
01026 
01027   REQUIRE_EQ(mean(img), 49.5);
01028 }
01029 
01030 static void Image_xx_sum_xx_1(TestSuite& suite)
01031 {
01032   Image<byte> img = generateImage<byte>(10, 10, Counter(0));
01033 
01034   REQUIRE_EQ(sum(img), 4950.0);
01035 }
01036 
01037 static void Image_xx_sum_xx_2(TestSuite& suite)
01038 {
01039   // Empty image
01040   Image<byte> img;
01041 
01042   REQUIRE_EQ(sum(img), 0.0);
01043 }
01044 
01045 static void Image_xx_rangeOf_xx_1(TestSuite& suite)
01046 {
01047   Image<byte> img(1,1, NO_INIT); img.setVal(0, 3);
01048 
01049   Range<byte> rng = rangeOf(img);
01050   REQUIRE_EQ(rng.min(), 3);
01051   REQUIRE_EQ(rng.max(), 3);
01052 }
01053 
01054 static void Image_xx_rangeOf_xx_2(TestSuite& suite)
01055 {
01056   float data[] = { 1.f, -32.f, 14.f, -17.f, 21.f, -9.f };
01057 
01058   Image<float> img(data, 6, 1);
01059 
01060   Range<float> rng = rangeOf(img);
01061   REQUIRE_EQ(rng.min(), -32.f);
01062   REQUIRE_EQ(rng.max(), 21.f);
01063 }
01064 
01065 static void Image_xx_remapRange_xx_1(TestSuite& suite)
01066 {
01067   float data[] = { 0.f, 1.f, 2.f, 3.f, 4.f };
01068 
01069   Image<float> img(data, 5, 1);
01070 
01071   Image<float> scaled = remapRange(img,
01072                                    Range<float>(0.f, 10.f),
01073                                    Range<float>(1.f, 2.f));
01074 
01075   float expected_data[] = { 1.0f, 1.1f, 1.2f, 1.3f, 1.4f };
01076 
01077   Image<float> expected(expected_data, 5, 1);
01078 
01079   REQUIRE_EQ(scaled, expected);
01080 }
01081 
01082 static void Image_xx_squared_xx_1(TestSuite& suite)
01083 {
01084   Image<float> arr = generateImage<float>(1,11,Counter(0));
01085 
01086   float expected_data[] = {
01087     0.f, 1.f, 4.f, 9.f, 16.f, 25.f, 36.f, 49.f, 64.f, 81.f, 100.f };
01088 
01089   Image<float> expected(expected_data, 1, 11);
01090 
01091   REQUIRE_EQ(squared(arr), expected);
01092 }
01093 
01094 static void Image_xx_toPower_xx_1(TestSuite& suite)
01095 {
01096   Image<float> arr = generateImage<float>(1,11,Counter(0));
01097 
01098   float expected_data[] = {
01099     0.f, 1.f, 8.f, 27.f, 64.f, 125.f, 216.f, 343.f, 512.f, 729.f, 1000.f };
01100 
01101   Image<float> expected(expected_data, 1, 11);
01102 
01103   REQUIRE_EQ(toPower(arr, 3.0), expected);
01104 }
01105 
01106 static void Image_xx_toPower_xx_2(TestSuite& suite)
01107 {
01108   Image<byte> arr = generateImage<float>(1,11,Counter(0));
01109 
01110   byte expected_data[] = { 0, 1, 2, 5, 8, 11, 14, 18, 22, 27, 31 };
01111 
01112   Image<byte> expected(expected_data, 1, 11);
01113   Image<byte> result = toPower(arr, 1.5);
01114 
01115   REQUIRE_EQ(result, expected);
01116 }
01117 
01118 static void Image_xx_quadEnergy_xx_1(TestSuite& suite)
01119 {
01120   byte a_data[4] = { 3, 5, 7, 9 };
01121   byte b_data[4] = { 2, 4, 6, 8 };
01122 
01123   Image<byte> a(a_data, 2, 2);
01124   Image<byte> b(b_data, 2, 2);
01125 
01126   Image<byte> res = quadEnergy(a, b);
01127 
01128   REQUIRE_EQ((int)res.getVal(0), 3); // 3.60555
01129   REQUIRE_EQ((int)res.getVal(1), 6); // 6.40312
01130   REQUIRE_EQ((int)res.getVal(2), 9); // 9.21954
01131   REQUIRE_EQ((int)res.getVal(3), 12); // 12.04159
01132 }
01133 
01134 static void Image_xx_overlay_xx_1(TestSuite& suite)
01135 {
01136   float top_data[4] =    { 1.0, 2.0, 3.0, 4.0 };
01137   float bottom_data[4] = { 5.0, 10.0, 15.0, 20.0 };
01138 
01139   Image<float> top(top_data, 2, 2);
01140   Image<float> bottom(bottom_data, 2, 2);
01141 
01142   Image<float> res = overlay(top, bottom, 75.0);
01143 
01144   REQUIRE_EQ(res.getVal(0), 4.0f);
01145   REQUIRE_EQ(res.getVal(1), 8.0f);
01146   REQUIRE_EQ(res.getVal(2), 12.0f);
01147   REQUIRE_EQ(res.getVal(3), 16.0f);
01148 }
01149 
01150 static void Image_xx_exp_xx_1(TestSuite& suite)
01151 {
01152   const double d[4] = { -1.0, 0.0, 1.0, 2.5 };
01153   const double e[4] = { 0.3679, 1.0, 2.7183, 12.1825 };
01154 
01155   Image<double> in(&d[0], 4, 1);
01156   Image<double> out(&e[0], 4, 1);
01157 
01158   REQUIRE_EQFP(exp(in), out, 1e-3);
01159 }
01160 
01161 static void Image_xx_log_xx_1(TestSuite& suite)
01162 {
01163   const double d[4] = { 0.1, 1.0, 2.7183, 10000.0 };
01164   const double l[4] = { -2.3026, 0.0, 1.0, 9.2103 };
01165 
01166   Image<double> in(&d[0], 4, 1);
01167   Image<double> out(&l[0], 4, 1);
01168 
01169   REQUIRE_EQFP(log(in), out, 1e-3);
01170 }
01171 
01172 static void Image_xx_log10_xx_1(TestSuite& suite)
01173 {
01174   const double d[4] = { 0.1, 1.0, 2.7183, 10000.0 };
01175   const double l[4] = { -1.0, 0.0, 0.4343, 4 };
01176 
01177   Image<double> in(&d[0], 4, 1);
01178   Image<double> out(&l[0], 4, 1);
01179 
01180   REQUIRE_EQFP(log10(in), out, 1e-3);
01181 }
01182 
01183 static void Image_xx_getMaskedMinMax_xx_1(TestSuite& suite)
01184 {
01185   const byte d[4] = { 1, 2, 3, 4 };
01186   const byte m[4] = { 0, 1, 1, 0 };
01187 
01188   Image<byte> img(&d[0], 4, 1);
01189   Image<byte> msk(&m[0], 4, 1);
01190 
01191   byte mini, maxi, mino, maxo;
01192   getMaskedMinMax(img, msk, mini, maxi, mino, maxo);
01193 
01194   REQUIRE_EQ(mini, byte(2));
01195   REQUIRE_EQ(maxi, byte(3));
01196   REQUIRE_EQ(mino, byte(1));
01197   REQUIRE_EQ(maxo, byte(4));
01198 }
01199 
01200 static void Image_xx_getMaskedMinMaxAvg_xx_1(TestSuite& suite)
01201 {
01202   const float d[4] = { 1.0F, 2.0F, 3.0F, 4.0F };
01203   const byte m[4] = { 0, 1, 1, 0 };
01204 
01205   Image<float> img(&d[0], 4, 1);
01206   Image<byte> msk(&m[0], 4, 1);
01207 
01208   float mini, maxi, avg;
01209   getMaskedMinMaxAvg(img, msk, mini, maxi, avg);
01210 
01211   REQUIRE_EQ(mini, 2.0F);
01212   REQUIRE_EQ(maxi, 3.0F);
01213   REQUIRE_EQ(avg, 2.5F);
01214 }
01215 
01216 //---------------------------------------------------------------------
01217 //
01218 // MatrixOps
01219 //
01220 //---------------------------------------------------------------------
01221 
01222 static void Image_xx_vmMult_xx_1(TestSuite& suite)
01223 {
01224   // test data generated in matlab (same as from
01225   // Image_xx_matrixMult_xx_3())
01226   const float a[] =
01227     {
01228       9.5012929e-01,  4.8598247e-01,  4.5646767e-01,  4.4470336e-01,  9.2181297e-01,  4.0570621e-01,  4.1027021e-01,
01229       2.3113851e-01,  8.9129897e-01,  1.8503643e-02,  6.1543235e-01,  7.3820725e-01,  9.3546970e-01,  8.9364953e-01,
01230       6.0684258e-01,  7.6209683e-01,  8.2140716e-01,  7.9193704e-01,  1.7626614e-01,  9.1690444e-01,  5.7891305e-02
01231     };
01232 
01233   const float b_data[] =
01234     {
01235       3.5286813e-01,  2.7218792e-01,  4.1864947e-01,  6.8127716e-01,
01236       8.1316650e-01,  1.9881427e-01,  8.4622142e-01,  3.7948102e-01,
01237       9.8613007e-03,  1.5273927e-02,  5.2515250e-01,  8.3179602e-01,
01238       1.3889088e-01,  7.4678568e-01,  2.0264736e-01,  5.0281288e-01,
01239       2.0276522e-01,  4.4509643e-01,  6.7213747e-01,  7.0947139e-01,
01240       1.9872174e-01,  9.3181458e-01,  8.3811845e-01,  4.2889237e-01,
01241       6.0379248e-01,  4.6599434e-01,  1.9639514e-02,  3.0461737e-01
01242     };
01243 
01244   const float c[] =
01245     {
01246       1.3119739e+00,  1.6738263e+00,  2.1065254e+00,  2.3879927e+00,
01247       1.7671561e+00,  2.3166881e+00,  2.2831973e+00,  2.0177129e+00,
01248       1.2048438e+00,  1.8804617e+00,  2.3788915e+00,  2.3200124e+00
01249     };
01250 
01251   const Image<float> b(b_data, 4, 7);
01252 
01253   // this should use dgemv from lapack if lapack is available
01254 
01255   typedef Image<float> VEC;
01256 
01257   REQUIRE_EQFP(vmMult(VEC(a+7*0, 7, 1), b), VEC(c+4*0, 4, 1), 1e-5);
01258   REQUIRE_EQFP(vmMult(VEC(a+7*1, 7, 1), b), VEC(c+4*1, 4, 1), 1e-5);
01259   REQUIRE_EQFP(vmMult(VEC(a+7*2, 7, 1), b), VEC(c+4*2, 4, 1), 1e-5);
01260 
01261   // and now repeat using matrixMult(), since vmMult() is just a
01262   // special case of matrixMult()
01263 
01264   REQUIRE_EQFP(matrixMult(VEC(a+7*0, 7, 1), b), VEC(c+4*0, 4, 1), 1e-5);
01265   REQUIRE_EQFP(matrixMult(VEC(a+7*1, 7, 1), b), VEC(c+4*1, 4, 1), 1e-5);
01266   REQUIRE_EQFP(matrixMult(VEC(a+7*2, 7, 1), b), VEC(c+4*2, 4, 1), 1e-5);
01267 }
01268 
01269 static void Image_xx_vmMult_xx_2(TestSuite& suite)
01270 {
01271   // test data generated in matlab (same as first row from
01272   // Image_xx_matrixMult_xx_4())
01273   const double d[] =
01274     {
01275       1.8965375e-01,  8.1797434e-01,  6.2131013e-01,  2.9872301e-01,  6.4052650e-01,  7.6795039e-01,  9.3338011e-01,  1.2862575e-02,  6.9266939e-01,  2.7310247e-01,  9.9429549e-01,  2.3788031e-01,
01276       1.9343116e-01,  6.6022756e-01,  7.9482108e-01,  6.6144258e-01,  2.0906940e-01,  9.7084494e-01,  6.8333232e-01,  3.8396729e-01,  8.4079061e-02,  2.5476930e-01,  4.3979086e-01,  6.4583125e-01,
01277       6.8222322e-01,  3.4197062e-01,  9.5684345e-01,  2.8440859e-01,  3.7981837e-01,  9.9008259e-01,  2.1255986e-01,  6.8311597e-01,  4.5435515e-01,  8.6560348e-01,  3.4004795e-01,  9.6688742e-01,
01278       3.0276440e-01,  2.8972590e-01,  5.2259035e-01,  4.6922429e-01,  7.8332865e-01,  7.8886169e-01,  8.3923824e-01,  9.2842462e-02,  4.4182830e-01,  2.3235037e-01,  3.1421731e-01,  6.6493121e-01,
01279       5.4167385e-01,  3.4119357e-01,  8.8014221e-01,  6.4781123e-02,  6.8084575e-01,  4.3865853e-01,  6.2878460e-01,  3.5338324e-02,  3.5325046e-01,  8.0487174e-01,  3.6507839e-01,  8.7038103e-01,
01280       1.5087298e-01,  5.3407902e-01,  1.7295614e-01,  9.8833494e-01,  4.6109513e-01,  4.9831130e-01,  1.3377275e-01,  6.1239548e-01,  1.5360636e-01,  9.0839754e-01,  3.9323955e-01,  9.9273048e-03,
01281       6.9789848e-01,  7.2711322e-01,  9.7974690e-01,  5.8279168e-01,  5.6782871e-01,  2.1396333e-01,  2.0713273e-01,  6.0854036e-01,  6.7564465e-01,  2.3189432e-01,  5.9152520e-01,  1.3700989e-01,
01282       3.7837300e-01,  3.0929016e-01,  2.7144726e-01,  4.2349626e-01,  7.9421065e-01,  6.4349229e-01,  6.0719894e-01,  1.5759818e-02,  6.9921333e-01,  2.3931256e-01,  1.1974662e-01,  8.1875583e-01,
01283       8.6001160e-01,  8.3849604e-01,  2.5232935e-01,  5.1551175e-01,  5.9182593e-02,  3.2003558e-01,  6.2988785e-01,  1.6354934e-02,  7.2750913e-01,  4.9754484e-02,  3.8128797e-02,  4.3016605e-01,
01284       8.5365513e-01,  5.6807246e-01,  8.7574190e-01,  3.3395148e-01,  6.0286909e-01,  9.6009860e-01,  3.7047683e-01,  1.9007459e-01,  4.7838438e-01,  7.8384075e-02,  4.5859795e-01,  8.9032172e-01,
01285       5.9356291e-01,  3.7041356e-01,  7.3730599e-01,  4.3290660e-01,  5.0268804e-02,  7.2663177e-01,  5.7514778e-01,  5.8691847e-01,  5.5484199e-01,  6.4081541e-01,  8.6986735e-01,  7.3490821e-01,
01286       4.9655245e-01,  7.0273991e-01,  1.3651874e-01,  2.2594987e-01,  4.1537486e-01,  4.1195321e-01,  4.5142483e-01,  5.7581090e-02,  1.2104711e-01,  1.9088657e-01,  9.3423652e-01,  6.8732359e-01,
01287       8.9976918e-01,  5.4657115e-01,  1.1756687e-02,  5.7980687e-01,  3.0499868e-01,  7.4456578e-01,  4.3895325e-02,  3.6756804e-01,  4.5075394e-01,  8.4386950e-01,  2.6444917e-01,  3.4611197e-01,
01288       8.2162916e-01,  4.4488020e-01,  8.9389797e-01,  7.6036501e-01,  8.7436717e-01,  2.6794725e-01,  2.7185123e-02,  6.3145116e-01,  7.1588295e-01,  1.7390025e-01,  1.6030034e-01,  1.6603474e-01,
01289       6.4491038e-01,  6.9456724e-01,  1.9913807e-01,  5.2982312e-01,  1.5009499e-02,  4.3992431e-01,  3.1268505e-01,  7.1763442e-01,  8.9284161e-01,  1.7079281e-01,  8.7285526e-01,  1.5561258e-01
01290     };
01291 
01292   const double e_data[] =
01293     {
01294       1.9111631e-01,  4.9162489e-02,  7.5366963e-01,  5.4878213e-01,  4.2525316e-01,  4.8496372e-01,  5.4851281e-01,  8.3881007e-02,  2.9198392e-01,  7.5455138e-01,  4.7404145e-01,  6.1011358e-01,  7.6943640e-01,  7.1168466e-02,  4.0180434e-01,  6.6405187e-01,  1.6627012e-01,  7.5947939e-01,
01295       4.2245153e-01,  6.9318045e-01,  7.9387177e-01,  9.3158335e-01,  5.9466337e-01,  1.1461282e-01,  2.6176957e-01,  9.4546279e-01,  8.5796351e-01,  7.9112320e-01,  9.0898935e-01,  7.0149260e-01,  4.4416162e-01,  3.1428029e-01,  3.0768794e-01,  7.2406171e-01,  3.9390601e-01,  9.4975928e-01,
01296       8.5597571e-01,  6.5010641e-01,  9.1995721e-01,  3.3519743e-01,  5.6573857e-01,  6.6485557e-01,  5.9734485e-01,  9.1594246e-01,  3.3575514e-01,  8.1495207e-01,  5.9624714e-01,  9.2196203e-02,  6.2062012e-01,  6.0838366e-01,  4.1156796e-01,  2.8163360e-01,  5.2075748e-01,  5.5793851e-01,
01297       4.9024999e-01,  9.8298778e-01,  8.4472150e-01,  6.5553106e-01,  7.1654240e-01,  3.6537389e-01,  4.9277997e-02,  6.0198742e-01,  6.8020385e-01,  6.7000386e-01,  3.2895530e-01,  4.2488914e-01,  9.5168928e-01,  1.7502018e-01,  2.8593923e-01,  2.6181868e-01,  7.1812397e-01,  1.4233016e-02,
01298       8.1593477e-01,  5.5267324e-01,  3.6775288e-01,  3.9190421e-01,  5.1131145e-01,  1.4004446e-01,  5.7105749e-01,  2.5356058e-01,  5.3444421e-02,  2.0087641e-01,  4.7819443e-01,  3.7557666e-01,  6.4000966e-01,  6.2102743e-01,  3.9412761e-01,  7.0847140e-01,  5.6918952e-01,  5.9617708e-01,
01299       4.6076983e-01,  4.0007352e-01,  6.2080133e-01,  6.2731479e-01,  7.7640121e-01,  5.6677280e-01,  7.0085723e-01,  8.7345081e-01,  3.5665554e-01,  2.7308816e-01,  5.9717078e-01,  1.6615408e-01,  2.4732763e-01,  2.4595993e-01,  5.0301449e-01,  7.8385902e-01,  4.6080617e-01,  8.1620571e-01,
01300       4.5735438e-01,  1.9878852e-01,  7.3127726e-01,  6.9908014e-01,  4.8934548e-01,  8.2300831e-01,  9.6228826e-01,  5.1340071e-01,  4.9830460e-01,  6.2623464e-01,  1.6144875e-01,  8.3315146e-01,  3.5270199e-01,  5.8735822e-01,  7.2197985e-01,  9.8615781e-01,  4.4530705e-01,  9.7709235e-01,
01301       4.5068888e-01,  6.2520102e-01,  1.9389318e-01,  3.9718395e-01,  1.8590445e-01,  6.7394863e-01,  7.5051823e-01,  7.3265065e-01,  4.3444054e-01,  5.3685169e-01,  8.2947425e-01,  8.3863970e-01,  1.8786048e-01,  5.0605345e-01,  3.0620855e-01,  4.7334271e-01,  8.7744606e-02,  2.2190808e-01,
01302       4.1221906e-01,  7.3336280e-01,  9.0481233e-01,  4.1362890e-01,  7.0063541e-01,  9.9944730e-01,  7.3999305e-01,  4.2222659e-01,  5.6245842e-01,  5.9504051e-02,  9.5612241e-01,  4.5161403e-01,  4.9064436e-01,  4.6477892e-01,  1.1216371e-01,  9.0281883e-01,  4.4348322e-01,  7.0368367e-01,
01303       9.0160982e-01,  3.7588548e-01,  5.6920575e-01,  6.5521295e-01,  9.8270880e-01,  9.6163641e-01,  4.3187339e-01,  9.6137000e-01,  6.1662113e-01,  8.8961759e-02,  5.9554800e-01,  9.5660138e-01,  4.0927433e-01,  5.4141893e-01,  4.4328996e-01,  4.5105876e-01,  3.6629985e-01,  5.2206092e-01,
01304       5.5839392e-03,  9.8764629e-03,  6.3178993e-01,  8.3758510e-01,  8.0663775e-01,  5.8862165e-02,  6.3426596e-01,  7.2059239e-02,  1.1333998e-01,  2.7130817e-01,  2.8748213e-02,  1.4715324e-01,  4.6352558e-01,  9.4232657e-01,  4.6676255e-01,  8.0451681e-01,  3.0253382e-01,  9.3289706e-01,
01305       2.9740568e-01,  4.1985781e-01,  2.3441296e-01,  3.7160803e-01,  7.0356766e-01,  3.6031117e-01,  8.0302634e-01,  5.5340797e-01,  8.9825174e-01,  4.0907232e-01,  8.1211782e-01,  8.6993293e-01,  6.1094355e-01,  3.4175909e-01,  1.4668875e-02,  8.2886448e-01,  8.5184470e-01,  7.1335444e-01
01306     };
01307 
01308   const double f[] =
01309     {
01310       2.9772969e+00,  2.8490411e+00,  4.4797086e+00,  4.0472153e+00,  4.2385898e+00,  3.1089057e+00,  3.9680287e+00,  3.6182944e+00,  2.8321589e+00,  2.8590936e+00,  3.2751040e+00,  2.9576420e+00,  3.1684692e+00,  3.3303050e+00,  2.6519174e+00,  4.6993431e+00,  2.9377072e+00,  4.9226116e+00,
01311       2.8828908e+00,  2.9468518e+00,  3.8639357e+00,  3.5524610e+00,  3.7833252e+00,  2.9278979e+00,  3.5016651e+00,  3.9692976e+00,  3.0388124e+00,  3.1115468e+00,  3.2611307e+00,  2.9748704e+00,  2.9958628e+00,  2.5970407e+00,  2.3159149e+00,  3.8482168e+00,  2.8993006e+00,  3.9599320e+00,
01312       3.6616983e+00,  3.3154566e+00,  4.2936709e+00,  3.7892124e+00,  4.5560450e+00,  4.0146890e+00,  4.3795135e+00,  4.5824720e+00,  3.4797825e+00,  3.1939967e+00,  4.4170725e+00,  3.8467199e+00,  3.5581161e+00,  3.0685804e+00,  2.4724131e+00,  4.4983547e+00,  3.2227638e+00,  4.5532449e+00,
01313       2.8770496e+00,  2.6837391e+00,  3.6312439e+00,  3.1895117e+00,  3.6330218e+00,  2.9321011e+00,  3.6152253e+00,  3.2475376e+00,  2.6380256e+00,  2.5503276e+00,  3.0408538e+00,  2.8843431e+00,  3.0061753e+00,  2.5875682e+00,  2.2089052e+00,  4.0333769e+00,  2.9073422e+00,  3.9545291e+00,
01314       3.2261417e+00,  2.5285158e+00,  3.7453372e+00,  3.2509103e+00,  3.9258666e+00,  3.2580602e+00,  3.7827043e+00,  3.5485848e+00,  2.8301733e+00,  2.6563408e+00,  3.3658067e+00,  3.3009714e+00,  3.1525772e+00,  2.8519437e+00,  2.2367581e+00,  4.0317027e+00,  2.9054567e+00,  4.2438312e+00,
01315       2.7175339e+00,  2.7874049e+00,  3.1339862e+00,  3.1080394e+00,  3.3142479e+00,  2.5340986e+00,  2.3388486e+00,  3.3125004e+00,  2.4677117e+00,  2.1814506e+00,  2.7400965e+00,  2.7884337e+00,  2.6173022e+00,  2.1913543e+00,  1.8988358e+00,  2.8064566e+00,  2.1689501e+00,  2.6368829e+00,
01316       3.0274399e+00,  3.2152336e+00,  4.2571178e+00,  3.4918421e+00,  3.6468027e+00,  3.0499596e+00,  3.4026987e+00,  3.5039376e+00,  2.7403580e+00,  3.1970256e+00,  3.6175464e+00,  2.9387411e+00,  3.4106452e+00,  2.8549384e+00,  2.1980184e+00,  3.7847895e+00,  2.5788601e+00,  3.8722196e+00,
01317       2.6204453e+00,  2.6003722e+00,  3.3132585e+00,  2.8606140e+00,  3.4053166e+00,  2.7714573e+00,  3.3263859e+00,  2.9014815e+00,  2.6262746e+00,  2.1894414e+00,  3.1162571e+00,  2.8516770e+00,  2.8813169e+00,  2.2267207e+00,  1.8123421e+00,  3.8500517e+00,  2.7820085e+00,  3.6468303e+00,
01318       1.9514074e+00,  2.3236933e+00,  3.4771615e+00,  2.8717049e+00,  2.8585138e+00,  2.5205856e+00,  2.6733132e+00,  2.6320762e+00,  2.6747614e+00,  2.5998615e+00,  2.9002340e+00,  2.7250883e+00,  2.6814182e+00,  1.6101946e+00,  1.6266525e+00,  3.3724282e+00,  2.1568087e+00,  3.3935804e+00,
01319       3.0410726e+00,  3.0017518e+00,  4.2835098e+00,  3.6473755e+00,  4.1143910e+00,  3.1462353e+00,  4.0665241e+00,  3.7358847e+00,  3.0687749e+00,  3.2723858e+00,  3.8724654e+00,  3.1290047e+00,  3.5834522e+00,  2.7560633e+00,  2.3354593e+00,  4.5214364e+00,  3.1668170e+00,  4.6689449e+00,
01320       3.0465649e+00,  2.9554987e+00,  4.3779882e+00,  3.9635060e+00,  4.4176241e+00,  3.7532293e+00,  4.2454293e+00,  4.0283616e+00,  3.3024941e+00,  3.1422887e+00,  3.7717235e+00,  3.6158122e+00,  3.4025077e+00,  3.2034486e+00,  2.5230896e+00,  4.5324723e+00,  2.9804889e+00,  4.5961247e+00,
01321       1.8121819e+00,  1.8008390e+00,  2.9678931e+00,  3.0937592e+00,  3.1415898e+00,  1.8038475e+00,  2.8690504e+00,  2.3885329e+00,  2.2755915e+00,  2.2616361e+00,  2.4096396e+00,  2.5260285e+00,  2.5221974e+00,  2.3072328e+00,  1.7953609e+00,  3.5424877e+00,  2.2167963e+00,  3.7083622e+00,
01322       2.5259039e+00,  2.5013631e+00,  3.4267798e+00,  3.2397377e+00,  3.5555266e+00,  2.8694980e+00,  2.8299854e+00,  3.1837414e+00,  2.7081506e+00,  2.3140245e+00,  3.2457792e+00,  3.1137285e+00,  2.8586286e+00,  1.9626517e+00,  1.8924617e+00,  3.4525684e+00,  2.2397491e+00,  3.3826311e+00,
01323       3.1189663e+00,  3.3296225e+00,  3.9541879e+00,  3.0499924e+00,  3.3688889e+00,  2.9958105e+00,  3.1656017e+00,  3.2712432e+00,  2.5462913e+00,  2.9841602e+00,  3.6107629e+00,  2.8016577e+00,  3.4604375e+00,  2.4543084e+00,  1.9793549e+00,  3.4650897e+00,  2.5831721e+00,  3.3252931e+00,
01324       2.1014542e+00,  2.6514890e+00,  3.8076366e+00,  3.4706349e+00,  3.4221974e+00,  2.8748121e+00,  3.2500480e+00,  2.9766863e+00,  2.6829611e+00,  2.6263997e+00,  3.2525714e+00,  2.8956778e+00,  2.8036752e+00,  2.5255539e+00,  1.9645498e+00,  3.8438016e+00,  2.1336250e+00,  3.7436370e+00
01325     };
01326 
01327   const Image<double> e(e_data, 18, 12);
01328 
01329   typedef Image<double> VEC;
01330 
01331   // this should use dgemv from lapack if lapack is available
01332 
01333   REQUIRE_EQFP(vmMult(VEC(d+12* 0, 12,1), e), VEC(f+18* 0, 18,1), 1e-5);
01334   REQUIRE_EQFP(vmMult(VEC(d+12* 1, 12,1), e), VEC(f+18* 1, 18,1), 1e-5);
01335   REQUIRE_EQFP(vmMult(VEC(d+12* 2, 12,1), e), VEC(f+18* 2, 18,1), 1e-5);
01336   REQUIRE_EQFP(vmMult(VEC(d+12* 3, 12,1), e), VEC(f+18* 3, 18,1), 1e-5);
01337   REQUIRE_EQFP(vmMult(VEC(d+12* 4, 12,1), e), VEC(f+18* 4, 18,1), 1e-5);
01338   REQUIRE_EQFP(vmMult(VEC(d+12* 5, 12,1), e), VEC(f+18* 5, 18,1), 1e-5);
01339   REQUIRE_EQFP(vmMult(VEC(d+12* 6, 12,1), e), VEC(f+18* 6, 18,1), 1e-5);
01340   REQUIRE_EQFP(vmMult(VEC(d+12* 7, 12,1), e), VEC(f+18* 7, 18,1), 1e-5);
01341   REQUIRE_EQFP(vmMult(VEC(d+12* 8, 12,1), e), VEC(f+18* 8, 18,1), 1e-5);
01342   REQUIRE_EQFP(vmMult(VEC(d+12* 9, 12,1), e), VEC(f+18* 9, 18,1), 1e-5);
01343   REQUIRE_EQFP(vmMult(VEC(d+12*10, 12,1), e), VEC(f+18*10, 18,1), 1e-5);
01344   REQUIRE_EQFP(vmMult(VEC(d+12*11, 12,1), e), VEC(f+18*11, 18,1), 1e-5);
01345   REQUIRE_EQFP(vmMult(VEC(d+12*12, 12,1), e), VEC(f+18*12, 18,1), 1e-5);
01346   REQUIRE_EQFP(vmMult(VEC(d+12*13, 12,1), e), VEC(f+18*13, 18,1), 1e-5);
01347   REQUIRE_EQFP(vmMult(VEC(d+12*14, 12,1), e), VEC(f+18*14, 18,1), 1e-5);
01348 
01349   // and now repeat using matrixMult(), since vmMult() is just a
01350   // special case of matrixMult()
01351 
01352   REQUIRE_EQFP(matrixMult(VEC(d+12* 0, 12,1), e), VEC(f+18* 0, 18,1), 1e-5);
01353   REQUIRE_EQFP(matrixMult(VEC(d+12* 1, 12,1), e), VEC(f+18* 1, 18,1), 1e-5);
01354   REQUIRE_EQFP(matrixMult(VEC(d+12* 2, 12,1), e), VEC(f+18* 2, 18,1), 1e-5);
01355   REQUIRE_EQFP(matrixMult(VEC(d+12* 3, 12,1), e), VEC(f+18* 3, 18,1), 1e-5);
01356   REQUIRE_EQFP(matrixMult(VEC(d+12* 4, 12,1), e), VEC(f+18* 4, 18,1), 1e-5);
01357   REQUIRE_EQFP(matrixMult(VEC(d+12* 5, 12,1), e), VEC(f+18* 5, 18,1), 1e-5);
01358   REQUIRE_EQFP(matrixMult(VEC(d+12* 6, 12,1), e), VEC(f+18* 6, 18,1), 1e-5);
01359   REQUIRE_EQFP(matrixMult(VEC(d+12* 7, 12,1), e), VEC(f+18* 7, 18,1), 1e-5);
01360   REQUIRE_EQFP(matrixMult(VEC(d+12* 8, 12,1), e), VEC(f+18* 8, 18,1), 1e-5);
01361   REQUIRE_EQFP(matrixMult(VEC(d+12* 9, 12,1), e), VEC(f+18* 9, 18,1), 1e-5);
01362   REQUIRE_EQFP(matrixMult(VEC(d+12*10, 12,1), e), VEC(f+18*10, 18,1), 1e-5);
01363   REQUIRE_EQFP(matrixMult(VEC(d+12*11, 12,1), e), VEC(f+18*11, 18,1), 1e-5);
01364   REQUIRE_EQFP(matrixMult(VEC(d+12*12, 12,1), e), VEC(f+18*12, 18,1), 1e-5);
01365   REQUIRE_EQFP(matrixMult(VEC(d+12*13, 12,1), e), VEC(f+18*13, 18,1), 1e-5);
01366   REQUIRE_EQFP(matrixMult(VEC(d+12*14, 12,1), e), VEC(f+18*14, 18,1), 1e-5);
01367 }
01368 
01369 static void Image_xx_matrixMult_xx_1(TestSuite& suite)
01370 {
01371   Image<float> a = generateImage<float>(5, 3, Counter(0));
01372   Image<float> b = generateImage<float>(2, 5, Counter(0));
01373 
01374   float expected_data[] = {
01375      60.0F,    70.0F,
01376     160.0F,   195.0F,
01377     260.0F,   320.0F };
01378 
01379   Image<float> expected(expected_data, 2, 3);
01380 
01381   // this should use sgemm from lapack if lapack is available
01382 
01383   REQUIRE_EQ(matrixMult(a, b), expected);
01384 }
01385 
01386 static void Image_xx_matrixMult_xx_2(TestSuite& suite)
01387 {
01388   Image<byte> a = generateImage<byte>(5, 3, Counter(0));
01389   Image<byte> b = generateImage<byte>(2, 5, Counter(0));
01390 
01391   byte expected_data[] = {
01392      60,    70,
01393     160,   195,
01394     255,   255 };  // last two values clamped
01395 
01396   Image<byte> expected(expected_data, 2, 3);
01397 
01398   // this should NOT use anything from lapack; we use lapack only for
01399   // float and double
01400 
01401   Image<byte> result = matrixMult(a, b); // will clamp
01402 
01403   REQUIRE_EQ(result, expected);
01404 }
01405 
01406 static void Image_xx_matrixMult_xx_3(TestSuite& suite)
01407 {
01408   // test data generated in matlab
01409   const float a_data[] =
01410     {
01411       9.5012929e-01,  4.8598247e-01,  4.5646767e-01,  4.4470336e-01,  9.2181297e-01,  4.0570621e-01,  4.1027021e-01,
01412       2.3113851e-01,  8.9129897e-01,  1.8503643e-02,  6.1543235e-01,  7.3820725e-01,  9.3546970e-01,  8.9364953e-01,
01413       6.0684258e-01,  7.6209683e-01,  8.2140716e-01,  7.9193704e-01,  1.7626614e-01,  9.1690444e-01,  5.7891305e-02
01414     };
01415 
01416   const float b_data[] =
01417     {
01418       3.5286813e-01,  2.7218792e-01,  4.1864947e-01,  6.8127716e-01,
01419       8.1316650e-01,  1.9881427e-01,  8.4622142e-01,  3.7948102e-01,
01420       9.8613007e-03,  1.5273927e-02,  5.2515250e-01,  8.3179602e-01,
01421       1.3889088e-01,  7.4678568e-01,  2.0264736e-01,  5.0281288e-01,
01422       2.0276522e-01,  4.4509643e-01,  6.7213747e-01,  7.0947139e-01,
01423       1.9872174e-01,  9.3181458e-01,  8.3811845e-01,  4.2889237e-01,
01424       6.0379248e-01,  4.6599434e-01,  1.9639514e-02,  3.0461737e-01
01425     };
01426 
01427   const float c_data[] =
01428     {
01429       1.3119739e+00,  1.6738263e+00,  2.1065254e+00,  2.3879927e+00,
01430       1.7671561e+00,  2.3166881e+00,  2.2831973e+00,  2.0177129e+00,
01431       1.2048438e+00,  1.8804617e+00,  2.3788915e+00,  2.3200124e+00
01432     };
01433 
01434   const Image<float> a(a_data, 7, 3);
01435   const Image<float> b(b_data, 4, 7);
01436   const Image<float> c(c_data, 4, 3);
01437 
01438   // this should use dgemm from lapack if lapack is available
01439 
01440   REQUIRE_EQFP(matrixMult(a, b), c, 1e-5);
01441 }
01442 
01443 static void Image_xx_matrixMult_xx_4(TestSuite& suite)
01444 {
01445   // test data generated in matlab
01446   const double d_data[] =
01447     {
01448       1.8965375e-01,  8.1797434e-01,  6.2131013e-01,  2.9872301e-01,  6.4052650e-01,  7.6795039e-01,  9.3338011e-01,  1.2862575e-02,  6.9266939e-01,  2.7310247e-01,  9.9429549e-01,  2.3788031e-01,
01449       1.9343116e-01,  6.6022756e-01,  7.9482108e-01,  6.6144258e-01,  2.0906940e-01,  9.7084494e-01,  6.8333232e-01,  3.8396729e-01,  8.4079061e-02,  2.5476930e-01,  4.3979086e-01,  6.4583125e-01,
01450       6.8222322e-01,  3.4197062e-01,  9.5684345e-01,  2.8440859e-01,  3.7981837e-01,  9.9008259e-01,  2.1255986e-01,  6.8311597e-01,  4.5435515e-01,  8.6560348e-01,  3.4004795e-01,  9.6688742e-01,
01451       3.0276440e-01,  2.8972590e-01,  5.2259035e-01,  4.6922429e-01,  7.8332865e-01,  7.8886169e-01,  8.3923824e-01,  9.2842462e-02,  4.4182830e-01,  2.3235037e-01,  3.1421731e-01,  6.6493121e-01,
01452       5.4167385e-01,  3.4119357e-01,  8.8014221e-01,  6.4781123e-02,  6.8084575e-01,  4.3865853e-01,  6.2878460e-01,  3.5338324e-02,  3.5325046e-01,  8.0487174e-01,  3.6507839e-01,  8.7038103e-01,
01453       1.5087298e-01,  5.3407902e-01,  1.7295614e-01,  9.8833494e-01,  4.6109513e-01,  4.9831130e-01,  1.3377275e-01,  6.1239548e-01,  1.5360636e-01,  9.0839754e-01,  3.9323955e-01,  9.9273048e-03,
01454       6.9789848e-01,  7.2711322e-01,  9.7974690e-01,  5.8279168e-01,  5.6782871e-01,  2.1396333e-01,  2.0713273e-01,  6.0854036e-01,  6.7564465e-01,  2.3189432e-01,  5.9152520e-01,  1.3700989e-01,
01455       3.7837300e-01,  3.0929016e-01,  2.7144726e-01,  4.2349626e-01,  7.9421065e-01,  6.4349229e-01,  6.0719894e-01,  1.5759818e-02,  6.9921333e-01,  2.3931256e-01,  1.1974662e-01,  8.1875583e-01,
01456       8.6001160e-01,  8.3849604e-01,  2.5232935e-01,  5.1551175e-01,  5.9182593e-02,  3.2003558e-01,  6.2988785e-01,  1.6354934e-02,  7.2750913e-01,  4.9754484e-02,  3.8128797e-02,  4.3016605e-01,
01457       8.5365513e-01,  5.6807246e-01,  8.7574190e-01,  3.3395148e-01,  6.0286909e-01,  9.6009860e-01,  3.7047683e-01,  1.9007459e-01,  4.7838438e-01,  7.8384075e-02,  4.5859795e-01,  8.9032172e-01,
01458       5.9356291e-01,  3.7041356e-01,  7.3730599e-01,  4.3290660e-01,  5.0268804e-02,  7.2663177e-01,  5.7514778e-01,  5.8691847e-01,  5.5484199e-01,  6.4081541e-01,  8.6986735e-01,  7.3490821e-01,
01459       4.9655245e-01,  7.0273991e-01,  1.3651874e-01,  2.2594987e-01,  4.1537486e-01,  4.1195321e-01,  4.5142483e-01,  5.7581090e-02,  1.2104711e-01,  1.9088657e-01,  9.3423652e-01,  6.8732359e-01,
01460       8.9976918e-01,  5.4657115e-01,  1.1756687e-02,  5.7980687e-01,  3.0499868e-01,  7.4456578e-01,  4.3895325e-02,  3.6756804e-01,  4.5075394e-01,  8.4386950e-01,  2.6444917e-01,  3.4611197e-01,
01461       8.2162916e-01,  4.4488020e-01,  8.9389797e-01,  7.6036501e-01,  8.7436717e-01,  2.6794725e-01,  2.7185123e-02,  6.3145116e-01,  7.1588295e-01,  1.7390025e-01,  1.6030034e-01,  1.6603474e-01,
01462       6.4491038e-01,  6.9456724e-01,  1.9913807e-01,  5.2982312e-01,  1.5009499e-02,  4.3992431e-01,  3.1268505e-01,  7.1763442e-01,  8.9284161e-01,  1.7079281e-01,  8.7285526e-01,  1.5561258e-01
01463     };
01464 
01465   const double e_data[] =
01466     {
01467       1.9111631e-01,  4.9162489e-02,  7.5366963e-01,  5.4878213e-01,  4.2525316e-01,  4.8496372e-01,  5.4851281e-01,  8.3881007e-02,  2.9198392e-01,  7.5455138e-01,  4.7404145e-01,  6.1011358e-01,  7.6943640e-01,  7.1168466e-02,  4.0180434e-01,  6.6405187e-01,  1.6627012e-01,  7.5947939e-01,
01468       4.2245153e-01,  6.9318045e-01,  7.9387177e-01,  9.3158335e-01,  5.9466337e-01,  1.1461282e-01,  2.6176957e-01,  9.4546279e-01,  8.5796351e-01,  7.9112320e-01,  9.0898935e-01,  7.0149260e-01,  4.4416162e-01,  3.1428029e-01,  3.0768794e-01,  7.2406171e-01,  3.9390601e-01,  9.4975928e-01,
01469       8.5597571e-01,  6.5010641e-01,  9.1995721e-01,  3.3519743e-01,  5.6573857e-01,  6.6485557e-01,  5.9734485e-01,  9.1594246e-01,  3.3575514e-01,  8.1495207e-01,  5.9624714e-01,  9.2196203e-02,  6.2062012e-01,  6.0838366e-01,  4.1156796e-01,  2.8163360e-01,  5.2075748e-01,  5.5793851e-01,
01470       4.9024999e-01,  9.8298778e-01,  8.4472150e-01,  6.5553106e-01,  7.1654240e-01,  3.6537389e-01,  4.9277997e-02,  6.0198742e-01,  6.8020385e-01,  6.7000386e-01,  3.2895530e-01,  4.2488914e-01,  9.5168928e-01,  1.7502018e-01,  2.8593923e-01,  2.6181868e-01,  7.1812397e-01,  1.4233016e-02,
01471       8.1593477e-01,  5.5267324e-01,  3.6775288e-01,  3.9190421e-01,  5.1131145e-01,  1.4004446e-01,  5.7105749e-01,  2.5356058e-01,  5.3444421e-02,  2.0087641e-01,  4.7819443e-01,  3.7557666e-01,  6.4000966e-01,  6.2102743e-01,  3.9412761e-01,  7.0847140e-01,  5.6918952e-01,  5.9617708e-01,
01472       4.6076983e-01,  4.0007352e-01,  6.2080133e-01,  6.2731479e-01,  7.7640121e-01,  5.6677280e-01,  7.0085723e-01,  8.7345081e-01,  3.5665554e-01,  2.7308816e-01,  5.9717078e-01,  1.6615408e-01,  2.4732763e-01,  2.4595993e-01,  5.0301449e-01,  7.8385902e-01,  4.6080617e-01,  8.1620571e-01,
01473       4.5735438e-01,  1.9878852e-01,  7.3127726e-01,  6.9908014e-01,  4.8934548e-01,  8.2300831e-01,  9.6228826e-01,  5.1340071e-01,  4.9830460e-01,  6.2623464e-01,  1.6144875e-01,  8.3315146e-01,  3.5270199e-01,  5.8735822e-01,  7.2197985e-01,  9.8615781e-01,  4.4530705e-01,  9.7709235e-01,
01474       4.5068888e-01,  6.2520102e-01,  1.9389318e-01,  3.9718395e-01,  1.8590445e-01,  6.7394863e-01,  7.5051823e-01,  7.3265065e-01,  4.3444054e-01,  5.3685169e-01,  8.2947425e-01,  8.3863970e-01,  1.8786048e-01,  5.0605345e-01,  3.0620855e-01,  4.7334271e-01,  8.7744606e-02,  2.2190808e-01,
01475       4.1221906e-01,  7.3336280e-01,  9.0481233e-01,  4.1362890e-01,  7.0063541e-01,  9.9944730e-01,  7.3999305e-01,  4.2222659e-01,  5.6245842e-01,  5.9504051e-02,  9.5612241e-01,  4.5161403e-01,  4.9064436e-01,  4.6477892e-01,  1.1216371e-01,  9.0281883e-01,  4.4348322e-01,  7.0368367e-01,
01476       9.0160982e-01,  3.7588548e-01,  5.6920575e-01,  6.5521295e-01,  9.8270880e-01,  9.6163641e-01,  4.3187339e-01,  9.6137000e-01,  6.1662113e-01,  8.8961759e-02,  5.9554800e-01,  9.5660138e-01,  4.0927433e-01,  5.4141893e-01,  4.4328996e-01,  4.5105876e-01,  3.6629985e-01,  5.2206092e-01,
01477       5.5839392e-03,  9.8764629e-03,  6.3178993e-01,  8.3758510e-01,  8.0663775e-01,  5.8862165e-02,  6.3426596e-01,  7.2059239e-02,  1.1333998e-01,  2.7130817e-01,  2.8748213e-02,  1.4715324e-01,  4.6352558e-01,  9.4232657e-01,  4.6676255e-01,  8.0451681e-01,  3.0253382e-01,  9.3289706e-01,
01478       2.9740568e-01,  4.1985781e-01,  2.3441296e-01,  3.7160803e-01,  7.0356766e-01,  3.6031117e-01,  8.0302634e-01,  5.5340797e-01,  8.9825174e-01,  4.0907232e-01,  8.1211782e-01,  8.6993293e-01,  6.1094355e-01,  3.4175909e-01,  1.4668875e-02,  8.2886448e-01,  8.5184470e-01,  7.1335444e-01
01479     };
01480 
01481   const double f_data[] =
01482     {
01483       2.9772969e+00,  2.8490411e+00,  4.4797086e+00,  4.0472153e+00,  4.2385898e+00,  3.1089057e+00,  3.9680287e+00,  3.6182944e+00,  2.8321589e+00,  2.8590936e+00,  3.2751040e+00,  2.9576420e+00,  3.1684692e+00,  3.3303050e+00,  2.6519174e+00,  4.6993431e+00,  2.9377072e+00,  4.9226116e+00,
01484       2.8828908e+00,  2.9468518e+00,  3.8639357e+00,  3.5524610e+00,  3.7833252e+00,  2.9278979e+00,  3.5016651e+00,  3.9692976e+00,  3.0388124e+00,  3.1115468e+00,  3.2611307e+00,  2.9748704e+00,  2.9958628e+00,  2.5970407e+00,  2.3159149e+00,  3.8482168e+00,  2.8993006e+00,  3.9599320e+00,
01485       3.6616983e+00,  3.3154566e+00,  4.2936709e+00,  3.7892124e+00,  4.5560450e+00,  4.0146890e+00,  4.3795135e+00,  4.5824720e+00,  3.4797825e+00,  3.1939967e+00,  4.4170725e+00,  3.8467199e+00,  3.5581161e+00,  3.0685804e+00,  2.4724131e+00,  4.4983547e+00,  3.2227638e+00,  4.5532449e+00,
01486       2.8770496e+00,  2.6837391e+00,  3.6312439e+00,  3.1895117e+00,  3.6330218e+00,  2.9321011e+00,  3.6152253e+00,  3.2475376e+00,  2.6380256e+00,  2.5503276e+00,  3.0408538e+00,  2.8843431e+00,  3.0061753e+00,  2.5875682e+00,  2.2089052e+00,  4.0333769e+00,  2.9073422e+00,  3.9545291e+00,
01487       3.2261417e+00,  2.5285158e+00,  3.7453372e+00,  3.2509103e+00,  3.9258666e+00,  3.2580602e+00,  3.7827043e+00,  3.5485848e+00,  2.8301733e+00,  2.6563408e+00,  3.3658067e+00,  3.3009714e+00,  3.1525772e+00,  2.8519437e+00,  2.2367581e+00,  4.0317027e+00,  2.9054567e+00,  4.2438312e+00,
01488       2.7175339e+00,  2.7874049e+00,  3.1339862e+00,  3.1080394e+00,  3.3142479e+00,  2.5340986e+00,  2.3388486e+00,  3.3125004e+00,  2.4677117e+00,  2.1814506e+00,  2.7400965e+00,  2.7884337e+00,  2.6173022e+00,  2.1913543e+00,  1.8988358e+00,  2.8064566e+00,  2.1689501e+00,  2.6368829e+00,
01489       3.0274399e+00,  3.2152336e+00,  4.2571178e+00,  3.4918421e+00,  3.6468027e+00,  3.0499596e+00,  3.4026987e+00,  3.5039376e+00,  2.7403580e+00,  3.1970256e+00,  3.6175464e+00,  2.9387411e+00,  3.4106452e+00,  2.8549384e+00,  2.1980184e+00,  3.7847895e+00,  2.5788601e+00,  3.8722196e+00,
01490       2.6204453e+00,  2.6003722e+00,  3.3132585e+00,  2.8606140e+00,  3.4053166e+00,  2.7714573e+00,  3.3263859e+00,  2.9014815e+00,  2.6262746e+00,  2.1894414e+00,  3.1162571e+00,  2.8516770e+00,  2.8813169e+00,  2.2267207e+00,  1.8123421e+00,  3.8500517e+00,  2.7820085e+00,  3.6468303e+00,
01491       1.9514074e+00,  2.3236933e+00,  3.4771615e+00,  2.8717049e+00,  2.8585138e+00,  2.5205856e+00,  2.6733132e+00,  2.6320762e+00,  2.6747614e+00,  2.5998615e+00,  2.9002340e+00,  2.7250883e+00,  2.6814182e+00,  1.6101946e+00,  1.6266525e+00,  3.3724282e+00,  2.1568087e+00,  3.3935804e+00,
01492       3.0410726e+00,  3.0017518e+00,  4.2835098e+00,  3.6473755e+00,  4.1143910e+00,  3.1462353e+00,  4.0665241e+00,  3.7358847e+00,  3.0687749e+00,  3.2723858e+00,  3.8724654e+00,  3.1290047e+00,  3.5834522e+00,  2.7560633e+00,  2.3354593e+00,  4.5214364e+00,  3.1668170e+00,  4.6689449e+00,
01493       3.0465649e+00,  2.9554987e+00,  4.3779882e+00,  3.9635060e+00,  4.4176241e+00,  3.7532293e+00,  4.2454293e+00,  4.0283616e+00,  3.3024941e+00,  3.1422887e+00,  3.7717235e+00,  3.6158122e+00,  3.4025077e+00,  3.2034486e+00,  2.5230896e+00,  4.5324723e+00,  2.9804889e+00,  4.5961247e+00,
01494       1.8121819e+00,  1.8008390e+00,  2.9678931e+00,  3.0937592e+00,  3.1415898e+00,  1.8038475e+00,  2.8690504e+00,  2.3885329e+00,  2.2755915e+00,  2.2616361e+00,  2.4096396e+00,  2.5260285e+00,  2.5221974e+00,  2.3072328e+00,  1.7953609e+00,  3.5424877e+00,  2.2167963e+00,  3.7083622e+00,
01495       2.5259039e+00,  2.5013631e+00,  3.4267798e+00,  3.2397377e+00,  3.5555266e+00,  2.8694980e+00,  2.8299854e+00,  3.1837414e+00,  2.7081506e+00,  2.3140245e+00,  3.2457792e+00,  3.1137285e+00,  2.8586286e+00,  1.9626517e+00,  1.8924617e+00,  3.4525684e+00,  2.2397491e+00,  3.3826311e+00,
01496       3.1189663e+00,  3.3296225e+00,  3.9541879e+00,  3.0499924e+00,  3.3688889e+00,  2.9958105e+00,  3.1656017e+00,  3.2712432e+00,  2.5462913e+00,  2.9841602e+00,  3.6107629e+00,  2.8016577e+00,  3.4604375e+00,  2.4543084e+00,  1.9793549e+00,  3.4650897e+00,  2.5831721e+00,  3.3252931e+00,
01497       2.1014542e+00,  2.6514890e+00,  3.8076366e+00,  3.4706349e+00,  3.4221974e+00,  2.8748121e+00,  3.2500480e+00,  2.9766863e+00,  2.6829611e+00,  2.6263997e+00,  3.2525714e+00,  2.8956778e+00,  2.8036752e+00,  2.5255539e+00,  1.9645498e+00,  3.8438016e+00,  2.1336250e+00,  3.7436370e+00
01498     };
01499 
01500   const Image<double> d(d_data, 12, 15);
01501   const Image<double> e(e_data, 18, 12);
01502   const Image<double> f(f_data, 18, 15);
01503 
01504   // this should use dgemm from lapack if lapack is available
01505 
01506   REQUIRE_EQFP(matrixMult(d, e), f, 1e-5);
01507 }
01508 
01509 static void Image_xx_matrixInv_xx_1(TestSuite& suite)
01510 {
01511   float orig_data[] = {
01512     1,     7,     5,     9,
01513     6,     5,     5,     5,
01514     10,    20,    30,    40,
01515     1,     9,     7,     6 };
01516 
01517   Image<float> a(orig_data, 4, 4);
01518 
01519   float expected_data[] = { // from matlab inv() function
01520    0.01529051987768,  0.20489296636086, -0.01529051987768, -0.09174311926605,
01521    0.15290519877676,  0.04892966360856, -0.05290519877676,  0.08256880733945,
01522   -0.36391437308868, -0.07645259938838,  0.06391437308869,  0.18348623853211,
01523    0.19266055045872, -0.01834862385321,  0.00733944954128, -0.15596330275229 };
01524 
01525   Image<float> expected(expected_data, 4, 4);
01526 
01527   REQUIRE_EQFP(matrixInv(a), expected, 1.0e-5F);
01528 }
01529 
01530 static void Image_xx_matrixInv_xx_2(TestSuite& suite)
01531 {
01532   /* test data generated in matlab with:
01533      sz=7;
01534      [y, idx] = sort(rand(sz*sz, 1));
01535      disp(reshape(idx, sz, sz));
01536      disp(inv(reshape(idx, sz, sz)));
01537   */
01538 
01539   const float orig_data7[] =
01540     {
01541       43,    16,    44,    34,    36,    46,    17,
01542       23,    31,     6,    26,    49,    28,    27,
01543       11,     2,     5,     4,     9,    37,    42,
01544       45,     1,    30,    40,    19,    25,    14,
01545       10,    33,     7,    39,    47,    35,    20,
01546       24,    18,     8,    12,    21,    13,    48,
01547       32,    15,    41,    38,    29,    22,     3
01548     };
01549 
01550   const float expected_data7[] =
01551     {
01552         0.0863664417165848,  -0.0342027308610078,  -0.0690509290541315,   0.0268123823662261,   0.0226507977720774,   0.0387060132448695, -0.110298233327886,
01553          0.184717788211439,   -0.158457450073631,   -0.144594411698772,  -0.0120193825757529,      0.1237223361442,    0.114187504191344, -0.192020508088664,
01554        -0.0376325996019747,   0.0173327100498285,   0.0376865299596207,  -0.0313288524314864,  -0.0330709668386202,  -0.0120148878751662, 0.0885582174684409,
01555        -0.0275145031181991,   -0.027622575353721, 0.000948089575441405,   0.0248025225647299,   0.0326718611234568,  0.00303449174780607,0.00913606104042284,
01556         -0.148202066322019,     0.16289455708109,    0.109236859441512,  -0.0133361690172031,   -0.112867758761273,  -0.0943874893011545,  0.169331672554365,
01557         0.0686841039544181,  -0.0444316914804608,  -0.0223629756868543,  0.00298105055676686,   0.0396401960952903,  0.00752975701431266, -0.074898694930778,
01558        -0.0530652065294748,   0.0213069824245555,   0.0404957714365029, -0.00485087186723845,  -0.0217336543989586,-0.000840911607400576, 0.0563155454935637
01559     };
01560 
01561   Image<float> a7(orig_data7, 7, 7);
01562   Image<float> expected7(expected_data7, 7, 7);
01563 
01564   REQUIRE_EQFP(matrixInv(a7), expected7, 1.0e-5F);
01565 }
01566 
01567 static void Image_xx_matrixInv_xx_3(TestSuite& suite)
01568 {
01569   /* test data generated in matlab with:
01570      sz=14;
01571      [y, idx] = sort(rand(sz*sz, 1));
01572      disp(reshape(idx, sz, sz));
01573      disp(inv(reshape(idx, sz, sz)));
01574   */
01575 
01576   const float orig_data14[] =
01577     {
01578         6,  160,  195,  153,    5,   32,  104,   20,  109,   66,  196,  128,  122,   21,
01579       191,   90,   19,  141,   24,   65,  108,   79,   58,  132,  168,   37,   30,  150,
01580       163,   45,  145,  107,  177,   87,   44,  190,   71,   29,   35,  169,  123,   69,
01581       114,   48,  133,   22,  156,  161,   38,   88,  142,   23,  179,   93,   11,  189,
01582        59,  126,   72,   82,   27,  184,  136,   34,  116,  164,  158,    9,  187,  131,
01583        84,  110,   57,  151,    1,  129,   86,   49,  139,   46,  165,   67,   81,  112,
01584        54,  121,  167,  134,  152,  182,  157,  180,   89,   95,   14,  174,  127,  125,
01585       100,  176,  102,   85,  103,  173,  147,   17,  130,   51,   75,   42,   73,   77,
01586       140,  143,   97,   55,  137,  124,   36,   60,   13,   83,    4,  115,   91,   53,
01587        78,   39,  166,   47,  154,  181,   74,  146,  144,   26,   64,   94,  172,   62,
01588        68,  135,  155,  185,   28,  138,  178,   33,    3,   40,   63,  193,   16,  194,
01589       183,   15,   80,   12,    7,  148,   99,  113,   98,   61,    8,   50,  105,   41,
01590       101,    2,  186,   31,   76,  162,  149,  192,   25,  117,   92,  175,   70,  170,
01591       118,   96,  159,  120,  119,  171,   56,  106,   18,   43,  188,  111,   10,   52
01592     };
01593 
01594   const float expected_data14[] =
01595     {
01596       7.53563392062889e-05,     0.000461707861660145,      0.00372449797232745,     0.000976014170193408,      0.00110971554872798,     -0.00275736817253676,      -0.0030838794331058,     0.000644139519418342,    -0.000373763475101289,     -0.00242814669384377,      0.00151417461528592,      0.00405285048664069,     -0.00191325733529331,     0.000437202785289814,
01597       -0.00205231848684335,        0.161112139816245,       -0.233529578918986,      -0.0998048351837866,       -0.195973606570308,       0.0976133973055097,      -0.0626092469087169,      -0.0102011444468062,        0.155621382432984,        0.319331712618087,     -0.00981464989785451,        -0.11723015374426,       0.0959682935636109,      -0.0662733175762567,
01598        0.00617429918685153,       0.0838497332111019,        -0.12088634449044,      -0.0370600916526799,      -0.0908447091405074,        0.024365092863746,      -0.0189883694308366,      -0.0212361627308311,       0.0694863490875842,        0.158816697415575,      0.00394414867624216,      -0.0414965239062269,       0.0272880174719444,      -0.0271786546398205,
01599        0.00229235617311322,      -0.0430798220069746,       0.0655717066455695,       0.0328171454409947,       0.0595232785391925,      -0.0360331650829408,        0.027782699369807,     -0.00631120804640155,      -0.0487762021179046,      -0.0927695791891363,      0.00753820406482533,       0.0405404686468824,      -0.0415702670292879,        0.023412757449553,
01600      -0.000773962977241737,      -0.0833884802715835,        0.124835722682279,       0.0495325285143792,        0.100808690170754,      -0.0494642249314272,         0.02960502027195,       0.0132651266524234,      -0.0791908401186713,       -0.165204993489785,      0.00235110811386487,       0.0530602105499828,      -0.0456738197005483,       0.0333464397653038,
01601       -0.00227263966037385,      -0.0419536956512115,        0.052276980269038,       0.0233534263813399,       0.0473461935710808,      -0.0190575175852659,       0.0163974953052667,      0.00129245475276669,      -0.0347738950301648,      -0.0765962563150846,      0.00221586597406838,       0.0295047899075718,      -0.0232165419375637,       0.0192687944398009,
01602       -0.00243408179849765,        -0.05146565904427,        0.078601083198067,       0.0209591798695574,       0.0575525797581148,      -0.0223995920940085,      0.00891341551471089,       0.0208503321070358,      -0.0501011810263884,      -0.0986858023152499,    -0.000313241141926206,       0.0260014317223912,      -0.0146014966781001,       0.0170531835993851,
01603       -0.00316165731675941,        0.154417515924666,       -0.220502866905236,      -0.0948364444416008,       -0.185737315868655,       0.0913629714277201,      -0.0553673808491966,      -0.0132747302628695,         0.14207612195838,        0.303615391802225,      -0.0105016926531228,        -0.10917933265103,       0.0905415501630788,      -0.0605385696865733,
01604        0.00431962296105473,      -0.0744114741281338,        0.104167579186192,       0.0513392034700611,       0.0873595209074504,      -0.0434430099208895,       0.0361884599841365,      0.00366132423521931,      -0.0708723088378299,       -0.151086293442918,       0.0012921697396745,       0.0586021550281484,      -0.0481225928114504,       0.0278352130701018,
01605        0.00603080726907753,       -0.117028827890343,        0.166291502211568,       0.0799026577873399,        0.146724081508712,      -0.0782854508777231,       0.0584770985886571,     0.000484062857531725,       -0.111273515210444,       -0.243621145463788,      0.00432315988844692,       0.0931472700367292,      -0.0776689408741061,       0.0500031364844012,
01606       -0.00179427989626322,      -0.0129877241534507,       0.0200096511411447,     0.000785980729038293,       0.0118751820514703,      0.00317334498048273,       -0.006027133506779,      0.00933642019990867,     -0.00945936975257917,      -0.0208671802272393,     -0.00348575622888212,     -0.00151864268549087,      0.00525120510517503,      0.00424911581372456,
01607      -6.62200107920678e-06,       -0.153126572929898,        0.214532637971622,       0.0821362342482833,        0.169416047801648,      -0.0662596632338817,       0.0470724122126177,       0.0214654729105009,       -0.129491939723347,       -0.293422791051627,        0.001314817279614,       0.0941185088799686,      -0.0677714609075475,       0.0537656264717411,
01608       -0.00257306548966421,       0.0351531875139322,      -0.0476630134419376,      -0.0283892345334294,       -0.041552450054926,       0.0259333876386372,      -0.0235836020163034,     0.000149894936715443,       0.0362535177337894,       0.0783828511291872,     -0.00096775604298647,      -0.0321788332441728,       0.0268588346486472,      -0.0178747861295432,
01609       -0.00172665693499422,        0.103580989074918,       -0.146449167610552,       -0.056330386951719,       -0.118211250058327,       0.0532027357703076,      -0.0369148821556138,      -0.0144037069277378,       0.0937462253549283,        0.202232551557968,     0.000264533062638735,      -0.0698776598085848,       0.0530908950765443,      -0.0426499130339133
01610     };
01611 
01612   Image<float> a14(orig_data14, 14, 14);
01613   Image<float> expected14(expected_data14, 14, 14);
01614 
01615   REQUIRE_EQFP(matrixInv(a14), expected14, 1.0e-5F);
01616 }
01617 
01618 static void Image_xx_matrixDet_xx_1(TestSuite& suite)
01619 {
01620   float orig_data[] = {
01621     1,     7,     5,     9,
01622     6,     5,     5,     5,
01623     10,    20,    30,    40,
01624     1,     9,     7,     6 };
01625 
01626   Image<float> a(orig_data, 4, 4);
01627 
01628   float expected = 3269.999511718750000F;
01629 
01630   REQUIRE_EQ(matrixDet(a), expected);
01631 }
01632 
01633 static void Image_xx_matrixDet_xx_2(TestSuite& suite)
01634 {
01635   Image<float> a(10, 10, ZEROS);
01636   float expected = 0.0F;
01637 
01638   REQUIRE_EQ(matrixDet(a), expected);
01639 }
01640 
01641 static void Image_xx_matrixDet_xx_3(TestSuite& suite)
01642 {
01643   Image<byte> a = eye<byte>(17); // identity matrix
01644   float expected = 1.0F;
01645 
01646   REQUIRE_EQ(matrixDet(a), expected);
01647 }
01648 
01649 namespace
01650 {
01651   Image<double> svdIdent(const Image<double>& M,
01652                          Image<double>& PI,
01653                          const SvdAlgo algo,
01654                          const SvdFlag flags = 0)
01655   {
01656     Image<double> U;
01657     Image<double> S;
01658     Image<double> V;
01659 
01660     svd(M, U, S, V, algo, flags);
01661 
01662     Image<double> US = matrixMult(U, S);
01663     Image<double> MM = matrixMult(US, transpose(V));
01664 
01665     PI = matrixMult(V, matrixMult(naiveUnstablePseudoInv(S), transpose(U)));
01666 
01667     return MM;
01668   }
01669 }
01670 
01671 static void Image_xx_svd_gsl_xx_1(TestSuite& suite)
01672 {
01673   rutz::urand gen(time((time_t*)0) + getpid());
01674 
01675   Image<double> x(50, 9000, NO_INIT);
01676 
01677   for (Image<double>::iterator itr = x.beginw(), stop = x.endw();
01678        itr != stop;
01679        ++itr)
01680     {
01681       *itr = gen.fdraw();
01682     }
01683 
01684   Image<double> xpi;
01685   Image<double> xx(svdIdent(x, xpi, SVD_GSL, SVD_TALL));
01686 
01687   // we're checking two identities here: first, that we can
01688   // reconstruct the original matrix 'x' from its SVD decomposition,
01689   // and second, that we get the same pseudoinverse whether we build
01690   // it directly with naiveUnstablePseudoInv(), or whether we
01691   // construct it from the SVD decomposition
01692 
01693   const double gsl_err = RMSerr(x, xx);
01694   const double gsl_pi_err = RMSerr(xpi, naiveUnstablePseudoInv(x));
01695 
01696   REQUIRE_LT(gsl_err, 1e-10);
01697   REQUIRE_LT(gsl_pi_err, 1e-10);
01698 }
01699 
01700 static void Image_xx_svd_lapack_xx_1(TestSuite& suite)
01701 {
01702   rutz::urand gen(time((time_t*)0) + getpid());
01703 
01704   Image<double> x(50, 9000, NO_INIT);
01705 
01706   for (Image<double>::iterator itr = x.beginw(), stop = x.endw();
01707        itr != stop;
01708        ++itr)
01709     {
01710       *itr = gen.fdraw();
01711     }
01712 
01713   Image<double> xpi;
01714   Image<double> xx(svdIdent(x, xpi, SVD_LAPACK));
01715 
01716   const double lapack_err = RMSerr(x, xx);
01717   const double lapack_pi_err = RMSerr(xpi, naiveUnstablePseudoInv(x));
01718 
01719   REQUIRE_LT(lapack_err, 1e-10);
01720   REQUIRE_LT(lapack_pi_err, 1e-10);
01721 }
01722 
01723 static void Image_xx_svd_lapack_xx_2(TestSuite& suite)
01724 {
01725   // like the previous test, but here using float instead of double
01726 
01727   rutz::urand_frange gen(time((time_t*)0) + getpid());
01728 
01729   Image<float> x(50, 9000, NO_INIT);
01730   fill(x, gen);
01731 
01732   Image<float> U;
01733   Image<float> S;
01734   Image<float> V;
01735 
01736   svdf(x, U, S, V, SVD_LAPACK);
01737 
01738   Image<float> US = matrixMult(U, S);
01739   Image<float> xx = matrixMult(US, transpose(V));
01740 
01741   const double lapack_err = RMSerr(x, xx);
01742   const double rsq        = corrcoef(x, xx);
01743 
01744   REQUIRE_LT(lapack_err, 1e-5);
01745   REQUIRE_GT(rsq, 0.99);
01746 }
01747 
01748 static void Image_xx_svd_full_xx_1(TestSuite& suite)
01749 {
01750   /* test data from matlab:
01751 
01752      A=rand(9,7);
01753      [U,S,V]=svd(A);
01754      format long g;
01755      disp(A)
01756      disp(U)
01757      disp(S)
01758      disp(V)
01759    */
01760   const double Adata[] = {
01761          0.950129285147175,   0.444703364353194,   0.410270206990945,   0.603792479193819,   0.846221417824324,   0.502812883996251,   0.150872976149765,
01762          0.231138513574288,   0.615432348100095,   0.893649530913534,    0.27218792496996,   0.525152496305172,   0.709471392703387,   0.697898481859863,
01763          0.606842583541787,   0.791937037427035,  0.0578913047842686,   0.198814267761062,   0.202647357650387,   0.428892365340997,   0.378373000512671,
01764            0.4859824687093,   0.921812970744803,      0.352868132217,  0.0152739270290363,   0.672137468474288,   0.304617366869394,    0.86001160488682,
01765          0.891298966148902,   0.738207245810665,   0.813166497303758,   0.746785676564429,   0.838118445052387,   0.189653747547175,   0.853655130662768,
01766          0.762096833027395,   0.176266144494618, 0.00986130066092356,   0.445096432287947,  0.0196395138648175,   0.193431156405215,   0.593562912539682,
01767          0.456467665168341,   0.405706213062095,    0.13889088195695,   0.931814578461665,   0.681277161282135,   0.682223223591384,   0.496552449703103,
01768         0.0185036432482244,   0.935469699107605,   0.202765218560273,   0.465994341675424,   0.379481018027998,   0.302764400776609,    0.89976917516961,
01769          0.821407164295253,   0.916904439913408,    0.19872174266149,   0.418649467727506,   0.831796017609607,   0.541673853898088,   0.821629160735343
01770   };
01771 
01772   const double Udata[] = {
01773         -0.334369457483348,   0.553753246384211,   0.173722104758991,   0.216107949399242,    0.33819994715599,   0.107950179334316,  -0.168945273189193,   0.457659744648732,  -0.375026665540279,
01774         -0.329665554632197,  -0.289771377227679,   0.634134705802461,  -0.018028983235094,  0.0467322256708354,  -0.615149159205802,  0.0907953598669529,  0.0925800794220671,    0.08656814784916,
01775         -0.246139085952845, -0.0548593578229483,   -0.41050144345874,    0.11040680321451,   0.332992352163831,   -0.37647619850007,  -0.618601139886217,  -0.340483123953779,  0.0670115015894877,
01776         -0.338502200326128,  -0.400181962186731,   -0.13227390062104,   0.362805829219031,   0.129457018880407,   0.171533541715475,   0.398807623266607,  -0.305062586901122,  -0.527117278260459,
01777          -0.44489875430374,   0.131261679408881,   0.240577903720863,   0.271982040280096,  -0.592256457043096,   0.318449189950086,  -0.285471727381645,  -0.272222800411694,   0.212618330011173,
01778         -0.198783947890269,   0.257075663136555,  -0.465947906013995, -0.0378515144915132,  -0.542621813915509,  -0.497996499745613,   0.245305115243475,   0.187677943372127,  -0.194987949697117,
01779         -0.324145914503961,   0.328343166397085,  0.0761178782792188,   -0.71190747904549,    0.14722746538287,  0.0786683148078264,   0.192639295168155,  -0.450336123723707, -0.0820783064210453,
01780          -0.29677060429998,  -0.504820108786232,  -0.140000844979403,  -0.466845088254261,  -0.137738046651579,   0.252315401154192,  -0.322375638216978,   0.451927826068197,  -0.169527726112523,
01781         -0.416840705481074, -0.0162676625612421,  -0.285143189435573,  0.0948209656476317,   0.264461771501813,   0.139706911019148,   0.372550868730716,   0.237938856853049,   0.671427163909875
01782   };
01783 
01784   const double Sdata[] = {
01785           4.33980802951066,                  0,                  0,                  0,                  0,                  0,                  0,
01786                          0,    1.1612093946393,                  0,                  0,                  0,                  0,                  0,
01787                          0,                  0,  0.879337316628834,                  0,                  0,                  0,                  0,
01788                          0,                  0,                  0,  0.760487539411249,                  0,                  0,                  0,
01789                          0,                  0,                  0,                  0,  0.658580414390557,                  0,                  0,
01790                          0,                  0,                  0,                  0,                  0,  0.509093207477467,                  0,
01791                          0,                  0,                  0,                  0,                  0,                  0,  0.320075663338178,
01792                          0,                  0,                  0,                  0,                  0,                  0,                  0,
01793                          0,                  0,                  0,                  0,                  0,                  0,                  0
01794   };
01795 
01796   const double Vdata[] = {
01797         -0.403622982097106,   0.578252330821083,  -0.391767249118321,   0.529050685580787, -0.0947464346071052,  -0.245674262341264,-0.00194801953388936,
01798          -0.46392416666584,  -0.478943519182328,  -0.279266979790604,  0.0820353792216147,   0.307808958667134,   0.142898419581493,  -0.596239306165418,
01799         -0.257442552523379,  -0.109255973768973,   0.777953044405826,   0.332765835361449,  -0.298225513057705,  -0.241240252591135,    -0.2422954967662,
01800         -0.318285152564917,   0.443339154898195,  0.0596398081141739,  -0.659948317149671,  -0.326435253493529,   0.178830452220086,  -0.352868193530783,
01801         -0.412560890051571,   0.146384150301362,   0.297908475746163,   0.109867117049205,    0.34346695774658,   0.648160416413319,   0.411659413522294,
01802         -0.292710011070547,  0.0554502483926221,   0.149523329998174,  -0.365108802679842,   0.562068682918466,  -0.631639863837263,   0.201728365526942,
01803         -0.445415661076658,  -0.450830149565138,  -0.220576164554481,  -0.147429525356922,  -0.516611625256527, -0.0998306836562218,   0.501112780763699
01804   };
01805 
01806   Image<double> A(&Adata[0], 7, 9);
01807   Image<double> Ux(&Udata[0], 9, 9);
01808   Image<double> Sx(&Sdata[0], 7, 9);
01809   Image<double> Vx(&Vdata[0], 7, 7);
01810 
01811 #ifdef HAVE_LAPACK // SVD_FULL is only supported with LAPACK (and not with GSL)
01812   Image<double> Ulapack, Slapack, Vlapack;
01813   svd(A, Ulapack, Slapack, Vlapack, SVD_LAPACK, SVD_FULL);
01814 
01815   REQUIRE_EQFP(Ulapack, Ux, 1e-10);
01816   REQUIRE_EQFP(Slapack, Sx, 1e-10);
01817   REQUIRE_EQFP(Vlapack, Vx, 1e-10);
01818 #endif
01819 }
01820 
01821 //---------------------------------------------------------------------
01822 //
01823 // ShapeOps
01824 //
01825 //---------------------------------------------------------------------
01826 
01827 static void Image_xx_rescale_xx_1(TestSuite& suite)
01828 {
01829   float orig_data[] =
01830     {
01831       0.0, 0.5,
01832       0.5, 1.0
01833     };
01834 
01835   Image<float> orig(orig_data, 2, 2);
01836 
01837   Image<float> scaled = rescale(orig, 2, 2);
01838 
01839   REQUIRE_EQ(orig, scaled);
01840 }
01841 
01842 static void Image_xx_rescale_xx_2(TestSuite& suite)
01843 {
01844   // test rescaling with dest size > src size
01845 
01846   float orig_data[] =
01847     {
01848       0.0, 0.5,
01849       0.5, 1.0
01850     };
01851 
01852   float scaled_data[] =
01853     {
01854       0.000, 0.125, 0.375, 0.500,
01855       0.125, 0.250, 0.500, 0.625,
01856       0.375, 0.500, 0.750, 0.875,
01857       0.500, 0.625, 0.875, 1.000
01858     };
01859 
01860   Image<float> orig(orig_data, 2, 2);
01861   Image<float> expected(scaled_data, 4, 4);
01862 
01863   Image<float> actual = rescale(orig, 4, 4);
01864 
01865   REQUIRE_EQ(actual, expected);
01866 }
01867 
01868 static void Image_xx_rescale_xx_3(TestSuite& suite)
01869 {
01870   // test rescaling with dest size < src size
01871 
01872   float orig_data[] =
01873     {
01874       0.0, 0.25, 0.5, 0.75,
01875       0.25, 0.5, 0.75, 1.0,
01876       0.5, 0.75, 1.0, 1.25,
01877       0.75, 1.0, 1.25, 1.5
01878     };
01879 
01880   float scaled_data[] =
01881     {
01882       0.25, 0.75,
01883       0.75, 1.25
01884     };
01885 
01886   Image<float> orig(orig_data, 4, 4);
01887   Image<float> expected(scaled_data, 2, 2);
01888 
01889   Image<float> actual = rescale(orig, 2, 2);
01890 
01891   REQUIRE_EQ(actual, expected);
01892 }
01893 
01894 static void Image_xx_rescale_xx_4(TestSuite& suite)
01895 {
01896   // test rescaling rgb with dest size > src size
01897 
01898   typedef PixRGB<byte> PB;
01899 
01900   const PixRGB<byte> orig_data_rgb[] =
01901     {
01902       PB(0, 1, 2),    PB(33, 34, 35),
01903       PB(29, 30, 31), PB(64, 65, 66)
01904     };
01905 
01906   const PixRGB<byte> scaled_data_rgb[] =
01907     {
01908       PB(0, 1, 2),    PB(8, 9, 10),   PB(24, 25, 26), PB(33, 34, 35),
01909       PB(7, 8, 9),    PB(15, 16, 17), PB(32, 33, 34), PB(40, 41, 42),
01910       PB(21, 22, 23), PB(30, 31, 32), PB(47, 48, 49), PB(56, 57, 58),
01911       PB(29, 30, 31), PB(37, 38, 39), PB(55, 56, 57), PB(64, 65, 66)
01912     };
01913 
01914   Image<PixRGB<byte> > orig_rgb(orig_data_rgb, 2, 2);
01915   Image<PixRGB<byte> > expected_rgb(scaled_data_rgb, 4, 4);
01916 
01917   Image<PixRGB<byte> > actual_rgb = rescale(orig_rgb, 4, 4);
01918 
01919   REQUIRE_EQ(actual_rgb, expected_rgb);
01920 }
01921 
01922 static void Image_xx_rescale_xx_5(TestSuite& suite)
01923 {
01924   // test rescaling rgb with dest size < src size
01925 
01926   typedef PixRGB<byte> PB;
01927 
01928   const PixRGB<byte> orig_data_rgb[] =
01929     {
01930       PB(0, 1, 2),    PB(25, 26, 27),    PB(50, 51, 52),    PB(75, 76, 77),
01931       PB(25, 26, 27), PB(50, 51, 52),    PB(75, 76, 77),    PB(100, 101, 102),
01932       PB(50, 51, 52), PB(75, 76, 77),    PB(100, 101, 102), PB(125, 126, 127),
01933       PB(75, 76, 77), PB(100, 101, 102), PB(125, 126, 127), PB(150, 151, 152)
01934     };
01935 
01936   const PixRGB<byte> scaled_data_rgb[] =
01937     {
01938       PB(25, 26, 27), PB(75, 76, 77),
01939       PB(75, 76, 77), PB(125, 126, 127)
01940     };
01941 
01942   Image<PixRGB<byte> > orig_rgb(orig_data_rgb, 4, 4);
01943   Image<PixRGB<byte> > expected_rgb(scaled_data_rgb, 2, 2);
01944 
01945   Image<PixRGB<byte> > actual_rgb = rescale(orig_rgb, 2, 2);
01946 
01947   REQUIRE_EQ(actual_rgb, expected_rgb);
01948 }
01949 
01950 static void Image_xx_zoomXY_xx_1(TestSuite& suite)
01951 {
01952   byte orig_data[] =
01953     {
01954       1, 3, 5, 7, 9
01955     };
01956 
01957   byte zoomed_data[] =
01958     {
01959       1, 3, 5, 7, 9,
01960       1, 3, 5, 7, 9
01961     };
01962 
01963   Image<byte> orig(orig_data, 5, 1);
01964   Image<byte> expected(zoomed_data, 5, 2);
01965 
01966   Image<byte> actual = zoomXY(orig, 1, 2);
01967 
01968   REQUIRE_EQ(actual, expected);
01969 }
01970 
01971 static void Image_xx_zoomXY_xx_2(TestSuite& suite)
01972 {
01973   float orig_data[] =
01974     {
01975       0.2, 0.4, 0.6, 0.8
01976     };
01977 
01978   float zoomed_data[] =
01979     {
01980       0.2, 0.2, 0.4, 0.4, 0.6, 0.6, 0.8, 0.8
01981     };
01982 
01983   Image<float> orig(orig_data, 1, 4);
01984   Image<float> expected(zoomed_data, 2, 4);
01985 
01986   Image<float> actual = zoomXY(orig, 2, 1);
01987 
01988   REQUIRE_EQ(actual, expected);
01989 }
01990 
01991 static void Image_xx_zoomXY_xx_3(TestSuite& suite)
01992 {
01993   byte orig_data[] =
01994     {
01995       1, 2,
01996       3, 4
01997     };
01998 
01999   byte zoomed_data[] =
02000     {
02001       1,1,1, 2,2,2,
02002       1,1,1, 2,2,2,
02003       1,1,1, 2,2,2,
02004       1,1,1, 2,2,2,
02005       3,3,3, 4,4,4,
02006       3,3,3, 4,4,4,
02007       3,3,3, 4,4,4,
02008       3,3,3, 4,4,4
02009     };
02010 
02011   Image<byte> orig(orig_data, 2, 2);
02012   Image<byte> expected(zoomed_data, 6, 8);
02013 
02014   Image<byte> actual = zoomXY(orig, 3, 4);
02015 
02016   REQUIRE_EQ(actual, expected);
02017 }
02018 
02019 static void Image_xx_zoomXY_xx_4(TestSuite& suite)
02020 {
02021   Image<byte> orig(5,5, NO_INIT);
02022   Image<byte> zoomed00 = zoomXY(orig, 0, 0);
02023   Image<byte> zoomed01 = zoomXY(orig, 0, 1);
02024   Image<byte> zoomed10 = zoomXY(orig, 1, 0);
02025   Image<byte> zoomed11 = zoomXY(orig, 1, 1);
02026 
02027   REQUIRE_EQ(zoomed00.getWidth(), 0);
02028   REQUIRE_EQ(zoomed00.getHeight(), 0);
02029 
02030   REQUIRE_EQ(zoomed01.getWidth(), 0);
02031   REQUIRE_EQ(zoomed01.getHeight(), 0);
02032 
02033   REQUIRE_EQ(zoomed10.getWidth(), 0);
02034   REQUIRE_EQ(zoomed10.getHeight(), 0);
02035 
02036   REQUIRE_EQ(zoomed11, orig);
02037 }
02038 
02039 static void Image_xx_concatX_xx_1(TestSuite& suite)
02040 {
02041   const Image<byte> left = generateImage<byte>(6, 6, Counter(1));
02042   const Image<byte> right = generateImage<byte>(3, 6, Counter(100));
02043 
02044   const byte expected_data[] =
02045     {
02046       1,  2,  3,  4,  5,  6,  100, 101, 102,
02047       7,  8,  9,  10, 11, 12, 103, 104, 105,
02048       13, 14, 15, 16, 17, 18, 106, 107, 108,
02049       19, 20, 21, 22, 23, 24, 109, 110, 111,
02050       25, 26, 27, 28, 29, 30, 112, 113, 114,
02051       31, 32, 33, 34, 35, 36, 115, 116, 117
02052     };
02053 
02054   REQUIRE_EQ(concatX(left, right),
02055              Image<byte>(expected_data, 9, 6));
02056 
02057   const Image<byte> empty;
02058 
02059   REQUIRE_EQ(concatX(left, empty), left);
02060   REQUIRE_EQ(concatX(empty, right), right);
02061   REQUIRE_EQ(concatX(empty, empty), empty);
02062 }
02063 
02064 static void Image_xx_concatY_xx_1(TestSuite& suite)
02065 {
02066   const Image<byte> top = generateImage<byte>(4, 3, Counter(1));
02067   const Image<byte> bottom = generateImage<byte>(4, 4, Counter(100));
02068 
02069   const byte expected_data[] =
02070     {
02071       1,   2,   3,   4,
02072       5,   6,   7,   8,
02073       9,   10,  11,  12,
02074       100, 101, 102, 103,
02075       104, 105, 106, 107,
02076       108, 109, 110, 111,
02077       112, 113, 114, 115
02078     };
02079 
02080   REQUIRE_EQ(concatY(top, bottom),
02081              Image<byte>(expected_data, 4, 7));
02082 
02083   const Image<byte> empty;
02084 
02085   REQUIRE_EQ(concatY(top, empty), top);
02086   REQUIRE_EQ(concatY(empty, bottom), bottom);
02087   REQUIRE_EQ(concatY(empty, empty), empty);
02088 }
02089 
02090 static void Image_xx_concatLooseX_xx_1(TestSuite& suite)
02091 {
02092   const Image<byte> left = generateImage<byte>(4, 4, Counter(1));
02093   const Image<byte> right = generateImage<byte>(2, 2, Counter(100));
02094 
02095   const byte expected_data[] =
02096     {
02097       1,  2,  3,  4,  100, 101,
02098       5,  6,  7,  8,  102, 103,
02099       9,  10, 11, 12, 0,   0,
02100       13, 14, 15, 16, 0,   0
02101     };
02102 
02103   REQUIRE_EQ(concatLooseX(left, right),
02104              Image<byte>(expected_data, 6, 4));
02105 
02106   const Image<byte> empty;
02107 
02108   REQUIRE_EQ(concatLooseX(empty, empty), empty);
02109 }
02110 
02111 static void Image_xx_concatLooseY_xx_1(TestSuite& suite)
02112 {
02113   const Image<byte> top = generateImage<byte>(5, 5, Counter(1));
02114   const Image<byte> bottom = generateImage<byte>(3, 3, Counter(100));
02115 
02116   const byte expected_data[] =
02117     {
02118       1,   2,   3,   4,  5,
02119       6,   7,   8,   9,  10,
02120       11,  12,  13,  14, 15,
02121       16,  17,  18,  19, 20,
02122       21,  22,  23,  24, 25,
02123       100, 101, 102, 0,  0,
02124       103, 104, 105, 0,  0,
02125       106, 107, 108, 0,  0
02126     };
02127 
02128   REQUIRE_EQ(concatLooseY(top, bottom),
02129              Image<byte>(expected_data, 5, 8));
02130 
02131   const Image<byte> empty;
02132 
02133   REQUIRE_EQ(concatLooseY(empty, empty), empty);
02134 }
02135 
02136 static void Image_xx_crop_xx_1(TestSuite& suite)
02137 {
02138   /*
02139   byte orig_data[] =
02140     {
02141        1,  2,  3,  4,  5,  6,  7,
02142        8,  9, 10, 11, 12, 13, 14,
02143       15, 16, 17, 18, 19, 20, 21,
02144       22, 23, 24, 25, 26, 27, 28,
02145       29, 30, 31, 32, 33, 34, 35,
02146       36, 37, 38, 39, 40, 41, 42,
02147       43, 44, 45, 46, 47, 48, 49
02148     };
02149   */
02150 
02151   const Image<byte> orig = generateImage<byte>(7, 7, Counter(1));
02152 
02153   // Sub-image == full image
02154   REQUIRE_EQ(orig, crop(orig, Point2D<int>(0,0), Dims(7, 7)));
02155   REQUIRE_EQ(orig, crop(orig, Rectangle::tlbrI(0, 0, 6, 6)));
02156 
02157   // Sub-image == empty image
02158   Image<byte> empty;
02159   REQUIRE_EQ(empty, crop(orig, Point2D<int>(3,3), Dims(0, 0)));
02160 
02161   // Sub-image == upper all
02162   byte upper_rows[] =
02163     {
02164       1, 2, 3, 4, 5, 6, 7,
02165       8, 9, 10, 11, 12, 13, 14
02166     };
02167 
02168   REQUIRE_EQ(crop(orig, Point2D<int>(0,0), Dims(7, 2)),
02169              Image<byte>(upper_rows, 7, 2));
02170   REQUIRE_EQ(crop(orig, Rectangle::tlbrI(0, 0, 1, 6)),
02171              Image<byte>(upper_rows, 7, 2));
02172 
02173   // Sub-image == upper left
02174   byte upper_left[] =
02175     {
02176       1, 2, 3, 4,
02177       8, 9, 10, 11,
02178       15, 16, 17, 18
02179     };
02180 
02181   REQUIRE_EQ(crop(orig, Point2D<int>(0,0), Dims(4, 3)),
02182              Image<byte>(upper_left, 4, 3));
02183   REQUIRE_EQ(crop(orig, Rectangle::tlbrI(0, 0, 2, 3)),
02184              Image<byte>(upper_left, 4, 3));
02185 
02186   // Sub-image == upper center
02187   byte upper_center[] =
02188     {
02189       2, 3, 4, 5, 6,
02190       9, 10, 11, 12, 13,
02191       16, 17, 18, 19, 20,
02192     };
02193 
02194   REQUIRE_EQ(crop(orig, Point2D<int>(1,0), Dims(5, 3)),
02195              Image<byte>(upper_center, 5, 3));
02196   REQUIRE_EQ(crop(orig, Rectangle::tlbrI(0, 1, 2, 5)),
02197              Image<byte>(upper_center, 5, 3));
02198 
02199   // Sub-image == upper right
02200   byte upper_right[] =
02201     {
02202       4, 5, 6, 7,
02203       11, 12, 13, 14,
02204       18, 19, 20, 21
02205     };
02206 
02207   REQUIRE_EQ(crop(orig, Point2D<int>(3,0), Dims(4, 3)),
02208              Image<byte>(upper_right, 4, 3));
02209   REQUIRE_EQ(crop(orig, Rectangle::tlbrI(0, 3, 2, 6)),
02210              Image<byte>(upper_right, 4, 3));
02211 
02212   // Sub-image == middle all
02213   byte middle_all[] =
02214     {
02215       22, 23, 24, 25, 26, 27, 28,
02216       29, 30, 31, 32, 33, 34, 35,
02217     };
02218 
02219   REQUIRE_EQ(crop(orig, Point2D<int>(0,3), Dims(7, 2)),
02220              Image<byte>(middle_all, 7, 2));
02221   REQUIRE_EQ(crop(orig, Rectangle::tlbrI(3, 0, 4, 6)),
02222              Image<byte>(middle_all, 7, 2));
02223 
02224   // Sub-image == middle left
02225   byte middle_left[] =
02226     {
02227       15, 16, 17,
02228       22, 23, 24,
02229       29, 30, 31,
02230     };
02231 
02232   REQUIRE_EQ(crop(orig, Point2D<int>(0,2), Dims(3, 3)),
02233              Image<byte>(middle_left, 3, 3));
02234   REQUIRE_EQ(crop(orig, Rectangle::tlbrI(2, 0, 4, 2)),
02235              Image<byte>(middle_left, 3, 3));
02236 
02237   // Sub-image == middle center
02238   byte middle_center[] =
02239     {
02240       25
02241     };
02242 
02243   REQUIRE_EQ(crop(orig, Point2D<int>(3,3), Dims(1, 1)),
02244              Image<byte>(middle_center, 1, 1));
02245   REQUIRE_EQ(crop(orig, Rectangle::tlbrI(3, 3, 3, 3)),
02246              Image<byte>(middle_center, 1, 1));
02247 
02248   // Sub-image == middle right
02249   byte middle_right[] =
02250     {
02251       13, 14,
02252       20, 21,
02253       27, 28,
02254       34, 35,
02255       41, 42,
02256     };
02257 
02258   REQUIRE_EQ(crop(orig, Point2D<int>(5,1), Dims(2, 5)),
02259              Image<byte>(middle_right, 2, 5));
02260   REQUIRE_EQ(crop(orig, Rectangle::tlbrI(1, 5, 5, 6)),
02261              Image<byte>(middle_right, 2, 5));
02262 
02263   // Sub-image == lower all
02264   byte lower_all[] =
02265     {
02266       43, 44, 45, 46, 47, 48, 49
02267     };
02268 
02269   REQUIRE_EQ(crop(orig, Point2D<int>(0,6), Dims(7, 1)),
02270              Image<byte>(lower_all, 7, 1));
02271   REQUIRE_EQ(crop(orig, Rectangle::tlbrI(6, 0, 6, 6)),
02272              Image<byte>(lower_all, 7, 1));
02273 
02274   // Sub-image == lower left
02275   byte lower_left[] =
02276     {
02277       22, 23, 24,
02278       29, 30, 31,
02279       36, 37, 38,
02280       43, 44, 45,
02281     };
02282 
02283   REQUIRE_EQ(crop(orig, Point2D<int>(0,3), Dims(3, 4)),
02284              Image<byte>(lower_left, 3, 4));
02285   REQUIRE_EQ(crop(orig, Rectangle::tlbrI(3, 0, 6, 2)),
02286              Image<byte>(lower_left, 3, 4));
02287 
02288   // Sub-image == lower center
02289   byte lower_center[] =
02290     {
02291       38, 39, 40,
02292       45, 46, 47,
02293     };
02294 
02295   REQUIRE_EQ(crop(orig, Point2D<int>(2,5), Dims(3, 2)),
02296              Image<byte>(lower_center, 3, 2));
02297   REQUIRE_EQ(crop(orig, Rectangle::tlbrI(5, 2, 6, 4)),
02298              Image<byte>(lower_center, 3, 2));
02299 
02300   // Sub-image == lower right
02301   byte lower_right[] =
02302     {
02303       19, 20, 21,
02304       26, 27, 28,
02305       33, 34, 35,
02306       40, 41, 42,
02307       47, 48, 49
02308     };
02309 
02310   REQUIRE_EQ(crop(orig, Point2D<int>(4,2), Dims(3, 5)),
02311              Image<byte>(lower_right, 3, 5));
02312   REQUIRE_EQ(crop(orig, Rectangle::tlbrI(2, 4, 6, 6)),
02313              Image<byte>(lower_right, 3, 5));
02314 
02315   // Sub-image == all left
02316   byte all_left[] =
02317     {
02318       1, 2, 3, 4,
02319       8, 9, 10, 11,
02320       15, 16, 17, 18,
02321       22, 23, 24, 25,
02322       29, 30, 31, 32,
02323       36, 37, 38, 39,
02324       43, 44, 45, 46,
02325     };
02326 
02327   REQUIRE_EQ(crop(orig, Point2D<int>(0, 0), Dims(4, 7)),
02328              Image<byte>(all_left, 4, 7));
02329   REQUIRE_EQ(crop(orig, Rectangle::tlbrI(0, 0, 6, 3)),
02330              Image<byte>(all_left, 4, 7));
02331 
02332   // Sub-image == all center
02333   byte all_center[] =
02334     {
02335       5, 6,
02336       12, 13,
02337       19, 20,
02338       26, 27,
02339       33, 34,
02340       40, 41,
02341       47, 48,
02342     };
02343 
02344   REQUIRE_EQ(crop(orig, Point2D<int>(4, 0), Dims(2, 7)),
02345              Image<byte>(all_center, 2, 7));
02346   REQUIRE_EQ(crop(orig, Rectangle::tlbrI(0, 4, 6, 5)),
02347              Image<byte>(all_center, 2, 7));
02348 
02349   // Sub-image == all right
02350   byte all_right[] =
02351     {
02352       3, 4, 5, 6, 7,
02353       10, 11, 12, 13, 14,
02354       17, 18, 19, 20, 21,
02355       24, 25, 26, 27, 28,
02356       31, 32, 33, 34, 35,
02357       38, 39, 40, 41, 42,
02358       45, 46, 47, 48, 49
02359     };
02360 
02361   REQUIRE_EQ(crop(orig, Point2D<int>(2, 0), Dims(5, 7)),
02362              Image<byte>(all_right, 5, 7));
02363   REQUIRE_EQ(crop(orig, Rectangle::tlbrI(0, 2, 6, 6)),
02364              Image<byte>(all_right, 5, 7));
02365 
02366   // Sub-image == interior chunk 1
02367   byte interior_chunk_1[] =
02368     {
02369        9, 10, 11, 12,
02370       16, 17, 18, 19,
02371       23, 24, 25, 26,
02372     };
02373 
02374   REQUIRE_EQ(crop(orig, Point2D<int>(1, 1), Dims(4, 3)),
02375              Image<byte>(interior_chunk_1, 4, 3));
02376   REQUIRE_EQ(crop(orig, Rectangle::tlbrI(1, 1, 3, 4)),
02377              Image<byte>(interior_chunk_1, 4, 3));
02378 
02379   // Sub-image == interior chunk 1
02380   byte interior_chunk_2[] =
02381     {
02382       33, 34,
02383       40, 41,
02384     };
02385 
02386   REQUIRE_EQ(crop(orig, Point2D<int>(4, 4), Dims(2, 2)),
02387              Image<byte>(interior_chunk_2, 2, 2));
02388   REQUIRE_EQ(crop(orig, Rectangle::tlbrI(4, 4, 5, 5)),
02389              Image<byte>(interior_chunk_2, 2, 2));
02390 }
02391 
02392 static void Image_xx_interpolate_xx_1(TestSuite& suite)
02393 {
02394   // To avoid bugs in involving transposing width/height values, the test
02395   // arrays here should be non-square.
02396   const float orig_data[] =
02397     {
02398       1.0, 1.0, 3.0, 3.0, 1.0, 1.0,
02399       1.0, 1.0, 3.0, 3.0, 1.0, 1.0,
02400       3.0, 3.0, 3.0, 3.0, 3.0, 3.0,
02401       1.0, 1.0, 3.0, 3.0, 1.0, 1.0,
02402       1.0, 1.0, 3.0, 3.0, 1.0, 1.0
02403     };
02404 
02405   const Image<float> orig(orig_data, 6, 5);
02406 
02407   const float expected_data[] =
02408     {
02409       1.00, 1.00, 1.00, 2.00, 3.00, 3.00, 3.00, 2.00, 1.00, 1.00, 1.00, 0.75,
02410       1.00, 1.00, 1.00, 2.00, 3.00, 3.00, 3.00, 2.00, 1.00, 1.00, 1.00, 0.75,
02411       1.00, 1.00, 1.00, 2.00, 3.00, 3.00, 3.00, 2.00, 1.00, 1.00, 1.00, 0.75,
02412       2.00, 2.00, 2.00, 2.50, 3.00, 3.00, 3.00, 2.50, 2.00, 2.00, 2.00, 1.50,
02413       3.00, 3.00, 3.00, 3.00, 3.00, 3.00, 3.00, 3.00, 3.00, 3.00, 3.00, 2.25,
02414       2.00, 2.00, 2.00, 2.50, 3.00, 3.00, 3.00, 2.50, 2.00, 2.00, 2.00, 1.50,
02415       1.00, 1.00, 1.00, 2.00, 3.00, 3.00, 3.00, 2.00, 1.00, 1.00, 1.00, 0.75,
02416       1.00, 1.00, 1.00, 2.00, 3.00, 3.00, 3.00, 2.00, 1.00, 1.00, 1.00, 0.75,
02417       1.00, 1.00, 1.00, 2.00, 3.00, 3.00, 3.00, 2.00, 1.00, 1.00, 1.00, 0.75,
02418       0.75, 0.75, 0.75, 1.50, 2.25, 2.25, 2.25, 1.50, 0.75, 0.75, 0.75, 0.50
02419     };
02420 
02421   const Image<float> expected(expected_data, 12, 10);
02422 
02423   const Image<float> result = interpolate(orig);
02424 
02425   REQUIRE_EQ(result, expected);
02426 }
02427 
02428 static void Image_xx_decY_xx_1(TestSuite& suite)
02429 {
02430   const Image<byte> src = generateImage<byte>(5, 50, Counter(0));
02431 
02432   const byte expected_data[] =
02433     {
02434       0, 1, 2, 3, 4,
02435       65, 66, 67, 68, 69,
02436       130, 131, 132, 133, 134
02437     };
02438 
02439   const Image<byte> expected(expected_data, 5, 3);
02440 
02441   REQUIRE_EQ(decY(src, 13), expected);
02442   REQUIRE_EQ(decXY(src, 1, 13), expected);
02443 }
02444 
02445 static void Image_xx_blurAndDecY_xx_1(TestSuite& suite)
02446 {
02447   rutz::urand_frange gen(0.0, 256.0, time((time_t*)0) + getpid());
02448 
02449   Image<float> src(400, 7500, NO_INIT);
02450 
02451   {
02452     gen = fill(src, gen);
02453 
02454     const int reduction_factor = 13;
02455 
02456     Image<float> yFilter(1, reduction_factor, NO_INIT);
02457     yFilter.clear(1.0f/reduction_factor);
02458 
02459     const Image<float> ff1 =
02460       decY(sepFilter(src, Image<float>(), yFilter,
02461                      CONV_BOUNDARY_CLEAN),
02462            reduction_factor);
02463 
02464     const Image<float> ff2 = blurAndDecY(src, reduction_factor);
02465 
02466     REQUIRE_LTE(RMSerr(ff1, ff2), 0.0001);
02467     REQUIRE_GTE(corrcoef(ff1, ff2), 0.9999);
02468   }
02469 
02470   {
02471     gen = fill(src, gen);
02472 
02473     const int reduction_factor = 19;
02474 
02475     Image<float> yFilter(1, reduction_factor, NO_INIT);
02476     yFilter.clear(1.0f/reduction_factor);
02477 
02478     const Image<float> ff1 =
02479       decY(sepFilter(src, Image<float>(), yFilter,
02480                      CONV_BOUNDARY_CLEAN),
02481            reduction_factor);
02482 
02483     const Image<float> ff2 = blurAndDecY(src, reduction_factor);
02484 
02485     REQUIRE_LTE(RMSerr(ff1, ff2), 0.0001);
02486     REQUIRE_GTE(corrcoef(ff1, ff2), 0.9999);
02487   }
02488 
02489   {
02490     gen = fill(src, gen);
02491 
02492     const int reduction_factor = 25;
02493 
02494     Image<float> yFilter(1, reduction_factor, NO_INIT);
02495     yFilter.clear(1.0f/reduction_factor);
02496 
02497     const Image<float> ff1 =
02498       decY(sepFilter(src, Image<float>(), yFilter,
02499                      CONV_BOUNDARY_CLEAN),
02500            reduction_factor);
02501 
02502     const Image<float> ff2 = blurAndDecY(src, reduction_factor);
02503 
02504     REQUIRE_LTE(RMSerr(ff1, ff2), 0.0001);
02505     REQUIRE_GTE(corrcoef(ff1, ff2), 0.9999);
02506   }
02507 
02508 }
02509 
02510 //---------------------------------------------------------------------
02511 //
02512 // FilterOps
02513 //
02514 //---------------------------------------------------------------------
02515 
02516 static void Image_xx_lowPass3x_xx_1(TestSuite& suite)
02517 {
02518   // To avoid bugs in involving transposing width/height values, the test
02519   // arrays here should be non-square.
02520   const float orig_data[] =
02521     {
02522       1.0, 1.0, 3.0, 3.0, 1.0, 1.0,
02523       1.0, 1.0, 3.0, 3.0, 1.0, 1.0,
02524       3.0, 3.0, 3.0, 3.0, 3.0, 3.0,
02525       1.0, 1.0, 3.0, 3.0, 1.0, 1.0,
02526       1.0, 1.0, 3.0, 3.0, 1.0, 1.0
02527     };
02528 
02529   const Image<float> orig(orig_data, 6, 5);
02530 
02531   const float expected_data[] =
02532     {
02533       1.0, 1.5, 2.5, 2.5, 1.5, 1.0,
02534       1.0, 1.5, 2.5, 2.5, 1.5, 1.0,
02535       3.0, 3.0, 3.0, 3.0, 3.0, 3.0,
02536       1.0, 1.5, 2.5, 2.5, 1.5, 1.0,
02537       1.0, 1.5, 2.5, 2.5, 1.5, 1.0
02538     };
02539 
02540   const Image<float> expected(expected_data, 6, 5);
02541 
02542   const Image<float> result = lowPass3x(orig);
02543 
02544   REQUIRE_EQ(result, expected);
02545 }
02546 
02547 static void Image_xx_lowPass3y_xx_1(TestSuite& suite)
02548 {
02549   // To avoid bugs in involving transposing width/height values, the test
02550   // arrays here should be non-square.
02551   const float orig_data[] =
02552     {
02553       1.0, 1.0, 3.0, 1.0, 1.0,
02554       1.0, 1.0, 3.0, 1.0, 1.0,
02555       3.0, 3.0, 3.0, 3.0, 3.0,
02556       3.0, 3.0, 3.0, 3.0, 3.0,
02557       1.0, 1.0, 3.0, 1.0, 1.0,
02558       1.0, 1.0, 3.0, 1.0, 1.0
02559     };
02560 
02561   const Image<float> orig(orig_data, 5, 6);
02562 
02563   const float expected_data[] =
02564     {
02565       1.0, 1.0, 3.0, 1.0, 1.0,
02566       1.5, 1.5, 3.0, 1.5, 1.5,
02567       2.5, 2.5, 3.0, 2.5, 2.5,
02568       2.5, 2.5, 3.0, 2.5, 2.5,
02569       1.5, 1.5, 3.0, 1.5, 1.5,
02570       1.0, 1.0, 3.0, 1.0, 1.0
02571     };
02572 
02573   const Image<float> expected(expected_data, 5, 6);
02574 
02575   const Image<float> result = lowPass3y(orig);
02576 
02577   REQUIRE_EQ(result, expected);
02578 }
02579 
02580 static void Image_xx_lowPass3_xx_1(TestSuite& suite)
02581 {
02582   const float orig_data[] =
02583     {
02584        6.0, 18.0,  6.0, 18.0,  6.0,
02585        6.0, 18.0,  6.0, 18.0,  6.0,
02586       18.0,  6.0, 18.0,  6.0, 18.0,
02587       18.0,  6.0, 18.0,  6.0, 18.0,
02588        6.0, 18.0,  6.0, 18.0,  6.0,
02589        6.0, 18.0,  6.0, 18.0,  6.0
02590     };
02591 
02592   const Image<float> orig(orig_data, 5, 6);
02593 
02594   const float expected_data[] =
02595     {
02596       10.0, 12.0, 12.0, 12.0, 10.0,
02597       11.0, 12.0, 12.0, 12.0, 11.0,
02598       13.0, 12.0, 12.0, 12.0, 13.0,
02599       13.0, 12.0, 12.0, 12.0, 13.0,
02600       11.0, 12.0, 12.0, 12.0, 11.0,
02601       10.0, 12.0, 12.0, 12.0, 10.0
02602     };
02603 
02604   const Image<float> expected(expected_data, 5, 6);
02605 
02606   REQUIRE_EQ(lowPass3(orig), expected);
02607   REQUIRE_EQ(lowPass3x(lowPass3y(orig)), expected);
02608   REQUIRE_EQ(lowPass3y(lowPass3x(orig)), expected);
02609 }
02610 
02611 static void Image_xx_lowPass5x_xx_1(TestSuite& suite)
02612 {
02613   const float orig_data[] =
02614     {
02615       10, 20, 30, 20, 10, 50, 50, 50, 10, 20, 30, 20, 10,
02616       20, 30, 40, 30, 20, 50, 50, 50, 20, 30, 40, 30, 20,
02617       30, 40, 50, 40, 30, 50, 50, 50, 30, 40, 50, 40, 30,
02618       20, 30, 40, 30, 20, 50, 50, 50, 20, 30, 40, 30, 20,
02619       10, 20, 30, 20, 10, 50, 50, 50, 10, 20, 30, 20, 10,
02620       50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
02621       10, 20, 30, 20, 10, 50, 50, 50, 10, 20, 30, 20, 10,
02622       20, 30, 40, 30, 20, 50, 50, 50, 20, 30, 40, 30, 20,
02623       30, 40, 50, 40, 30, 50, 50, 50, 30, 40, 50, 40, 30,
02624       20, 30, 40, 30, 20, 50, 50, 50, 20, 30, 40, 30, 20,
02625       10, 20, 30, 20, 10, 50, 50, 50, 10, 20, 30, 20, 10,
02626     };
02627 
02628   const Image<float> orig(orig_data, 13, 11);
02629 
02630   // Just work with the integer portions of the results
02631   const byte expected_data[] =
02632     {
02633       15, 20, 22, 21, 26, 38, 45, 38, 26, 21, 22, 20, 15,
02634       25, 30, 32, 31, 33, 41, 46, 41, 33, 31, 32, 30, 25,
02635       35, 40, 42, 40, 40, 44, 47, 44, 40, 40, 42, 40, 35,
02636       25, 30, 32, 31, 33, 41, 46, 41, 33, 31, 32, 30, 25,
02637       15, 20, 22, 21, 26, 38, 45, 38, 26, 21, 22, 20, 15,
02638       50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
02639       15, 20, 22, 21, 26, 38, 45, 38, 26, 21, 22, 20, 15,
02640       25, 30, 32, 31, 33, 41, 46, 41, 33, 31, 32, 30, 25,
02641       35, 40, 42, 40, 40, 44, 47, 44, 40, 40, 42, 40, 35,
02642       25, 30, 32, 31, 33, 41, 46, 41, 33, 31, 32, 30, 25,
02643       15, 20, 22, 21, 26, 38, 45, 38, 26, 21, 22, 20, 15,
02644     };
02645 
02646   const Image<byte> expected(expected_data, 13, 11);
02647 
02648   REQUIRE_EQ(Image<byte>(lowPass5x(orig)), expected);
02649 }
02650 
02651 static void Image_xx_lowPass5y_xx_1(TestSuite& suite)
02652 {
02653   const float orig_data[] =
02654     {
02655       10, 20, 30, 20, 10, 50, 10, 20, 30, 20, 10,
02656       20, 30, 40, 30, 20, 50, 20, 30, 40, 30, 20,
02657       30, 40, 50, 40, 30, 50, 30, 40, 50, 40, 30,
02658       20, 30, 40, 30, 20, 50, 20, 30, 40, 30, 20,
02659       10, 20, 30, 20, 10, 50, 10, 20, 30, 20, 10,
02660       50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
02661       50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
02662       50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
02663       10, 20, 30, 20, 10, 50, 10, 20, 30, 20, 10,
02664       20, 30, 40, 30, 20, 50, 20, 30, 40, 30, 20,
02665       30, 40, 50, 40, 30, 50, 30, 40, 50, 40, 30,
02666       20, 30, 40, 30, 20, 50, 20, 30, 40, 30, 20,
02667       10, 20, 30, 20, 10, 50, 10, 20, 30, 20, 10,
02668     };
02669 
02670   const Image<float> orig(orig_data, 11, 13);
02671 
02672   // Just work with the integer portions of the results
02673   const byte expected_data[] =
02674     {
02675       15, 25, 35, 25, 15, 50, 15, 25, 35, 25, 15,
02676       20, 30, 40, 30, 20, 50, 20, 30, 40, 30, 20,
02677       22, 32, 42, 32, 22, 50, 22, 32, 42, 32, 22,
02678       21, 31, 40, 31, 21, 50, 21, 31, 40, 31, 21,
02679       26, 33, 40, 33, 26, 50, 26, 33, 40, 33, 26,
02680       38, 41, 44, 41, 38, 50, 38, 41, 44, 41, 38,
02681       45, 46, 47, 46, 45, 50, 45, 46, 47, 46, 45,
02682       38, 41, 44, 41, 38, 50, 38, 41, 44, 41, 38,
02683       26, 33, 40, 33, 26, 50, 26, 33, 40, 33, 26,
02684       21, 31, 40, 31, 21, 50, 21, 31, 40, 31, 21,
02685       22, 32, 42, 32, 22, 50, 22, 32, 42, 32, 22,
02686       20, 30, 40, 30, 20, 50, 20, 30, 40, 30, 20,
02687       15, 25, 35, 25, 15, 50, 15, 25, 35, 25, 15,
02688     };
02689 
02690   const Image<byte> expected(expected_data, 11, 13);
02691 
02692   REQUIRE_EQ(Image<byte>(lowPass5y(orig)), expected);
02693 }
02694 
02695 static void Image_xx_lowPass5_xx_1(TestSuite& suite)
02696 {
02697   const float orig_data[] =
02698     {
02699       10, 20, 30, 20, 10, 50, 10, 20, 30, 20, 10,
02700       20, 30, 40, 30, 20, 50, 20, 30, 40, 30, 20,
02701       30, 40, 50, 40, 30, 50, 30, 40, 50, 40, 30,
02702       20, 30, 40, 30, 20, 50, 20, 30, 40, 30, 20,
02703       10, 20, 30, 20, 10, 50, 10, 20, 30, 20, 10,
02704       50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
02705       50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
02706       50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
02707       10, 20, 30, 20, 10, 50, 10, 20, 30, 20, 10,
02708       20, 30, 40, 30, 20, 50, 20, 30, 40, 30, 20,
02709       30, 40, 50, 40, 30, 50, 30, 40, 50, 40, 30,
02710       20, 30, 40, 30, 20, 50, 20, 30, 40, 30, 20,
02711       10, 20, 30, 20, 10, 50, 10, 20, 30, 20, 10,
02712     };
02713 
02714   const Image<float> orig(orig_data, 11, 13);
02715 
02716   // Just work with the integer portions of the results
02717   const byte expected_data[] =
02718     {
02719       20, 25, 27, 26, 27, 29, 27, 26, 27, 25, 20,
02720       25, 30, 32, 31, 31, 32, 31, 31, 32, 30, 25,
02721       27, 32, 35, 33, 33, 34, 33, 33, 35, 32, 27,
02722       26, 31, 33, 32, 32, 33, 32, 32, 33, 31, 26,
02723       30, 33, 34, 34, 34, 36, 34, 34, 34, 33, 30,
02724       39, 41, 42, 41, 42, 42, 42, 41, 42, 41, 39,
02725       45, 46, 46, 46, 46, 47, 46, 46, 46, 46, 45,
02726       39, 41, 42, 41, 42, 42, 42, 41, 42, 41, 39,
02727       30, 33, 34, 34, 34, 36, 34, 34, 34, 33, 30,
02728       26, 31, 33, 32, 32, 33, 32, 32, 33, 31, 26,
02729       27, 32, 35, 33, 33, 34, 33, 33, 35, 32, 27,
02730       25, 30, 32, 31, 31, 32, 31, 31, 32, 30, 25,
02731       20, 25, 27, 26, 27, 29, 27, 26, 27, 25, 20,
02732     };
02733 
02734   const Image<byte> expected(expected_data, 11, 13);
02735 
02736   REQUIRE_EQ(Image<byte>(lowPass5(orig)), expected);
02737   REQUIRE_EQ(Image<byte>(lowPass5x(lowPass5y(orig))), expected);
02738   REQUIRE_EQ(Image<byte>(lowPass5y(lowPass5x(orig))), expected);
02739 }
02740 
02741 static void Image_xx_binomialKernel_xx_1(TestSuite& suite)
02742 {
02743   float b0[] = { 1 };
02744   float b1[] = { 1,  1 };
02745   float b2[] = { 1,  2,  1 };
02746   float b3[] = { 1,  3,  3,  1 };
02747   float b4[] = { 1,  4,  6,  4,  1 };
02748   float b5[] = { 1,  5, 10, 10,  5,  1 };
02749   float b6[] = { 1,  6, 15, 20, 15,  6,  1 };
02750   float b7[] = { 1,  7, 21, 35, 35, 21,  7,  1 };
02751   float b8[] = { 1,  8, 28, 56, 70, 56, 28,  8,  1 };
02752 
02753   REQUIRE_EQ(Image<float>(b0, 1, 1), binomialKernel(1)*1.0f);
02754   REQUIRE_EQ(Image<float>(b1, 2, 1), binomialKernel(2)*2.0f);
02755   REQUIRE_EQ(Image<float>(b2, 3, 1), binomialKernel(3)*4.0f);
02756   REQUIRE_EQ(Image<float>(b3, 4, 1), binomialKernel(4)*8.0f);
02757   REQUIRE_EQ(Image<float>(b4, 5, 1), binomialKernel(5)*16.0f);
02758   REQUIRE_EQ(Image<float>(b5, 6, 1), binomialKernel(6)*32.0f);
02759   REQUIRE_EQ(Image<float>(b6, 7, 1), binomialKernel(7)*64.0f);
02760   REQUIRE_EQ(Image<float>(b7, 8, 1), binomialKernel(8)*128.0f);
02761   REQUIRE_EQ(Image<float>(b8, 9, 1), binomialKernel(9)*256.0f);
02762 }
02763 
02764 static void Image_xx_sepFilter_xx_1(TestSuite& suite)
02765 {
02766   // check that an even-sized filter is equivalent to a one-larger
02767   // odd-sized filter with an extra 0 at the end, when applied to an
02768   // image that is larger than the filter size
02769 
02770   const Image<float> src = generateImage<float>(12, 12, Counter(0));
02771 
02772   const Image<float> kern8 = binomialKernel(8);
02773   const Image<float> kern9 = hcat(kern8, Image<float>(1,1,ZEROS)).render();
02774 
02775   const Image<float> f8x = sepFilter(src, kern8, Image<float>(), CONV_BOUNDARY_ZERO);
02776   const Image<float> f9x = sepFilter(src, kern9, Image<float>(), CONV_BOUNDARY_ZERO);
02777 
02778   const Image<float> f8y = sepFilter(src, Image<float>(), kern8, CONV_BOUNDARY_ZERO);
02779   const Image<float> f9y = sepFilter(src, Image<float>(), kern9, CONV_BOUNDARY_ZERO);
02780 
02781   REQUIRE_LT(rangeOf(abs(f8x-f9x)).max(), 0.5f);
02782   REQUIRE_LT(fabs(mean(f8x-f9x)), 0.005f);
02783   REQUIRE_EQFP(f8x, f9x, 0.005f);
02784 
02785   REQUIRE_LT(rangeOf(abs(f8y-f9y)).max(), 0.5f);
02786   REQUIRE_LT(fabs(mean(f8y-f9y)), 0.005f);
02787   REQUIRE_EQFP(f8y, f9y, 0.005f);
02788 }
02789 
02790 static void Image_xx_sepFilter_xx_2(TestSuite& suite)
02791 {
02792   // check that CONV_BOUNDARY_ZERO and CONV_BOUNDARY_CLEAN give
02793   // identical results away from the boundaries
02794 
02795   const Image<float> src = generateImage<float>(15, 15, Counter(0));
02796 
02797   const Image<float> kern9 = binomialKernel(9);
02798 
02799   const Image<float> f9x0 = sepFilter(src, kern9, Image<float>(),
02800                                       CONV_BOUNDARY_ZERO);
02801   const Image<float> f9y0 = sepFilter(src, Image<float>(), kern9,
02802                                       CONV_BOUNDARY_ZERO);
02803 
02804   const Image<float> f9xc = sepFilter(src, kern9, Image<float>(),
02805                                       CONV_BOUNDARY_CLEAN);
02806   const Image<float> f9yc = sepFilter(src, Image<float>(), kern9,
02807                                       CONV_BOUNDARY_CLEAN);
02808 
02809   const Image<float> cutf9x0 = crop(f9x0, Point2D<int>(4,0), Dims(7,15));
02810   const Image<float> cutf9y0 = crop(f9y0, Point2D<int>(0,4), Dims(15,7));
02811   const Image<float> cutf9xc = crop(f9xc, Point2D<int>(4,0), Dims(7,15));
02812   const Image<float> cutf9yc = crop(f9yc, Point2D<int>(0,4), Dims(15,7));
02813 
02814   REQUIRE_EQFP(cutf9x0, cutf9xc, 0.0001f);
02815   REQUIRE_EQFP(cutf9y0, cutf9yc, 0.0001f);
02816 }
02817 
02818 static void Image_xx_sepFilter_xx_3(TestSuite& suite)
02819 {
02820   const Image<float> src = generateImage<float>(50, 50, Counter(0));
02821 
02822   const Image<float> kern = binomialKernel(9);
02823 
02824   const Image<float> f1 = sepFilter(src, kern, kern,
02825                                     CONV_BOUNDARY_CLEAN);
02826 
02827   const Image<float> f2 = lowPass9(src);
02828 
02829   REQUIRE_LT(rangeOf(abs(f2-f1)).max(), 0.5f);
02830   REQUIRE_LT(fabs(mean(f2-f1)), 0.005f);
02831 }
02832 
02833 static void Image_xx_sepFilter_xx_4(TestSuite& suite)
02834 {
02835   // check that an even-sized filter is equivalent to a one-larger
02836   // odd-sized filter with an extra 0 at the end, when applied to an
02837   // image that is larger than the filter size
02838 
02839   const Image<float> src = generateImage<float>(12, 12, Counter(0));
02840 
02841   const Image<float> kern8 = binomialKernel(8);
02842   const Image<float> kern9 = hcat(kern8, Image<float>(1,1,ZEROS)).render();
02843 
02844   const Image<float> f8x = sepFilter(src, kern8, Image<float>(), CONV_BOUNDARY_CLEAN);
02845   const Image<float> f9x = sepFilter(src, kern9, Image<float>(), CONV_BOUNDARY_CLEAN);
02846 
02847   const Image<float> f8y = sepFilter(src, Image<float>(), kern8, CONV_BOUNDARY_CLEAN);
02848   const Image<float> f9y = sepFilter(src, Image<float>(), kern9, CONV_BOUNDARY_CLEAN);
02849 
02850   REQUIRE_LT(rangeOf(abs(f8x-f9x)).max(), 0.5f);
02851   REQUIRE_LT(fabs(mean(f8x-f9x)), 0.005f);
02852   REQUIRE_EQFP(f8x, f9x, 0.005f);
02853 
02854   REQUIRE_LT(rangeOf(abs(f8y-f9y)).max(), 0.5f);
02855   REQUIRE_LT(fabs(mean(f8y-f9y)), 0.005f);
02856   REQUIRE_EQFP(f8y, f9y, 0.005f);
02857 }
02858 
02859 static void Image_xx_sepFilter_xx_5(TestSuite& suite)
02860 {
02861   // check that an even-sized filter is equivalent to a one-larger
02862   // odd-sized filter with an extra 0 at the end, when applied to an
02863   // image that is smaller than the filter size
02864 
02865   const Image<float> src = generateImage<float>(7, 7, Counter(0));
02866 
02867   const Image<float> kern8 = binomialKernel(8);
02868   const Image<float> kern9 = hcat(kern8, Image<float>(1,1,ZEROS)).render();
02869 
02870   const Image<float> f8x = sepFilter(src, kern8, Image<float>(), CONV_BOUNDARY_CLEAN);
02871   const Image<float> f9x = sepFilter(src, kern9, Image<float>(), CONV_BOUNDARY_CLEAN);
02872 
02873   const Image<float> f8y = sepFilter(src, Image<float>(), kern8, CONV_BOUNDARY_CLEAN);
02874   const Image<float> f9y = sepFilter(src, Image<float>(), kern9, CONV_BOUNDARY_CLEAN);
02875 
02876   REQUIRE_LT(rangeOf(abs(f8x-f9x)).max(), 0.5f);
02877   REQUIRE_LT(fabs(mean(f8x-f9x)), 0.005f);
02878   REQUIRE_EQFP(f8x, f9x, 0.005f);
02879 
02880   REQUIRE_LT(rangeOf(abs(f8y-f9y)).max(), 0.5f);
02881   REQUIRE_LT(fabs(mean(f8y-f9y)), 0.005f);
02882   REQUIRE_EQFP(f8y, f9y, 0.005f);
02883 }
02884 
02885 static void Image_xx_orientedFilter_xx_1(TestSuite& suite)
02886 {
02887   const float orig_data[] =
02888     {
02889       10, 20, 30, 20, 10, 50, 10, 20, 30, 20,
02890       20, 30, 40, 30, 20, 50, 20, 30, 40, 30,
02891       30, 40, 50, 40, 30, 50, 30, 40, 50, 40,
02892       20, 30, 40, 30, 20, 50, 20, 30, 40, 30,
02893       10, 20, 30, 20, 10, 50, 10, 20, 30, 20,
02894       50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
02895       50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
02896       50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
02897       10, 20, 30, 20, 10, 50, 10, 20, 30, 20,
02898       20, 30, 40, 30, 20, 50, 20, 30, 40, 30,
02899       30, 40, 50, 40, 30, 50, 30, 40, 50, 40,
02900       20, 30, 40, 30, 20, 50, 20, 30, 40, 30,
02901       10, 20, 30, 20, 10, 50, 10, 20, 30, 20,
02902     };
02903 
02904   const Image<float> src(orig_data, 10, 13);
02905 
02906   const float expected_data[] = {
02907     233902.047,250623.719,253935.844,239278.641,238924.609,258473.656,261919.859,262513.344,281796.719,303053.625,
02908     225843.578,234913.422,234116.266,218271.859,208632.438,218174.469,226722.812,236762.672,256971.500,275891.656,
02909     200403.828,205929.266,202567.281,189035.500,177270.094,174477.828,178821.438,195386.891,218143.078,234475.688,
02910     102263.820,113528.578,115940.648,110839.195,107660.242,102110.594,93207.430,102330.367,122657.445,134862.062,
02911     91459.391,85742.062,91527.344,95810.195,98878.625,109111.586,109412.320,98036.555,97433.875,108059.281,
02912     251815.953,229960.188,218164.219,213880.000,209260.328,213255.656,222066.203,224363.047,229832.062,243398.000,
02913     320321.594,293108.562,272337.875,264862.750,260077.484,255934.797,261658.047,272536.219,284596.844,298885.781,
02914     272513.438,247958.188,225470.578,219610.375,220951.125,213255.656,210765.562,221831.625,233799.156,243067.531,
02915     127430.023,116273.438,100976.875,97668.055,109103.297,109111.586,99769.367,101574.281,107191.016,108095.719,
02916     94058.680,107256.539,110298.391,98822.922,92682.031,102110.594,108085.828,113659.148,125567.055,135643.500,
02917     198810.375,204759.812,202499.297,189836.312,177871.188,174477.828,178199.688,194368.016,217465.688,234422.422,
02918     238918.094,245396.422,241252.156,230916.797,225684.375,218174.484,209885.812,225632.281,255207.125,275071.062,
02919     253072.625,265567.594,263707.219,256049.375,260779.906,258473.656,240346.828,247880.875,279652.781,301962.344
02920   };
02921   const Image<float> expected(expected_data, 10, 13);
02922 
02923   const float expected_datare[] = {
02924     -73954.562,31536.285,305258.156,327229.906,186689.266,827527.375,105085.578,39506.438,-210786.000,-287240.656,
02925     -373156.281,-483831.938,-390970.969,-33109.398,156572.422,745248.562,368956.469,528518.500,504409.688,138411.406,
02926     -258415.766,-616607.812,-928103.875,-692339.125,-358547.625,-188067.750,159617.281,525646.688,892320.188,732832.938,
02927     225334.047,87022.234,-246115.750,-412436.156,-361673.344,-906619.812,-277650.219,-190245.594,108113.734,333193.406,
02928     182812.406,358083.469,398477.781,110242.641,-35650.812,-589856.312,-172324.484,-371650.031,-465816.969,-175818.984,
02929     220974.734,623095.688,877500.375,923877.562,751232.688,400494.281,-45188.574,-480158.656,-801298.312,-932475.562,
02930     -724454.875,-360562.125,88808.508,517125.500,822848.375,933500.000,822848.375,517125.500,88808.508,-360562.125,
02931     -842592.438,-932475.562,-801298.312,-480158.656,-45188.574,400494.281,751232.688,923877.562,877500.375,623095.688,
02932     293.893,-175818.984,-465816.969,-371650.031,-172324.484,-589856.312,-35650.812,110242.641,398477.781,358083.469,
02933     337541.312,333193.406,108113.734,-190245.594,-277650.219,-906619.812,-361673.344,-412436.156,-246115.750,87022.234,
02934     433558.719,732832.938,892320.188,525646.688,159617.281,-188067.750,-358547.625,-692339.125,-928103.875,-616607.812,
02935     -89531.617,138411.406,504409.688,528518.500,368956.469,745248.562,156572.422,-33109.398,-390970.969,-483831.938,
02936     -182930.812,-287240.656,-210786.000,39506.438,105085.578,827527.375,186689.266,327229.906,305258.156,31536.285
02937   };
02938   const Image<float> expected_re(expected_datare, 10, 13);
02939 
02940   const float expected_dataim[] = {
02941     171428.141,372065.875,469605.625,179855.891,2001.617,-431996.188,-154317.562,-371304.156,-518923.156,-238579.891,
02942     13488.465,282167.750,636279.750,559120.562,338987.656,562162.688,57434.102,-185419.000,-550709.625,-542728.500,
02943     -496923.812,-421313.438,-100227.195,279958.500,430297.094,914359.188,536874.562,530476.938,274202.312,-143757.016,
02944     -297745.062,-553298.375,-705079.562,-378956.969,-92843.711,222402.156,249675.641,526800.375,738932.812,450215.625,
02945     37901.371,-105847.977,-393608.219,-356754.969,-183264.594,-723527.312,-71841.250,36108.480,311008.906,329416.500,
02946     906968.812,695107.188,318457.688,-133688.016,-554140.562,-843223.938,-932405.625,-800543.500,-478897.875,-43720.777,
02947     588716.688,861055.875,929266.000,777176.625,440843.281,0.000,-440843.281,-777176.625,-929266.000,-861055.875,
02948     -401821.156,43720.777,478897.875,800543.500,932405.625,843223.938,554140.562,133688.016,-318457.688,-695107.188,
02949     -186699.766,-329416.500,-311008.906,-36108.480,71841.250,723527.312,183264.594,356754.969,393608.219,105847.977,
02950     -159666.562,-450215.625,-738932.812,-526800.375,-249675.641,-222402.156,92843.711,378956.969,705079.562,553298.375,
02951     354596.719,143757.016,-274202.312,-530476.938,-536874.562,-914359.188,-430297.094,-279958.500,100227.195,421313.438,
02952     362507.438,542728.500,550709.625,185419.000,-57434.102,-562162.688,-338987.656,-559120.562,-636279.750,-282167.750,
02953     37325.633,238579.891,518923.156,371304.156,154317.562,431996.188,-2001.617,-179855.891,-469605.625,-372065.875
02954   };
02955   const Image<float> expected_im(expected_dataim, 10, 13);
02956 
02957   const float expected_dataarg[] = {
02958     -43051.074,-47969.469,-52887.859,-57806.250,-62724.645,-67643.031,-72561.422,-77479.812,-82398.203,-87316.602,
02959     -31777.238,-36695.629,-41614.023,-46532.410,-51450.801,-56369.195,-61287.586,-66205.977,-71124.367,-76042.758,
02960     -20503.398,-25421.791,-30340.184,-35258.570,-40176.965,-45095.352,-50013.746,-54932.137,-59850.527,-64768.922,
02961     -9229.562,-14147.953,-19066.344,-23984.734,-28903.125,-33821.516,-38739.906,-43658.301,-48576.688,-53495.078,
02962     2044.277,-2874.114,-7792.504,-12710.896,-17629.285,-22547.676,-27466.068,-32384.461,-37302.848,-42221.242,
02963     13318.115,8399.725,3481.334,-1437.057,-6355.448,-11273.838,-16192.230,-21110.621,-26029.012,-30947.402,
02964     24591.953,19673.562,14755.173,9836.781,4918.391,0.000,-4918.391,-9836.781,-14755.173,-19673.562,
02965     35865.793,30947.402,26029.012,21110.621,16192.230,11273.838,6355.448,1437.057,-3481.334,-8399.725,
02966     47139.629,42221.242,37302.848,32384.461,27466.068,22547.676,17629.285,12710.896,7792.504,2874.114,
02967     58413.473,53495.078,48576.688,43658.301,38739.906,33821.516,28903.125,23984.734,19066.344,14147.953,
02968     69687.312,64768.922,59850.527,54932.137,50013.746,45095.352,40176.965,35258.570,30340.184,25421.791,
02969     80961.148,76042.758,71124.367,66205.977,61287.586,56369.195,51450.801,46532.410,41614.023,36695.629,
02970     92234.984,87316.602,82398.203,77479.812,72561.422,67643.031,62724.645,57806.250,52887.859,47969.469
02971   };
02972   const Image<float> expected_arg(expected_dataarg, 10, 13);
02973 
02974   const float expected_datacos[] = {
02975     -3961.144,844.571,5450.066,8763.521,9999.426,8864.782,5628.579,1058.019,-3763.364,-7692.572,
02976     -9993.474,-8638.313,-5235.283,-591.134,4193.155,7983.380,9880.998,9436.146,6754.281,2471.191,
02977     -4613.744,-8256.666,-9942.194,-9270.744,-6401.494,-2014.652,2849.800,7038.654,9558.866,9812.975,
02978     6034.656,1553.691,-3295.604,-7363.617,-9685.949,-9712.050,-7435.731,-3396.636,1447.693,5948.821,
02979     9791.773,9589.809,7114.404,2952.401,-1909.524,-6318.761,-9230.021,-9953.134,-8316.676,-4708.597,
02980     2367.164,6674.833,9400.111,9896.921,8047.484,4290.244,-484.077,-5143.639,-8583.807,-9989.026,
02981     -7760.631,-3862.476,951.350,5539.641,8814.658,10000.000,8814.658,5539.641,951.350,-3862.476,
02982     -9026.164,-9989.026,-8583.807,-5143.639,-484.077,4290.244,8047.484,9896.921,9400.111,6674.833,
02983     15.741,-4708.597,-8316.676,-9953.134,-9230.021,-6318.761,-1909.524,2952.401,7114.404,9589.809,
02984     9039.672,5948.821,1447.693,-3396.636,-7435.731,-9712.050,-9685.949,-7363.617,-3295.604,1553.691,
02985     7740.738,9812.975,9558.866,7038.654,2849.800,-2014.652,-6401.494,-9270.744,-9942.194,-8256.666,
02986     -2397.740,2471.191,6754.281,9436.146,9880.998,7983.380,4193.155,-591.134,-5235.283,-8638.313,
02987     -9798.116,-7692.572,-3763.364,1058.019,5628.579,8864.782,9999.426,8763.521,5450.066,844.571
02988   };
02989   const Image<float> expected_cos(expected_datacos, 10, 13);
02990 
02991   const float expected_datasin[] = {
02992     9182.012,9964.271,8384.317,4816.708,107.210,-4627.704,-8265.536,-9943.872,-9264.831,-6389.392,
02993     361.234,5037.811,8520.082,9982.513,9078.405,6022.096,1538.139,-3310.463,-7374.259,-9689.852,
02994     -8872.056,-5641.584,-1073.671,3748.775,7682.505,9794.957,9585.335,7103.333,2937.357,-1924.973,
02995     -7973.890,-9878.565,-9441.345,-6765.881,-2486.441,2382.455,6686.546,9405.470,9894.654,8038.130,
02996     2030.068,-2834.708,-7027.464,-9554.231,-9815.993,-7750.694,-3847.951,967.019,5552.739,8822.082,
02997     9715.788,7446.248,3411.438,-1432.116,-5936.160,-9032.929,-9988.276,-8575.720,-5130.133,-468.353,
02998     6306.552,9223.951,9954.644,8325.405,4722.478,0.000,-4722.478,-8325.405,-9954.644,-9223.951,
02999     -4304.458,468.353,5130.133,8575.720,9988.276,9032.929,5936.160,1432.116,-3411.438,-7446.248,
03000     -9999.987,-8822.082,-5552.739,-967.019,3847.951,7750.694,9815.993,9554.231,7027.464,2834.708,
03001     -4276.020,-8038.130,-9894.654,-9405.470,-6686.546,-2382.455,2486.441,6765.881,9441.345,9878.565,
03002     6330.954,1924.973,-2937.357,-7103.333,-9585.335,-9794.957,-7682.505,-3748.775,1073.671,5641.584,
03003     9708.287,9689.852,7374.259,3310.463,-1538.139,-6022.096,-9078.405,-9982.513,-8520.082,-5037.811,
03004     1999.231,6389.392,9264.831,9943.872,8265.536,4627.704,-107.210,-4816.708,-8384.317,-9964.271
03005   };
03006   const Image<float> expected_sin(expected_datasin, 10, 13);
03007 
03008   const float expected_datare2[] = {
03009     -198870.672,-170569.031,-105781.297,3016.711,131301.156,228119.469,261414.922,243822.578,207083.750,169946.781,
03010     -225843.203,-226634.922,-194836.891,-115253.492,-939.464,110167.797,189945.500,234423.188,251465.484,250186.500,
03011     -170630.672,-195557.047,-202542.375,-175012.906,-111708.742,-26743.404,64441.207,145408.375,201620.875,231070.000,
03012     -37747.637,-59289.730,-82312.852,-101016.750,-107654.484,-92048.188,-50309.738,3362.449,48356.617,77090.258,
03013     61872.816,80620.445,90513.578,78322.539,40683.930,-6542.297,-45842.941,-74071.273,-94482.938,-107893.844,
03014     7200.699,75335.188,148189.641,200200.141,207049.547,167023.625,93622.852,4572.647,-78962.953,-142378.016,
03015     -156214.453,-72886.625,35119.691,146583.953,227419.734,255934.797,229471.484,160911.203,77425.305,3687.065,
03016     -237189.906,-184710.141,-104918.352,-5231.254,92054.281,167023.625,208386.156,211017.281,184240.484,147178.312,
03017     -124733.383,-115620.148,-99428.438,-76080.328,-46203.367,-6542.297,40836.289,80799.805,101851.312,107687.352,
03018     78096.062,72204.789,49448.051,5076.073,-49886.719,-92048.188,-108077.398,-104294.734,-92861.250,-79724.750,
03019     192877.625,204758.359,193294.750,144867.641,64690.156,-26743.402,-111793.133,-177760.344,-216907.656,-231758.359,
03020     168181.391,205336.094,231437.406,229415.047,189495.672,110167.805,-285.233,-113552.664,-198297.938,-246859.703,
03021     70314.711,121817.273,181537.141,235599.938,260322.391,228119.469,132569.672,9338.555,-94736.156,-163147.797
03022   };
03023   const Image<float> expected_re2(expected_datare2, 10, 13);
03024 
03025   const float expected_dataim2[] = {
03026     123128.484,183625.859,230854.344,239259.625,199612.047,121532.492,16256.098,-97282.133,-191117.000,-250917.500,
03027     413.703,61813.645,129803.758,185362.453,208630.312,188316.656,123789.906,33201.414,-52909.965,-116288.109,
03028     -105104.086,-64531.355,-3175.899,71448.609,137643.906,172416.078,166806.594,130508.391,83279.195,39818.387,
03029     -95042.117,-96816.664,-81650.656,-45617.367,1113.320,44200.730,78463.711,102275.109,112723.055,110656.523,
03030     67354.094,29189.809,-13584.793,-55183.090,-90121.031,-108915.273,-99345.258,-64223.145,-23797.771,5977.211,
03031     251712.969,217270.109,160110.766,75263.273,-30337.646,-132593.688,-201365.734,-224316.453,-215841.672,-197410.953,
03032     279647.906,283901.688,270063.906,220602.438,126176.727,0.000,-125728.977,-219962.672,-273862.531,-298863.031,
03033     134180.906,165424.984,199572.344,219548.062,200861.656,132593.688,31580.619,-68417.609,-143935.734,-193443.453,
03034     -26076.699,-12308.285,17615.771,61244.031,98837.125,108915.273,91029.242,61552.637,33409.941,9387.089,
03035     -52421.746,-79312.258,-98593.242,-98692.469,-78110.648,-44200.730,-1349.855,45177.543,84521.438,109741.164,
03036     48205.688,771.516,-60358.137,-122683.297,-165690.500,-172416.078,-138771.125,-78614.125,-15568.865,35241.121,
03037     169696.406,134374.469,68112.594,-26292.568,-122575.797,-188316.656,-209885.625,-194976.203,-160650.547,-121344.070,
03038     243108.203,235980.281,191274.062,100269.422,-15440.636,-121532.484,-200479.125,-247704.906,-263117.344,-254094.578
03039   };
03040   const Image<float> expected_im2(expected_dataim2, 10, 13);
03041 
03042   // let's check that the overall filter works:
03043   float k = 1.23F, theta = 23.57F, intensity = 18.67F;
03044   Image<float> orifilt = orientedFilter(src, k, theta, intensity);
03045   REQUIRE_EQFP(orifilt * 1000.0F, expected, 0.001F);
03046 
03047   // let's do a breakdown of the various steps, taking code from
03048   // Image_FilterOps.C:
03049   double kx = double(k) * cos((theta + 90.0) * M_PI / 180.0);
03050   double ky = double(k) * sin((theta + 90.0) * M_PI / 180.0);
03051   Image<float> re(src.getDims(), NO_INIT), im(src.getDims(), NO_INIT);
03052   Image<float> cosi(src.getDims(), NO_INIT), sinu(src.getDims(), NO_INIT),
03053     argu(src.getDims(), NO_INIT);
03054 
03055   Image<float>::const_iterator sptr = src.begin();
03056   Image<float>::iterator reptr = re.beginw(), imptr = im.beginw(),
03057     argptr = argu.beginw(), cosptr = cosi.beginw(), sinptr = sinu.beginw();
03058   int w2l = src.getWidth() / 2, w2r = src.getWidth() - w2l;
03059   int h2l = src.getHeight() / 2, h2r = src.getHeight() - h2l;
03060   int total = 0;
03061   for (int j = -h2l; j < h2r; j ++)
03062     for (int i = -w2l; i < w2r; i ++)
03063       {
03064         double arg = kx * double(i) + ky * double(j);
03065         float val = (*sptr++) * intensity;
03066         *reptr++ = float(val * cos(arg));
03067         *imptr++ = float(val * sin(arg));
03068 
03069         // additional testing not part of orientedFilter() proper:
03070         *argptr++ = arg;
03071         *cosptr++ = cos(arg);
03072         *sinptr++ = sin(arg);
03073 
03074         total ++;
03075       }
03076 
03077   REQUIRE_EQ(total, 10 * 13);
03078 
03079   REQUIRE_EQFP(re * 1000.0F, expected_re, 0.001F);
03080   REQUIRE_EQFP(im * 1000.0F, expected_im, 0.001F);
03081   REQUIRE_EQFP(argu * 10000.0F, expected_arg, 0.001F);
03082   REQUIRE_EQFP(sinu * 10000.0F, expected_sin, 0.001F);
03083   REQUIRE_EQFP(cosi * 10000.0F, expected_cos, 0.001F);
03084 
03085   re = ::lowPass9(re);
03086   im = ::lowPass9(im);
03087 
03088   REQUIRE_EQFP(re * 1000.0F, expected_re2, 0.001F);
03089   REQUIRE_EQFP(im * 1000.0F, expected_im2, 0.001F);
03090 
03091   Image<float> ener = quadEnergy(re, im);
03092   // this result should be the same as the one of orientedFilter():
03093   REQUIRE_EQFP(ener * 1000.0F, expected, 0.001F);
03094 }
03095 
03096 static void Image_xx_gradientmag_xx_1(TestSuite& suite)
03097 {
03098   // To avoid bugs in involving transposing width/height values, the test
03099   // arrays here should be non-square.
03100   const float orig_data[] =
03101     {
03102       1.0, 1.0, 3.0, 3.0, 1.0, 1.0,
03103       1.0, 1.0, 3.0, 3.0, 1.0, 1.0,
03104       3.0, 3.0, 3.0, 3.0, 3.0, 3.0,
03105       1.0, 1.0, 3.0, 3.0, 1.0, 1.0,
03106       1.0, 1.0, 3.0, 3.0, 1.0, 1.0
03107     };
03108 
03109   const Image<float> orig(orig_data, 6, 5);
03110 
03111   const float sq = sqrtf(8.0f);
03112   const float expected_data[] =
03113     {
03114       0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
03115       0.0, sq,  2.0, 2.0, sq,  0.0,
03116       0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
03117       0.0, sq,  2.0, 2.0, sq,  0.0,
03118       0.0, 0.0, 0.0, 0.0, 0.0, 0.0
03119     };
03120 
03121   const Image<float> expected(expected_data, 6, 5);
03122 
03123   const Image<float> result = gradientmag(orig);
03124 
03125   REQUIRE_EQ(result, expected);
03126 }
03127 
03128 static void Image_xx_gradientori_xx_1(TestSuite& suite)
03129 {
03130   // To avoid bugs in involving transposing width/height values, the test
03131   // arrays here should be non-square.
03132   const float orig_data[] =
03133     {
03134       1.0, 1.0, 3.0, 3.0, 1.0, 1.0,
03135       1.0, 1.0, 3.0, 3.0, 1.0, 1.0,
03136       3.0, 3.0, 3.0, 3.0, 3.0, 3.0,
03137       1.0, 1.0, 3.0, 3.0, 1.0, 1.0,
03138       1.0, 1.0, 3.0, 3.0, 1.0, 1.0
03139     };
03140 
03141   const Image<float> orig(orig_data, 6, 5);
03142 
03143   const float o000 = 0.0F;
03144   const float o045 = float(M_PI / 4.0);
03145   const float o180 = float(M_PI);
03146   const float o135 = float(3.0 * M_PI / 4.0);
03147 
03148   const float expected_data[] =
03149     {
03150       0.0,   0.0,   0.0,   0.0,   0.0, 0.0,
03151       0.0,  o045,  o000,  o180,  o135, 0.0,
03152       0.0,  o000,  o000,  o000,  o000, 0.0,
03153       0.0, -o045,  o000,  o180, -o135, 0.0,
03154       0.0,   0.0,   0.0,   0.0,   0.0, 0.0
03155     };
03156 
03157   const Image<float> expected(expected_data, 6, 5);
03158 
03159   const Image<float> result = gradientori(orig);
03160 
03161   REQUIRE_EQ(result, expected);
03162 }
03163 
03164 static void Image_xx_gradient_xx_1(TestSuite& suite)
03165 {
03166   // To avoid bugs in involving transposing width/height values, the test
03167   // arrays here should be non-square.
03168   const float orig_data[] =
03169     {
03170       1.0, 1.0, 3.0, 3.0, 1.0, 1.0,
03171       1.0, 1.0, 3.0, 3.0, 1.0, 1.0,
03172       3.0, 3.0, 3.0, 3.0, 3.0, 3.0,
03173       1.0, 1.0, 3.0, 3.0, 1.0, 1.0,
03174       1.0, 1.0, 3.0, 3.0, 1.0, 1.0
03175     };
03176 
03177   const Image<float> orig(orig_data, 6, 5);
03178 
03179   const float sq = sqrtf(8.0f);
03180   const float expected_dataM[] =
03181     {
03182       0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
03183       0.0, sq,  2.0, 2.0, sq,  0.0,
03184       0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
03185       0.0, sq,  2.0, 2.0, sq,  0.0,
03186       0.0, 0.0, 0.0, 0.0, 0.0, 0.0
03187     };
03188 
03189   const Image<float> expectedM(expected_dataM, 6, 5);
03190 
03191   const float o000 = 0.0F;
03192   const float o045 = float(M_PI / 4.0);
03193   const float o180 = float(M_PI);
03194   const float o135 = float(3.0 * M_PI / 4.0);
03195 
03196   const float expected_dataO[] =
03197     {
03198       0.0,   0.0,   0.0,   0.0,   0.0, 0.0,
03199       0.0,  o045,  o000,  o180,  o135, 0.0,
03200       0.0,  o000,  o000,  o000,  o000, 0.0,
03201       0.0, -o045,  o000,  o180, -o135, 0.0,
03202       0.0,   0.0,   0.0,   0.0,   0.0, 0.0
03203     };
03204 
03205   const Image<float> expectedO(expected_dataO, 6, 5);
03206 
03207   Image<float> resultM, resultO;
03208   gradient(orig, resultM, resultO);
03209 
03210   REQUIRE_EQ(resultM, expectedM);
03211   REQUIRE_EQ(resultO, expectedO);
03212 }
03213 
03214 #ifdef HAVE_FFTW3_H
03215 
03216 static void Image_xx_fft_xx_1(TestSuite& suite)
03217 {
03218   // try the convolution with all 4 possible combination of even+odd
03219   // filter widths+heights -- this is to test the slightly tricky
03220   // zero-padding involved in fourier convolution
03221   for (int xfiltsize = 14; xfiltsize <= 15; ++xfiltsize)
03222     for (int yfiltsize = 16; yfiltsize <= 17; ++yfiltsize)
03223       {
03224         Image<float> src =
03225           generateImage<float>(Dims(200,200),
03226                                rutz::urand_frange(time((time_t*)0) + getpid()));
03227 
03228         Image<float> boxcar(xfiltsize, yfiltsize, NO_INIT);
03229         std::fill(boxcar.beginw(), boxcar.endw(),
03230                   1.0f/(boxcar.getSize()));
03231 
03232         Convolver fc(boxcar, src.getDims());
03233 
03234         const Image<float> conv1 = fc.spatialConvolve(src);
03235 
03236         const Image<float> conv2 = fc.fftConvolve(src);
03237 
03238         REQUIRE_GT(corrcoef(conv1, conv2), 0.999);
03239         REQUIRE_LT(RMSerr(conv1, conv2), 1.2e-7);
03240       }
03241 
03242   {
03243     Image<float> x(512, 512, ZEROS);
03244     FourierEngine<double> eng(x.getDims());
03245     // just test that this doesn't crash -- buggy fftw3 installs have
03246     // been known to crash for certain input sizes when fftw3 is built
03247     // with --enable-sse2:
03248     (void) eng.fft(x);
03249   }
03250 }
03251 
03252 #endif // HAVE_FFTW3_H
03253 
03254 static void Image_xx_Digest_xx_1(TestSuite& suite)
03255 {
03256   REQUIRE_EQ(Digest<16>::fromString("00112233445566778899aabbccddeeff").asString(),
03257              std::string("00112233445566778899aabbccddeeff"));
03258 
03259   bool caught;
03260 
03261   // string too short:
03262   try {
03263     caught = false;
03264     //Digest<16> d = 
03265       Digest<16>::fromString("00112233445566778899aabbccddeef");
03266   } catch (lfatal_exception& e) { caught = true; }
03267   REQUIRE(caught);
03268 
03269   // string too long:
03270   try {
03271     caught = false;
03272     // Digest<16> d = 
03273       Digest<16>::fromString("00112233445566778899aabbccddeefff");
03274   } catch (lfatal_exception& e) { caught = true; }
03275   REQUIRE(caught);
03276 
03277   // invalid hex chars in string:
03278   try {
03279     caught = false;
03280     //Digest<16> d = 
03281       Digest<16>::fromString("00112233445566778899aabbccddeefg");
03282   } catch (lfatal_exception& e) { caught = true; }
03283   REQUIRE(caught);
03284 }
03285 
03286 static void Image_xx_md5_xx_1(TestSuite& suite)
03287 {
03288   // test data from http://www.cr0.net:8040/code/crypto/md5/; these
03289   // are the standard RFC 1321 test vectors
03290   const char* msg[] =
03291     {
03292       "",
03293       "a",
03294       "abc",
03295       "message digest",
03296       "abcdefghijklmnopqrstuvwxyz",
03297       "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
03298       "12345678901234567890123456789012345678901234567890123456789012345678901234567890"
03299     };
03300 
03301   const char* val[] =
03302     {
03303       "d41d8cd98f00b204e9800998ecf8427e",
03304       "0cc175b9c0f1b6a831c399e269772661",
03305       "900150983cd24fb0d6963f7d28e17f72",
03306       "f96b697d7cb7938d525a2f31aaf161d0",
03307       "c3fcd3d76192e4007dfb496cca67e13b",
03308       "d174ab98d277d9f5a5611c2c9f419d9f",
03309       "57edf4a22be3c955ac49da2e2107b67a"
03310     };
03311 
03312   const Image<byte> img0((const byte*)msg[0], strlen(msg[0]), 1);
03313   const Image<byte> img1((const byte*)msg[1], strlen(msg[1]), 1);
03314   const Image<byte> img2((const byte*)msg[2], strlen(msg[2]), 1);
03315   const Image<byte> img3((const byte*)msg[3], strlen(msg[3]), 1);
03316   const Image<byte> img4((const byte*)msg[4], strlen(msg[4]), 1);
03317   const Image<byte> img5((const byte*)msg[5], strlen(msg[5]), 1);
03318   const Image<byte> img6((const byte*)msg[6], strlen(msg[6]), 1);
03319 
03320   const Digest<16> digest0 = md5byte(&img0);
03321   const Digest<16> digest1 = md5byte(&img1);
03322   const Digest<16> digest2 = md5byte(&img2);
03323   const Digest<16> digest3 = md5byte(&img3);
03324   const Digest<16> digest4 = md5byte(&img4);
03325   const Digest<16> digest5 = md5byte(&img5);
03326   const Digest<16> digest6 = md5byte(&img6);
03327 
03328   REQUIRE_EQ(digest0.asString(), std::string(val[0]));
03329   REQUIRE_EQ(digest1.asString(), std::string(val[1]));
03330   REQUIRE_EQ(digest2.asString(), std::string(val[2]));
03331   REQUIRE_EQ(digest3.asString(), std::string(val[3]));
03332   REQUIRE_EQ(digest4.asString(), std::string(val[4]));
03333   REQUIRE_EQ(digest5.asString(), std::string(val[5]));
03334   REQUIRE_EQ(digest6.asString(), std::string(val[6]));
03335 }
03336 
03337 static void Image_xx_sha1_xx_1(TestSuite& suite)
03338 {
03339   // test data from http://www.cr0.net:8040/code/crypto/sha1/; these
03340   // are the standard FIPS-180-1 test vectors
03341   const char* msg[] =
03342     {
03343       "abc",
03344       "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
03345     };
03346 
03347   const char* val[] =
03348     {
03349       "a9993e364706816aba3e25717850c26c9cd0d89d",
03350       "84983e441c3bd26ebaae4aa1f95129e5e54670f1",
03351       "34aa973cd4c4daa4f61eeb2bdbad27316534016f"
03352     };
03353 
03354   const Image<byte> img0((const byte*)msg[0], strlen(msg[0]), 1);
03355   const Image<byte> img1((const byte*)msg[1], strlen(msg[1]), 1);
03356   Image<byte> img2(Dims(1000000, 1), NO_INIT);
03357   img2.clear('a');
03358 
03359   const Digest<20> digest0 = sha1byte(&img0);
03360   const Digest<20> digest1 = sha1byte(&img1);
03361   const Digest<20> digest2 = sha1byte(&img2);
03362 
03363   REQUIRE_EQ(digest0.asString(), std::string(val[0]));
03364   REQUIRE_EQ(digest1.asString(), std::string(val[1]));
03365   REQUIRE_EQ(digest2.asString(), std::string(val[2]));
03366 }
03367 
03368 static void Image_xx_sha256_xx_1(TestSuite& suite)
03369 {
03370   // test data from http://www.cr0.net:8040/code/crypto/sha2/; these
03371   // are the standard FIPS-180-1 test vectors
03372   const char* msg[] =
03373     {
03374       "abc",
03375       "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
03376     };
03377 
03378   const char* val[] =
03379     {
03380       "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad",
03381       "248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1",
03382       "cdc76e5c9914fb9281a1c7e284d73e67f1809a48a497200e046d39ccc7112cd0"
03383     };
03384 
03385   const Image<byte> img0((const byte*)msg[0], strlen(msg[0]), 1);
03386   const Image<byte> img1((const byte*)msg[1], strlen(msg[1]), 1);
03387   Image<byte> img2(1000000, 1, NO_INIT);
03388   img2.clear(byte('a'));
03389 
03390   const Digest<32> digest0 = sha256byte(&img0);
03391   const Digest<32> digest1 = sha256byte(&img1);
03392   const Digest<32> digest2 = sha256byte(&img2);
03393 
03394   REQUIRE_EQ(digest0.asString(), std::string(val[0]));
03395   REQUIRE_EQ(digest1.asString(), std::string(val[1]));
03396   REQUIRE_EQ(digest2.asString(), std::string(val[2]));
03397 }
03398 
03399 //---------------------------------------------------------------------
03400 //
03401 // DrawOps
03402 //
03403 //---------------------------------------------------------------------
03404 
03405 static void Image_xx_warp3D_xx_1(TestSuite& suite)
03406 {
03407   const Image<PixRGB<byte> > ima =
03408     generateImage<byte>(Dims(11, 11), Counter(5, 2));
03409 
03410   const float z_[] = {
03411     25.1, 10.2,   .3,   .4,   .5,   .6,   .7,   .8,   .9,   .0,   .1,
03412     10.2,  5.3,  1.4,   .5,   .6,   .7,   .8,   .9,  3.0,   .1,   .2,
03413      5.3,  1.4,   .5,   .6,   .7,   .8,   .9,  4.0,  8.1,  3.2,   .3,
03414      5.4,  2.5,  6.6,   .7,   .8,   .9,  9.0,   .1,  3.2,   .3,   .4,
03415      4.5,  1.6, 12.7,  2.8,   .9,   .0,   .1,   .2,   .3,   .4,   .5,
03416      3.6,   .7,  6.8,   .9,  2.0,  9.1, 15.2,   .3, 18.4, 24.5, 15.6,
03417      2.7,   .8,   .9,   .0,   .1,  1.2,   .3,  9.4,   .5,   .6,   .7,
03418      1.8,   .9,   .0,   .1,  9.2,   .3,  2.4,   .5,   .6,   .7,   .8,
03419      1.9,   .0,   .1,  9.2,   .3,   .4,   .5,  1.6,   .7,   .8,   .9,
03420     15.0,  3.1,  5.2,  6.3,  8.4,  9.5, 11.6, 12.7, 14.8, 15.9, 17.0,
03421     10.1,  2.2,  3.3,  4.4,  5.5,  6.6,  7.7,  8.8,  9.9, 10.0, 11.1,
03422   };
03423 
03424   Image<float> z(&z_[0], 11, 11);
03425 
03426   const byte expected_w1_[] = {
03427     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
03428     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
03429     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
03430     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
03431     0,   0,   0,   5,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
03432     0,   0,   0,  29,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
03433     0,   0,   0,  29,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
03434     0,   0,   0,  29,   0,   0,   0,   0,   0,   0, 133,   0,   0,   0,
03435     0,   0,   0,  29,   0,   0,   0,   0,   0,   0, 157,   0,   0,   0,
03436     0,   0,   0,  29,   0,   0,   0,   0,   0,   0, 157,   0,   0,   0,
03437     0,   0,   0,  29,   0,   0,   0,   0,   0, 133, 157,   0,   0,   0,
03438     0,   0,   0,  29,   0,   0,   0,   0,   0, 133, 157,   0,   0,   0,
03439     0,   0,   0,  29,   0,   0,   0,   0,   0, 133, 157, 135,   0,   0,
03440     0,   0,   0,  29,   0,   0,   0,   0,   0, 131, 157, 135,   0,   0,
03441     0,   0,   0,  29,   0,   0,   0,   0,   0, 155, 157, 135,   0,   0,
03442     0,   0,   0,  29,   0,   0,   0, 127,   0, 155, 157, 135,   0,   0,
03443     0,   0,   0,  29,   0,   0,   0, 151,   0, 155, 223, 157,   0,   0,
03444     0, 203,   0,  97,   0,   0,   0, 151,   0, 221, 245, 157,   0,   0,
03445     0, 227,   0, 121,   0,   0, 127, 151, 219, 245, 245, 157,   0,   0,
03446     0, 227,   0, 121,   0,   0, 127, 217, 243, 245, 245, 157,   0,   0,
03447     0, 227,   0, 121,   0,   0, 215, 241, 243, 243, 245, 157,   0,   0,
03448     0, 227,   0, 121,   0, 215, 239, 239, 241, 243, 245, 157,   0,   0,
03449     0, 227, 205, 187,  99, 213, 237, 239, 241, 243, 245, 157,   0,   0,
03450     0, 227, 227, 209, 211, 237, 237, 239, 175, 243, 155, 157,   0,   0,
03451     0, 227, 227, 211, 235, 235, 237, 149, 175, 153, 155, 157,   0,   0,
03452     0,   0, 227, 209, 233, 235, 147, 151, 175, 153, 155, 157,   0,   0,
03453     0,   0, 227, 231, 233, 191, 169, 173, 175, 153, 155, 157,   0,   0,
03454     0, 181, 227, 229, 189, 191, 171, 173, 175, 153, 155, 157,  69,   0,
03455     0, 183, 227, 187, 189, 191, 193, 195, 175, 153, 155, 157,   0,   0,
03456     0,   0, 183, 185, 189, 191, 193, 173, 197, 199, 201,   0,   0,   0,
03457     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
03458     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
03459     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
03460     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
03461     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
03462     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
03463     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
03464     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
03465     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
03466     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
03467     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
03468     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
03469     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0
03470   };
03471   const Image<byte> expected_w1(&expected_w1_[0], 14, 43);
03472 
03473   const byte expected_w2_[] = {
03474     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
03475     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
03476     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
03477     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
03478     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
03479     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
03480     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
03481     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
03482     0,   0,   0,   0, 203, 225,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
03483     0,   0,   0,   0, 205, 227,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
03484     0,   0,   0,   0,   0, 227, 227,   0,   0,   0,   0,   0,   0,   0,   0,   0,
03485     0,   0,   0,   0,   0, 205, 227, 231, 233, 235, 237, 239, 241, 223,   0,   0,
03486     0,   0,   0,   0, 181,   0, 187, 189,   0,   0,   0, 133,   0, 243, 245,   0,
03487     0,   5,   0, 159,   0, 183, 185, 167, 189,   0, 133, 157,   0,   0,   0,   0,
03488     0,  29,   0, 137, 161, 163, 167, 169, 191,   0, 131, 157, 135,   0,   0,   0,
03489     0,  29,  93,  97, 121, 141, 165, 125, 169, 193, 195, 157, 135,   0,   0,   0,
03490     0,  49,  73,  95,  75, 121, 123, 149, 151, 153, 173, 197, 199, 201,   0,   0,
03491     0,  51,  29,  73,  77,   0, 101,  83, 149, 131, 153, 155, 177, 179,   0,   0,
03492     0,   9,  51,  53,  77,  79,  83, 103, 107, 129,   0, 155, 157,   0,   0,   0,
03493     0,   0,   9,  31,  55,  57,  81,  61,  85, 109, 111, 113,   0,   0,   0,   0,
03494     0,   0,   0,  11,  13,  15,  39,  41,  43,   0,  67,  91,   0,   0,   0,   0,
03495     0,   0,   0,   0,   0,   0,  17,  19,   0,  45,  69,   0,   0,   0,   0,   0,
03496     0,   0,   0,   0,   0,   0,   0,   0,  21,  23,  47,   0,   0,   0,   0,   0,
03497     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  25,   0,   0,   0,   0,   0,
03498     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
03499     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
03500     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
03501     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
03502     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
03503     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
03504     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
03505     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
03506   };
03507   const Image<byte> expected_w2(&expected_w2_[0], 16, 32);
03508 
03509   float pitch, yaw;
03510   Dims d;
03511 
03512   pitch = -25.0f;
03513   yaw = -15.0f;
03514   d = Dims();
03515   const Image<byte> w1 = luminance(warp3D(ima, z, pitch, yaw, 25.1f, d));
03516 
03517   pitch = +75.0f;
03518   yaw = +25.0f;
03519   d = Dims();
03520   const Image<byte> w2 = luminance(warp3D(ima, z, pitch, yaw, 25.1f, d));
03521 
03522   REQUIRE_EQ(w2, expected_w2);
03523 }
03524 
03525 //---------------------------------------------------------------------
03526 //
03527 // Transforms
03528 //
03529 //---------------------------------------------------------------------
03530 
03531 static void Image_xx_makeBinary_xx_1(TestSuite& suite)
03532 {
03533   const byte data[6] = { 0, 1, 63, 64, 254, 255 };
03534   const byte bindata[6] = { 20, 20, 20, 10, 10, 10 };
03535 
03536   Image<byte> img(data, 6, 1);
03537   Image<byte> binimg(bindata, 6, 1);
03538 
03539   REQUIRE_EQ(makeBinary(img, byte(63), byte(20), byte(10)), binimg);
03540 }
03541 
03542 static void Image_xx_contour2D_xx_1(TestSuite& suite)
03543 {
03544   byte orig_data[] =
03545     {
03546       0, 1, 0, 0, 0,
03547       1, 1, 1, 1, 0,
03548       0, 1, 1, 0, 0,
03549       0, 1, 0, 1, 0,
03550       0, 0, 0, 0, 0
03551     };
03552 
03553   byte contour_data[] =
03554     {
03555       0,   255, 0,   0,   0,
03556       255, 0,   255, 255, 0,
03557       0,   255, 255, 0,   0,
03558       0,   255, 0,   255, 0,
03559       0,   0,   0,   0,   0
03560     };
03561 
03562   Image<byte> orig(orig_data, 5, 5);
03563 
03564   Image<byte> contour(contour_data, 5, 5);
03565 
03566   Image<byte> c2d = contour2D(orig);
03567 
03568   REQUIRE_EQ(c2d, contour);
03569 }
03570 
03571 //--------------------------------------------------------------------
03572 //
03573 // Point2d
03574 //
03575 //-------------------------------------------------------------------
03576 
03577 static void Point2D_xx_testConstructAdd_xx_1(TestSuite& suite)
03578 {
03579 
03580     Point2D<int> pi(1,1);
03581     Point2D<float> pf(2.0,2.0);
03582     Point2D<double> pd(3.9,3.9);
03583     pi += 2;
03584     pf +=2.5;
03585     pd +=1.0;
03586     REQUIRE_EQ(pi.i,3);
03587     REQUIRE_EQ(pf.i,4.5);
03588     REQUIRE_EQ(pd.i,4.9);
03589 }
03590 
03591 
03592 static void Point2D_xx_testConvertType_xx_1(TestSuite& suite)
03593 {
03594 
03595     Point2D<float> pf(1.0,1.0);
03596     Point2D<double>pdf(pf);
03597     Point2D<int>   adder(1,1);
03598 
03599     pdf = pdf + adder;
03600 
03601     REQUIRE_EQ(pdf.i,2.0);
03602 
03603     REQUIRE_EQ(sizeof(pdf+adder), sizeof(Point2D<double>));
03604 
03605     Point2D<int> p2(300, -450);
03606     Point2D<byte> p3(p2);
03607     REQUIRE_EQ(p3.i, byte(255));
03608     REQUIRE_EQ(p3.j, byte(0));
03609 }
03610 
03611 
03612 
03613 
03614 ///////////////////////////////////////////////////////////////////////
03615 //
03616 // main
03617 //
03618 ///////////////////////////////////////////////////////////////////////
03619 
03620 int main(int argc, const char** argv)
03621 {
03622   TestSuite suite;
03623 
03624   suite.ADD_TEST(Rectangle_xx_getOverlap_xx_1);
03625   suite.ADD_TEST(Rectangle_xx_constrain_xx_1);
03626 
03627   suite.ADD_TEST(Image_xx_construct_from_array_xx_1);
03628   suite.ADD_TEST(Image_xx_construct_UDT_xx_1);
03629   suite.ADD_TEST(Image_xx_construct_and_clear_xx_1);
03630   suite.ADD_TEST(Image_xx_default_construct_xx_1);
03631   suite.ADD_TEST(Image_xx_swap_xx_1);
03632   suite.ADD_TEST(Image_xx_copy_xx_1);
03633   suite.ADD_TEST(Image_xx_copy_on_write_xx_1);
03634   suite.ADD_TEST(Image_xx_copy_on_write_xx_2);
03635   suite.ADD_TEST(Image_xx_copy_on_write_xx_3);
03636   suite.ADD_TEST(Image_xx_assignment_to_self_xx_1);
03637   suite.ADD_TEST(Image_xx_reshape_xx_1);
03638   suite.ADD_TEST(Image_xx_indexing_xx_1);
03639   suite.ADD_TEST(Image_xx_type_convert_xx_1);
03640   suite.ADD_TEST(Image_xx_type_convert_xx_2);
03641   suite.ADD_TEST(Image_xx_type_convert_xx_3);
03642   suite.ADD_TEST(Image_xx_attach_detach_xx_1);
03643   suite.ADD_TEST(Image_xx_destruct_xx_1);
03644   suite.ADD_TEST(Image_xx_begin_end_xx_1);
03645   suite.ADD_TEST(Image_xx_beginw_endw_xx_1);
03646   suite.ADD_TEST(Image_xx_getMean_xx_1);
03647   suite.ADD_TEST(Image_xx_clear_xx_1);
03648 
03649   suite.ADD_TEST(Image_xx_plus_eq_scalar_xx_1);
03650   suite.ADD_TEST(Image_xx_minus_eq_scalar_xx_1);
03651   suite.ADD_TEST(Image_xx_mul_eq_scalar_xx_1);
03652   suite.ADD_TEST(Image_xx_div_eq_scalar_xx_1);
03653   suite.ADD_TEST(Image_xx_lshift_eq_scalar_xx_1);
03654   suite.ADD_TEST(Image_xx_rshift_eq_scalar_xx_1);
03655 
03656   suite.ADD_TEST(Image_xx_plus_eq_array_xx_1);
03657   suite.ADD_TEST(Image_xx_minus_eq_array_xx_1);
03658   suite.ADD_TEST(Image_xx_mul_eq_array_xx_1);
03659   suite.ADD_TEST(Image_xx_div_eq_array_xx_1);
03660 
03661   suite.ADD_TEST(Image_xx_plus_scalar_xx_1);
03662   suite.ADD_TEST(Image_xx_minus_scalar_xx_1);
03663   suite.ADD_TEST(Image_xx_mul_scalar_xx_1);
03664   suite.ADD_TEST(Image_xx_div_scalar_xx_1);
03665   suite.ADD_TEST(Image_xx_lshift_scalar_xx_1);
03666   suite.ADD_TEST(Image_xx_rshift_scalar_xx_1);
03667 
03668   suite.ADD_TEST(Image_xx_plus_array_xx_1);
03669   suite.ADD_TEST(Image_xx_minus_array_xx_1);
03670   suite.ADD_TEST(Image_xx_minus_array_xx_2);
03671   suite.ADD_TEST(Image_xx_mul_array_xx_1);
03672   suite.ADD_TEST(Image_xx_div_array_xx_1);
03673 
03674   suite.ADD_TEST(Image_xx_row_ops_xx_1);
03675 
03676   suite.ADD_TEST(Image_xx_emptyArea_xx_1);
03677 
03678   // MathOps
03679   suite.ADD_TEST(Image_xx_mean_xx_1);
03680   suite.ADD_TEST(Image_xx_sum_xx_1);
03681   suite.ADD_TEST(Image_xx_sum_xx_2);
03682   suite.ADD_TEST(Image_xx_rangeOf_xx_1);
03683   suite.ADD_TEST(Image_xx_rangeOf_xx_2);
03684   suite.ADD_TEST(Image_xx_remapRange_xx_1);
03685   suite.ADD_TEST(Image_xx_squared_xx_1);
03686   suite.ADD_TEST(Image_xx_toPower_xx_1);
03687   suite.ADD_TEST(Image_xx_toPower_xx_2);
03688   suite.ADD_TEST(Image_xx_quadEnergy_xx_1);
03689   suite.ADD_TEST(Image_xx_overlay_xx_1);
03690   suite.ADD_TEST(Image_xx_exp_xx_1);
03691   suite.ADD_TEST(Image_xx_log_xx_1);
03692   suite.ADD_TEST(Image_xx_log10_xx_1);
03693   suite.ADD_TEST(Image_xx_getMaskedMinMax_xx_1);
03694   suite.ADD_TEST(Image_xx_getMaskedMinMaxAvg_xx_1);
03695 
03696   // MatrixOps
03697   suite.ADD_TEST(Image_xx_vmMult_xx_1);
03698   suite.ADD_TEST(Image_xx_vmMult_xx_2);
03699   suite.ADD_TEST(Image_xx_matrixMult_xx_1);
03700   suite.ADD_TEST(Image_xx_matrixMult_xx_2);
03701   suite.ADD_TEST(Image_xx_matrixMult_xx_3);
03702   suite.ADD_TEST(Image_xx_matrixMult_xx_4);
03703   suite.ADD_TEST(Image_xx_matrixInv_xx_1);
03704   suite.ADD_TEST(Image_xx_matrixInv_xx_2);
03705   suite.ADD_TEST(Image_xx_matrixInv_xx_3);
03706   suite.ADD_TEST(Image_xx_matrixDet_xx_1);
03707   suite.ADD_TEST(Image_xx_matrixDet_xx_2);
03708   suite.ADD_TEST(Image_xx_matrixDet_xx_3);
03709   suite.ADD_TEST(Image_xx_svd_gsl_xx_1);
03710   suite.ADD_TEST(Image_xx_svd_lapack_xx_1);
03711   suite.ADD_TEST(Image_xx_svd_lapack_xx_2);
03712   suite.ADD_TEST(Image_xx_svd_full_xx_1);
03713 
03714   // ShapeOps
03715   suite.ADD_TEST(Image_xx_rescale_xx_1);
03716   suite.ADD_TEST(Image_xx_rescale_xx_2);
03717   suite.ADD_TEST(Image_xx_rescale_xx_3);
03718   suite.ADD_TEST(Image_xx_rescale_xx_4);
03719   suite.ADD_TEST(Image_xx_rescale_xx_5);
03720   suite.ADD_TEST(Image_xx_zoomXY_xx_1);
03721   suite.ADD_TEST(Image_xx_zoomXY_xx_2);
03722   suite.ADD_TEST(Image_xx_zoomXY_xx_3);
03723   suite.ADD_TEST(Image_xx_zoomXY_xx_4);
03724   suite.ADD_TEST(Image_xx_interpolate_xx_1);
03725   suite.ADD_TEST(Image_xx_decY_xx_1);
03726   suite.ADD_TEST(Image_xx_blurAndDecY_xx_1);
03727 
03728   // CutPaste
03729   suite.ADD_TEST(Image_xx_concatX_xx_1);
03730   suite.ADD_TEST(Image_xx_concatY_xx_1);
03731   suite.ADD_TEST(Image_xx_concatLooseX_xx_1);
03732   suite.ADD_TEST(Image_xx_concatLooseY_xx_1);
03733   suite.ADD_TEST(Image_xx_crop_xx_1);
03734 
03735   // FilterOps
03736   suite.ADD_TEST(Image_xx_lowPass3x_xx_1);
03737   suite.ADD_TEST(Image_xx_lowPass3y_xx_1);
03738   suite.ADD_TEST(Image_xx_lowPass3_xx_1);
03739   suite.ADD_TEST(Image_xx_lowPass5x_xx_1);
03740   suite.ADD_TEST(Image_xx_lowPass5y_xx_1);
03741   suite.ADD_TEST(Image_xx_lowPass5_xx_1);
03742   suite.ADD_TEST(Image_xx_binomialKernel_xx_1);
03743   suite.ADD_TEST(Image_xx_sepFilter_xx_1);
03744   suite.ADD_TEST(Image_xx_sepFilter_xx_2);
03745   suite.ADD_TEST(Image_xx_sepFilter_xx_3);
03746   suite.ADD_TEST(Image_xx_sepFilter_xx_4);
03747   suite.ADD_TEST(Image_xx_sepFilter_xx_5);
03748   suite.ADD_TEST(Image_xx_orientedFilter_xx_1);
03749   suite.ADD_TEST(Image_xx_gradientmag_xx_1);
03750   suite.ADD_TEST(Image_xx_gradientori_xx_1);
03751   suite.ADD_TEST(Image_xx_gradient_xx_1);
03752 
03753 #ifdef HAVE_FFTW3_H
03754   suite.ADD_TEST(Image_xx_fft_xx_1);
03755 #endif // HAVE_FFTW3_H
03756 
03757   suite.ADD_TEST(Image_xx_Digest_xx_1);
03758   suite.ADD_TEST(Image_xx_md5_xx_1);
03759   suite.ADD_TEST(Image_xx_sha1_xx_1);
03760   suite.ADD_TEST(Image_xx_sha256_xx_1);
03761 
03762   // DrawOps
03763   suite.ADD_TEST(Image_xx_warp3D_xx_1);
03764 
03765   // Transforms
03766   suite.ADD_TEST(Image_xx_makeBinary_xx_1);
03767   suite.ADD_TEST(Image_xx_contour2D_xx_1);
03768 
03769   // Point2d
03770   suite.ADD_TEST(Point2D_xx_testConstructAdd_xx_1);
03771   suite.ADD_TEST(Point2D_xx_testConvertType_xx_1);
03772 
03773 
03774   suite.parseAndRun(argc, argv);
03775 
03776   return 0;
03777 }
03778 
03779 // ######################################################################
03780 /* So things look consistent in everyone's emacs... */
03781 /* Local Variables: */
03782 /* indent-tabs-mode: nil */
03783 /* End: */
Generated on Sun May 8 08:42:23 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3