Homepage Demos Overview Downloads Tutorials Reference
Credits

Sketch.h

Go to the documentation of this file.
00001 //-*-c++-*-
00002 
00003 #ifndef INCLUDED_Sketch_h
00004 #define INCLUDED_Sketch_h
00005 
00006 #include <valarray>
00007 #include <string>
00008 
00009 #include "SketchTypes.h"
00010 #include "SketchRoot.h"
00011 
00012 namespace DualCoding {
00013 
00014 class SketchSpace;
00015 class SketchIndices;
00016 template<typename T> class SketchData;
00017 
00018 //! Smart pointers for referencing @code SketchData<T> @endcode instances
00019 /*! This is the structure that provides safe user-level access to sketches.
00020  *  It's a smart pointer that does reference counting, and
00021  *  overloads operator-> so it can do validity checking.
00022  *  If the validity check succeeds, operator-> dereferences to a
00023  *  SketchData<T> object.  */
00024 
00025 template<typename T>
00026 class Sketch : public SketchRoot {
00027 public:
00028   int width, height;
00029 
00030   //! The SketchData object referenced by this Sketch.
00031   SketchData<T> *data;
00032 
00033   //! The image resource for the Sketch, owned by the SketchData object.
00034   std::valarray<T> *pixels;
00035 
00036   //! Constructor.  Allocates a new SketchData<T> to hold the data.
00037   Sketch(SketchSpace &_space, const std::string& _name = "(no name)");
00038 
00039   //! Constructor.  Inherits parent and color information from parent sketch.
00040   Sketch(const std::string& _name, const SketchRoot& parent);
00041 
00042   //! Dummy constructor, for use in vector construction.
00043   Sketch();
00044 
00045   /*! @brief Copy constructor, used in something like @code Sketch<bool> image = original; @endcode
00046    *  This is a shallow copy: it does not copy the underlying pixels. */
00047   Sketch(const Sketch &other);
00048 
00049   //! Shallow copy constructor used by NEW_SKETCH and NEW_SKETCH_N
00050   Sketch(const Sketch &other, const std::string &name, bool viewable);
00051 
00052   //! Destructor.  Cleans up and decrements SketchData reference count.
00053   virtual ~Sketch();
00054 
00055   //! Retrieve an existing sketch by name.
00056   Sketch(const std::string &name, SketchSpace &space);
00057 
00058   //! True if this Sketch actually points to a SketchData
00059   inline bool isValid() const { return data != NULL; }
00060 
00061   //! Print error message if Sketch fails isValid() test
00062   void checkValid() const;
00063 
00064   SketchData<T>* operator->() { checkValid(); return data; }
00065   const SketchData<T>* operator->() const { checkValid(); return data; }
00066 
00067   T& operator[] (size_t idx) { checkValid(); return (*pixels)[idx]; };
00068   const T& operator[] (size_t idx) const { checkValid(); return (*pixels)[idx]; };
00069   //! when passed indirection matrix (e.g. idx_left) returns resampled Sketch
00070   const Sketch<T> operator[] (const Sketch<usint>& indirection) const;
00071 
00072   T& operator() (size_t x, size_t y) { checkValid(); return (*pixels)[y*width + x]; };
00073   const T& operator() (size_t x, size_t y) const { checkValid(); return (*pixels)[y*width + x]; };
00074 
00075   Sketch& setIndices(const SketchIndices& indices, const T& value);
00076 
00077   //! Make this sketch point to another sketch's SketchData.
00078   void bind(const Sketch& other);
00079 
00080   //! Assignment operator: copies the pixels.
00081   Sketch& operator= (const Sketch& other);
00082 
00083   //! Sets all pixels in the Sketch to the specified value.
00084   Sketch& operator= (const T& value);
00085 
00086   Sketch<bool> operator!() const;
00087   
00088   Sketch<T>& operator+= (const Sketch<T>& other);
00089   Sketch<T>& operator-= (const Sketch<T>& other);
00090   Sketch<T>& operator*= (const Sketch<T>& other);
00091   Sketch<T>& operator/= (const Sketch<T>& other);
00092 
00093   Sketch<T>& operator+= (const T value);
00094   Sketch<T>& operator-= (const T value);
00095   Sketch<T>& operator*= (const T value);
00096   Sketch<T>& operator/= (const T value);
00097 
00098   Sketch& operator+= (const int value);
00099   Sketch& operator-= (const int value);
00100   Sketch& operator*= (const int value);
00101   Sketch& operator/= (const int value);
00102 
00103   void printVals() const;
00104 
00105   //! operator for implicitly or explicitly converting to Sketch<bool>
00106   operator Sketch<bool>() const;
00107 
00108   //! operator for implicity or explicitly converting to Sketch<uchar>
00109   operator Sketch<uchar>() const;
00110 
00111   //! operator for implicity or explicitly converting to Sketch<usint>
00112   operator Sketch<usint>() const;
00113 
00114   //! operator for implicity or explicitly converting to Sketch<float>
00115   operator Sketch<float>() const;
00116 
00117 };
00118 
00119 // ****************************************************************
00120 
00121 
00122 } // namespace
00123 
00124 #include "SketchData.h"
00125 #include "SketchIndices.h"
00126 #include "SketchSpace.h"
00127 
00128 namespace visops {
00129   template <class T> DualCoding::Sketch<T> copy(const DualCoding::Sketch<T>& other);
00130 }
00131 
00132 namespace DualCoding {
00133 
00134 // First constructor: requires a SketchSpace
00135 template <class T>
00136 Sketch<T>::Sketch(SketchSpace &_space, const std::string &_name)
00137   : SketchRoot(), width(_space.getWidth()), height(_space.getHeight()),
00138     data(_space.get_pool(*this).get_free_element()),
00139     pixels(&data->pixels)
00140 {
00141   data->name = _name;
00142   data->id = getNewId();
00143   data->parentId = 0;
00144   data->viewable = false;
00145   data->colormap = segMap;
00146   ++data->refcount;
00147   (*pixels)[_space.dummy] = 0;
00148   /*
00149   std::cout << "Creating new Sketch " << this << " '" << data->name << "'"
00150       << " [" << data << "]"
00151       << " id=" << getId() << ",parent=" << getParentId()
00152       << ",refcount=" << data->refcount << std::endl;
00153   */
00154 }
00155 
00156 // Second constructor: requires a parent sketch
00157 template <class T>
00158 Sketch<T>::Sketch(const std::string& _name, const SketchRoot& _parent)
00159   : SketchRoot(), width(), height(), data(NULL), pixels(NULL) {
00160   SketchSpace& space = _parent.rootGetSpace();
00161   width = space.getWidth();
00162   height = space.getHeight();
00163   data = space.get_pool(*this).get_free_element();
00164   data->name = _name;
00165   data->id = getNewId();
00166   data->inheritFrom(_parent.rootGetData());
00167   data->viewable = false;
00168   ++data->refcount;
00169   pixels = &data->pixels;
00170   (*pixels)[space.dummy] = 0;
00171   /*
00172   std::cout << "Creating new Sketch " << this << " '" << data->name << "'"
00173       << " [" << data << "]"
00174       << " id=" << getId() << ",parent=" << getParentId()
00175       << ",refcount=" << data->refcount << std::endl;
00176   */
00177 }
00178 
00179 // Dummy constructor
00180 template <typename T>
00181 Sketch<T>::Sketch()
00182   : SketchRoot(), width(), height(), data(NULL), pixels(NULL) {}
00183 
00184 // Retrieve existing sketch
00185 template <typename T>
00186 Sketch<T>::Sketch(const std::string &name, SketchSpace &space)
00187   : SketchRoot(), width(space.getWidth()), height(space.getHeight()), 
00188    data(space.get_pool(*this).findSketchData(name)), 
00189    pixels(data != NULL ? &data->pixels : NULL) {
00190   if ( data != NULL )
00191    ++data->refcount;
00192 }
00193 
00194 #define NEW_SKETCH_N(name,T,value) Sketch<T> name(value,#name,false);
00195 #define NEW_SKETCH(name,T,value) Sketch<T> name(value,#name,true);
00196 #define GET_SKETCH(name,T,space) Sketch<T> name(#name,space);
00197 
00198 template <class T>
00199 Sketch<T>::Sketch(const Sketch<T> &other)
00200   : SketchRoot(),
00201     width(other.width), height(other.height),
00202     data(other.data), pixels(other.pixels) 
00203 {
00204   if ( isValid() ) {
00205     ++data->refcount;
00206   /*
00207   std::cout << "Copying Sketch " << this << " '"
00208       << "'  <--  Sketch '" << other.data->name << "'"
00209       << " [" << data << "]"
00210       << " id=" << getId() << ",parent=" << getParentId()
00211       << ",refcount=" << data->refcount << std::endl;
00212   */
00213   }
00214 }
00215 
00216 // Shallow copy constructor: does not copy the underlying pixels.
00217 template <class T>
00218 Sketch<T>::Sketch(const Sketch<T> &other, const std::string &name, bool viewable)
00219   : SketchRoot(),
00220     width(other.width), height(other.height),
00221     data(other.data), pixels(other.pixels) 
00222 {
00223   if ( isValid() ) {
00224     ++data->refcount;
00225     data->setName(name);
00226     data->setViewable(viewable);
00227   }
00228 }
00229 
00230 
00231 // Destructor
00232 template <class T> Sketch<T>::~Sketch() {
00233   if ( isValid() ) {
00234   /*
00235   std::cout << "Deleting Sketch " << this << " '" << getName() << "'"
00236       << " [" << data << "]"
00237       << " id=" << getId() << ",parent=" << getParentId()
00238       << ",viewable=" << isViewable()
00239       << ",refcount=" << data->refcount;
00240   */
00241   if ( --data->refcount == 0 && ! data->viewable && data->refreshTag < data->space->getRefreshCounter() ) {
00242     data->clearPending = false;
00243   }
00244   /*
00245   std::cout << ",newrefcount=" << data->refcount << std::endl;
00246   */
00247   }
00248 }
00249 
00250 template <class T>
00251 void Sketch<T>::checkValid() const {
00252   if ( ! isValid() )
00253     std::cerr << "ERROR!  Attempt to dereference an invalid Sketch." << std::endl;
00254 }
00255 
00256 // Parallel indexed access via operator[]
00257 
00258 template <class T>
00259 const Sketch<T> Sketch<T>::operator[] (const Sketch<usint>& indirection) const
00260 {
00261   checkValid();
00262   Sketch<T> result(*(data->space), "shift("+(*this)->getName()+","+indirection->getName()+")");
00263   for (size_t i = 0; i < pixels->size(); i++) {
00264     (*result.pixels)[i] = (*pixels)[indirection[i]];
00265   }
00266   return result;
00267 }
00268 
00269 template <class T>
00270 Sketch<T>& Sketch<T>::setIndices(const SketchIndices& indices, const T& value) {
00271   checkValid();
00272   for (SketchIndices::CI it = indices.table.begin(); it != indices.table.end(); ++it)
00273     (*pixels)[*it] = value;
00274   return *this;
00275 }
00276 
00277 template <class T>
00278 void Sketch<T>::bind(const Sketch<T>& other)
00279 {
00280   if ( isValid() )
00281     --data->refcount;
00282   data = other.data;
00283   ++data->refcount;
00284   pixels = other.pixels;
00285   width = other.width;
00286   height = other.height;
00287 }
00288 
00289 template <class T>
00290 Sketch<T>& Sketch<T>::operator= (const Sketch<T>& other) {
00291   if ( isValid() )
00292     if ( other.isValid() )
00293       *pixels = *other.pixels;
00294     else {
00295       if ( --data->refcount == 0 && data->refreshTag < data->space->getRefreshCounter() ) {
00296   data->setViewable(false);
00297   data->clearPending = false;
00298       }
00299       pixels = NULL;
00300       data = NULL;
00301     }
00302   else
00303     if ( other.isValid() )
00304       bind(::visops::copy(other));
00305   return *this;
00306 }
00307 
00308 template <class T>
00309 Sketch<T>& Sketch<T>::operator= (const T& value) { 
00310   checkValid();
00311   *pixels = value; 
00312   return *this;
00313 }
00314 
00315 
00316 //================================================================
00317 
00318 //! non-member math operators
00319 //@{
00320 
00321 #define DEF_MATHOPS_H(_T1, _T2, _Result) \
00322   DEF_MATHOP_H( +, _T1, _T2, _Result ) \
00323   DEF_MATHOP_H( -, _T1, _T2, _Result ) \
00324   DEF_MATHOP_H( *, _T1, _T2, _Result ) \
00325   DEF_MATHOP_H( /, _T1, _T2, _Result )
00326 
00327 #define DEF_MATHOP_H(_Op, _T1, _T2, _Result) \
00328 Sketch<_Result> operator _Op (const Sketch<_T1> &lhs, const Sketch<_T2> &rhs); \
00329 Sketch<_Result> operator _Op (const Sketch<_T1> &lhs, const _T2 value);
00330 
00331 // DEF_MATHOPS_H(bool, bool, bool) disallowed because valarray<bool> doesn't provide arithmetic
00332 DEF_MATHOPS_H(bool, uchar, uchar)
00333 DEF_MATHOPS_H(bool, usint, usint)
00334 DEF_MATHOPS_H(bool, float, float)
00335 
00336 DEF_MATHOPS_H(uchar, bool, uchar)
00337 DEF_MATHOPS_H(uchar, uchar, uchar)
00338 DEF_MATHOPS_H(uchar, usint, usint)
00339 DEF_MATHOPS_H(uchar, float, float)
00340 
00341 DEF_MATHOPS_H(usint, bool, usint)
00342 DEF_MATHOPS_H(usint, uchar, usint)
00343 DEF_MATHOPS_H(usint, usint, usint)
00344 DEF_MATHOPS_H(usint, float, float)
00345 
00346 DEF_MATHOPS_H(float, bool, float)
00347 DEF_MATHOPS_H(float, uchar, float)
00348 DEF_MATHOPS_H(float, usint, float)
00349 DEF_MATHOPS_H(float, float, float)
00350 
00351 #undef DEF_MATHOPS_H
00352 #undef DEF_MATHOP_H
00353 
00354 #define DEF_MATHOPS_INT_H(_T1) \
00355   DEF_MATHOP_INT_H( +, _T1) \
00356   DEF_MATHOP_INT_H( -, _T1) \
00357   DEF_MATHOP_INT_H( *, _T1) \
00358   DEF_MATHOP_INT_H( /, _T1)
00359 
00360 #define DEF_MATHOP_INT_H(_Op, _T1) \
00361 Sketch<_T1> operator _Op (const Sketch<_T1>& lhs, const int value);
00362 
00363 //DEF_MATHOPS_INT_H(bool, uchar) disallowed because valarray won't mix types
00364 DEF_MATHOPS_INT_H(uchar)
00365 DEF_MATHOPS_INT_H(usint)
00366 DEF_MATHOPS_INT_H(float)
00367 
00368 #undef DEF_MATHOPS_INT_H
00369 #undef DEF_MATHOP_INT_H
00370 
00371 #define DEF_MATHBOOL_INT_H(_Op) \
00372 Sketch<uchar> operator _Op (const Sketch<bool>& lhs, const int value);
00373 
00374 DEF_MATHBOOL_INT_H( + )
00375 DEF_MATHBOOL_INT_H( - )
00376 DEF_MATHBOOL_INT_H( * )
00377 DEF_MATHBOOL_INT_H( / )
00378 
00379 #undef DEF_MATHBOOL_INT_H
00380 
00381 template <class T> Sketch<T>& Sketch<T>::operator+= (const Sketch<T>& other) { *pixels += *other.pixels; return *this; }
00382 template <class T> Sketch<T>& Sketch<T>::operator-= (const Sketch<T>& other) { *pixels -= *other.pixels; return *this; }
00383 template <class T> Sketch<T>& Sketch<T>::operator*= (const Sketch<T>& other) { *pixels *= *other.pixels; return *this; }
00384 template <class T> Sketch<T>& Sketch<T>::operator/= (const Sketch<T>& other) { *pixels /= *other.pixels; return *this; }
00385 
00386 template <class T> Sketch<T>& Sketch<T>::operator+= (const T value) {*pixels += (T)value; return *this; }
00387 template <class T> Sketch<T>& Sketch<T>::operator-= (const T value) {*pixels -= (T)value; return *this; }
00388 template <class T> Sketch<T>& Sketch<T>::operator*= (const T value) {*pixels *= (T)value; return *this; }
00389 template <class T> Sketch<T>& Sketch<T>::operator/= (const T value) {*pixels /= (T)value; return *this; }
00390 
00391 template <class T> Sketch<T>& Sketch<T>::operator+= (const int value) {*pixels += T(value); return *this; }
00392 template <class T> Sketch<T>& Sketch<T>::operator-= (const int value) {*pixels -= T(value); return *this; }
00393 template <class T> Sketch<T>& Sketch<T>::operator*= (const int value) {*pixels *= T(value); return *this; }
00394 template <class T> Sketch<T>& Sketch<T>::operator/= (const int value) {*pixels /= T(value); return *this; }
00395 
00396   //@}
00397 
00398 
00399   //! non-member logical operators
00400   //@{
00401 #define DEFINE_LOGICAL_OPERATOR(_Op)                       \
00402 template <class T>                     \
00403 Sketch<bool> operator _Op (const Sketch<T>& lhs, const Sketch<T>& rhs) {             \
00404   Sketch<bool> result(lhs->getName() + #_Op + rhs->getName(), lhs);                  \
00405     *(result.pixels) = *(lhs.pixels) _Op *(rhs.pixels);                  \
00406     return result;                                                                   \
00407 }                        \
00408 /* continued... */                     \
00409 template <class T>                     \
00410 Sketch<bool> operator _Op (const Sketch<T>& lhs, const T value) {        \
00411   Sketch<bool> result(lhs->getName() + #_Op "scalar", lhs);                          \
00412     *(result.pixels) = *(lhs.pixels) _Op value;              \
00413     return result;                     \
00414 }                        \
00415 /* continued... */                     \
00416 template <class T>                     \
00417 Sketch<bool> operator _Op (const Sketch<T>& lhs, const int value) {        \
00418   Sketch<bool> result(lhs->getName() + #_Op "scalar", lhs);                          \
00419     *(result.pixels) = *(lhs.pixels) _Op T(value);             \
00420     return result;                     \
00421 }
00422 
00423   DEFINE_LOGICAL_OPERATOR( == )
00424   DEFINE_LOGICAL_OPERATOR( != )
00425   DEFINE_LOGICAL_OPERATOR( <  )
00426   DEFINE_LOGICAL_OPERATOR( >  )
00427   DEFINE_LOGICAL_OPERATOR( <= )
00428   DEFINE_LOGICAL_OPERATOR( >= )
00429   DEFINE_LOGICAL_OPERATOR( & )
00430   DEFINE_LOGICAL_OPERATOR( | )
00431 #undef DEFINE_LOGICAL_OPERATOR
00432 //@}
00433 
00434 template <class T>
00435 Sketch<bool> Sketch<T>::operator! () const {
00436   Sketch<bool> result("operator!",*this);
00437   *(result.pixels) = !(*pixels);
00438   return result;
00439 }
00440 
00441 //! Logical assignment operators.
00442 //@{
00443 Sketch<bool>& operator&= (Sketch<bool>& arg1, Sketch<bool> const& arg2);
00444 Sketch<bool>& operator|= (Sketch<bool>& arg1, Sketch<bool> const& arg2);
00445 //@}
00446 
00447 template <class T>
00448 void Sketch<T>::printVals() const {
00449   std::cout << ((*this)->getName() +":") << std::endl;
00450   for (size_t i = 0; i < pixels->size(); i++) {
00451     if ((i % width) == 0)
00452       std::cout << std::endl;
00453     std::cout << (*pixels)[i] << ' ';
00454   }
00455   std::cout << std::endl;
00456 }
00457 
00458 // Type coercion
00459 
00460 template <class T>
00461 Sketch<T>::operator Sketch<bool>() const {
00462   Sketch<bool> converted("bool(" + (*this)->getName() + ")", *this);
00463   copyPixels(converted, *this);
00464   return converted;
00465 }
00466 
00467 template <class T>
00468 Sketch<T>::operator Sketch<uchar>() const {
00469   /*
00470   std::cout << "Converting " << this << " '" << getName() << "'"
00471       << " id=" << getId() << ",parent=" << getParentId() << ",refcount=" << data->refcount
00472       << " to Sketch<uchar>\n";
00473   */
00474   Sketch<uchar> converted("uchar("+(*this)->getName()+")", *this);
00475   copyPixels(converted, *this);
00476   return converted;
00477 }
00478 
00479 template <>
00480 Sketch<bool>::operator Sketch<uchar>() const;
00481 
00482 template <>
00483 Sketch<uchar>::operator Sketch<bool>() const;
00484 
00485 template <class T>
00486 Sketch<T>::operator Sketch<usint>() const {
00487   /*
00488   std::cout << "Converting " << this << " '" << getName() << "'"
00489       << " id=" << getId() << ",parent=" << getParentId() << ",refcount=" << data->refcount
00490       << " to Sketch<usint>\n";
00491   */
00492   Sketch<usint> converted("usint("+(*this)->getName()+")", *this);
00493   copyPixels(converted, *this);
00494   return converted;
00495 }
00496 
00497 template <class T>
00498 Sketch<T>::operator Sketch<float>() const {
00499   Sketch<float> converted("float("+(*this)->getName()+")", *this);
00500   copyPixels(converted, *this);
00501   return converted;
00502 }
00503 
00504 //! utility function used by type conversion operators
00505 template<class A, class B>
00506 void copyPixels(Sketch<A>& dest, const Sketch<B>& src)
00507 {
00508   std::valarray<A> &destpix = *dest.pixels;
00509   const std::valarray<B> &srcpix = *src.pixels;
00510   size_t length = src->getSpace().getNumPixels();
00511   for (size_t i = 0; i < length; i++) {
00512     destpix[i] = (A)(srcpix[i]);
00513   }
00514 }
00515 
00516 } // namespace
00517 
00518 /*! @file
00519  * @brief Templated class for an image-like Sketch
00520  * @author neilh (Creator)
00521  *
00522  * $Author: dst $
00523  * $Name: tekkotsu-3_0 $
00524  * $Revision: 1.20 $
00525  * $State: Exp $
00526  * $Date: 2006/08/11 03:16:57 $
00527  */
00528 
00529 #endif

DualCoding 3.0beta
Generated Wed Oct 4 00:01:54 2006 by Doxygen 1.4.7