ResizeSpec.C

Go to the documentation of this file.
00001 /*!@file Image/ResizeSpec.C Represents multiple ways of transforming image dimensions */
00002 
00003 // //////////////////////////////////////////////////////////////////// //
00004 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2000-2005   //
00005 // by the University of Southern California (USC) and the iLab at USC.  //
00006 // See http://iLab.usc.edu for information about this project.          //
00007 // //////////////////////////////////////////////////////////////////// //
00008 // Major portions of the iLab Neuromorphic Vision Toolkit are protected //
00009 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency //
00010 // in Visual Environments, and Applications'' by Christof Koch and      //
00011 // Laurent Itti, California Institute of Technology, 2001 (patent       //
00012 // pending; application number 09/912,225 filed July 23, 2001; see      //
00013 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status).     //
00014 // //////////////////////////////////////////////////////////////////// //
00015 // This file is part of the iLab Neuromorphic Vision C++ Toolkit.       //
00016 //                                                                      //
00017 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can   //
00018 // redistribute it and/or modify it under the terms of the GNU General  //
00019 // Public License as published by the Free Software Foundation; either  //
00020 // version 2 of the License, or (at your option) any later version.     //
00021 //                                                                      //
00022 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope  //
00023 // that it will be useful, but WITHOUT ANY WARRANTY; without even the   //
00024 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      //
00025 // PURPOSE.  See the GNU General Public License for more details.       //
00026 //                                                                      //
00027 // You should have received a copy of the GNU General Public License    //
00028 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write   //
00029 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,   //
00030 // Boston, MA 02111-1307 USA.                                           //
00031 // //////////////////////////////////////////////////////////////////// //
00032 //
00033 // Primary maintainer for this file: Rob Peters <rjpeters at usc dot edu>
00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Image/ResizeSpec.C $
00035 // $Id: ResizeSpec.C 8828 2007-10-12 21:20:18Z rjpeters $
00036 //
00037 
00038 #ifndef IMAGE_RESIZESPEC_C_DEFINED
00039 #define IMAGE_RESIZESPEC_C_DEFINED
00040 
00041 #include "Image/ResizeSpec.H"
00042 
00043 #include "Util/Assert.H"
00044 #include "Util/StringConversions.H"
00045 #include "Util/StringUtil.H"
00046 #include "Util/log.H"
00047 #include "Util/sformat.H"
00048 
00049 #include <iterator>
00050 #include <vector>
00051 
00052 // ######################################################################
00053 bool ResizeSpec::operator==(const ResizeSpec& that) const
00054 {
00055   if (this->itsMethod != that.itsMethod)
00056     return false;
00057 
00058   // OK, now what if the methods are the same:
00059 
00060   switch (this->itsMethod)
00061     {
00062     case NOOP:
00063       return true;
00064       break;
00065 
00066     case FIXED:
00067       return this->itsNewDims == that.itsNewDims;
00068       break;
00069 
00070     case SCALE_UP:     // fall-through
00071     case SCALE_DOWN:
00072       return (this->itsFactorW == that.itsFactorW
00073               && this->itsFactorH == that.itsFactorH);
00074       break;
00075     }
00076 
00077   ASSERT(0); /* can't happen */ return false;
00078 }
00079 
00080 // ######################################################################
00081 std::string ResizeSpec::toString() const
00082 {
00083   switch (itsMethod)
00084     {
00085     case NOOP: return "noop"; break;
00086 
00087     case FIXED: return convertToString(itsNewDims); break;
00088 
00089     case SCALE_UP:
00090       if (itsFactorW == itsFactorH)
00091         return sformat("*%g", itsFactorW);
00092       else
00093         return sformat("*%gx%g", itsFactorW, itsFactorH);
00094       break;
00095 
00096     case SCALE_DOWN:
00097       if (itsFactorW == itsFactorH)
00098         return sformat("/%g", itsFactorW);
00099       else
00100         return sformat("/%gx%g", itsFactorW, itsFactorH);
00101       break;
00102     }
00103 
00104   ASSERT(0); /* can't happen */ return std::string();
00105 }
00106 
00107 // ######################################################################
00108 ResizeSpec ResizeSpec::fromString(const std::string& origstr)
00109 {
00110   const std::string str = toLowerCase(origstr);
00111 
00112   if (str.length() == 0
00113       || str.compare("none") == 0
00114       || str.compare("noop") == 0)
00115     {
00116       return ResizeSpec(); // no-op ResizeSpec
00117     }
00118   else if (str[0] == '*' || str[0] == '/')
00119     {
00120       const Method m = (str[0] == '*' ? SCALE_UP : SCALE_DOWN);
00121 
00122       std::vector<std::string> parts;
00123       split(str.substr(1), "x", std::back_inserter(parts));
00124 
00125       if (parts.size() == 1)
00126         {
00127           const double f = fromStr<double>(parts[0]);
00128           if (f < 0.0)
00129             LFATAL("while parsing '%s' as a ResizeSpec: expected "
00130                    "a non-negative scale factor, but got %s",
00131                    origstr.c_str(), parts[0].c_str());
00132 
00133           if (f == 0.0 || f == 1.0)
00134             return ResizeSpec(); // no-op ResizeSpec
00135 
00136           return ResizeSpec(m, Dims(), f, f);
00137         }
00138       else if (parts.size() == 2)
00139         {
00140           const double fw = fromStr<double>(parts[0]);
00141           const double fh = fromStr<double>(parts[1]);
00142 
00143           if (fw < 0.0)
00144             LFATAL("while parsing '%s' as a ResizeSpec: expected "
00145                    "a non-negative scale factor, but got %s",
00146                    origstr.c_str(), parts[0].c_str());
00147 
00148           if (fh < 0.0)
00149             LFATAL("while parsing '%s' as a ResizeSpec: expected "
00150                    "a non-negative scale factor, but got %s",
00151                    origstr.c_str(), parts[1].c_str());
00152 
00153           if ((fw == 0.0 || fw == 1.0) && (fh == 0.0 || fh == 1.0))
00154             return ResizeSpec(); // no-op ResizeSpec
00155 
00156           return ResizeSpec(m, Dims(), fw, fh);
00157         }
00158       else
00159         LFATAL("while parsing '%s' as a ResizeSpec: after '%c', "
00160                "expected either one floating-point value or "
00161                "two values separated by 'x', but got '%s'",
00162                origstr.c_str(), str[0], str.substr(1).c_str());
00163     }
00164   else
00165     {
00166       const Dims d = fromStr<Dims>(str);
00167       if (d.isEmpty())
00168         return ResizeSpec(); // no-op ResizeSpec
00169       return ResizeSpec(FIXED, d, 0.0, 0.0);
00170     }
00171 
00172   conversion_error::raise<ResizeSpec>(origstr);
00173   ASSERT(0); /* can't happen */ return ResizeSpec();
00174 }
00175 
00176 // ######################################################################
00177 Dims ResizeSpec::transformDims(const Dims& in)
00178 {
00179   switch (itsMethod)
00180     {
00181     case NOOP:
00182       return in;
00183       break;
00184 
00185     case FIXED:
00186       return itsNewDims;
00187       break;
00188 
00189     case SCALE_UP:
00190       // if a scale factor is 0, then that dimension just passes
00191       // through untouched
00192       return Dims(itsFactorW > 0.0
00193                   ? int(0.5 + in.w() * itsFactorW)
00194                   : in.w(),
00195                   itsFactorH > 0.0
00196                   ? int(0.5 + in.h() * itsFactorH)
00197                   : in.h());
00198       break;
00199 
00200     case SCALE_DOWN:
00201       // if a scale factor is 0, then that dimension just passes
00202       // through untouched
00203       return Dims(itsFactorW > 0.0
00204                   ? int(0.5 + in.w() / itsFactorW)
00205                   : in.w(),
00206                   itsFactorH > 0.0
00207                   ? int(0.5 + in.h() / itsFactorH)
00208                   : in.h());
00209       break;
00210     }
00211 
00212   // we should never get here, because even if the user gave bogus
00213   // input, we should have caught that in convertFromString() or
00214   // wherever, so that once we have a ResizeSpec object, it should be
00215   // guaranteed to have a valid itsMethod value:
00216   ASSERT(0); /* can't happen */ return Dims();
00217 }
00218 
00219 // ######################################################################
00220 /* So things look consistent in everyone's emacs... */
00221 /* Local Variables: */
00222 /* mode: c++ */
00223 /* indent-tabs-mode: nil */
00224 /* End: */
00225 
00226 #endif // IMAGE_RESIZESPEC_C_DEFINED
Generated on Sun May 8 08:40:57 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3