Tekkotsu Homepage
Demos
Overview
Downloads
Dev. Resources
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<uint>& 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<uint>
00112   operator Sketch<uint>() 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).getFreeElement()),
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).getFreeElement();
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     if ( viewable )
00227       data->setViewable(viewable);
00228   }
00229 }
00230 
00231 
00232 // Destructor
00233 template <class T> Sketch<T>::~Sketch() {
00234   if ( isValid() ) {
00235   /*
00236   std::cout << "Deleting Sketch " << this << " '" << getName() << "'"
00237       << " [" << data << "]"
00238       << " id=" << getId() << ",parent=" << getParentId()
00239       << ",viewable=" << isViewable()
00240       << ",refcount=" << data->refcount << std::endl;
00241   */
00242     --data->refcount;
00243     if ( data->refcount == 0 && ! data->viewable && data->refreshTag < data->space->getRefreshCounter() ) {
00244       data->clearPending = false;
00245     }
00246   }
00247 }
00248 
00249 template <class T>
00250 void Sketch<T>::checkValid() const {
00251   if ( ! isValid() )
00252     std::cerr << "ERROR!  Attempt to dereference an invalid Sketch." << std::endl;
00253 }
00254 
00255 // Parallel indexed access via operator[]
00256 
00257 template <class T>
00258 const Sketch<T> Sketch<T>::operator[] (const Sketch<uint>& indirection) const
00259 {
00260   checkValid();
00261   Sketch<T> result(*(data->space), "shift("+(*this)->getName()+","+indirection->getName()+")");
00262   for (size_t i = 0; i < pixels->size(); i++) {
00263     (*result.pixels)[i] = (*pixels)[indirection[i]];
00264   }
00265   return result;
00266 }
00267 
00268 template <class T>
00269 Sketch<T>& Sketch<T>::setIndices(const SketchIndices& indices, const T& value) {
00270   checkValid();
00271   for (SketchIndices::CI it = indices.table.begin(); it != indices.table.end(); ++it)
00272     (*pixels)[*it] = value;
00273   return *this;
00274 }
00275 
00276 template <class T>
00277 void Sketch<T>::bind(const Sketch<T>& other)
00278 {
00279   if ( isValid() )
00280     --data->refcount;
00281   data = other.data;
00282   ++data->refcount;
00283   pixels = other.pixels;
00284   width = other.width;
00285   height = other.height;
00286 }
00287 
00288 template <class T>
00289 Sketch<T>& Sketch<T>::operator= (const Sketch<T>& other) {
00290   if ( isValid() )
00291     if ( other.isValid() ) {
00292       *pixels = *other.pixels;  // deep assignment copies the pixels
00293       data->parentId = other.data->parentId;
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, uint, uint)
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, uint, uint)
00339 DEF_MATHOPS_H(uchar, float, float)
00340 
00341 DEF_MATHOPS_H(uint, bool, uint)
00342 DEF_MATHOPS_H(uint, uchar, uint)
00343 DEF_MATHOPS_H(uint, uint, uint)
00344 DEF_MATHOPS_H(uint, float, float)
00345 
00346 DEF_MATHOPS_H(float, bool, float)
00347 DEF_MATHOPS_H(float, uchar, float)
00348 DEF_MATHOPS_H(float, uint, 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(uint)
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   DEFINE_LOGICAL_OPERATOR( ^ )
00432 #undef DEFINE_LOGICAL_OPERATOR
00433 //@}
00434 
00435 template <class T>
00436 Sketch<bool> Sketch<T>::operator! () const {
00437   Sketch<bool> result("operator!",*this);
00438   *(result.pixels) = !(*pixels);
00439   return result;
00440 }
00441 
00442 //! Logical assignment operators.
00443 //@{
00444 Sketch<bool>& operator&= (Sketch<bool>& arg1, Sketch<bool> const& arg2);
00445 Sketch<bool>& operator|= (Sketch<bool>& arg1, Sketch<bool> const& arg2);
00446 Sketch<bool>& operator^= (Sketch<bool>& arg1, Sketch<bool> const& arg2);
00447 //@}
00448 
00449 template <class T>
00450 void Sketch<T>::printVals() const {
00451   std::cout << ((*this)->getName() +":") << std::endl;
00452   for (size_t i = 0; i < pixels->size(); i++) {
00453     if ((i % width) == 0)
00454       std::cout << std::endl;
00455     std::cout << (*pixels)[i] << ' ';
00456   }
00457   std::cout << std::endl;
00458 }
00459 
00460 // Type coercion
00461 
00462 template <class T>
00463 Sketch<T>::operator Sketch<bool>() const {
00464   Sketch<bool> converted("bool(" + (*this)->getName() + ")", *this);
00465   copyPixels(converted, *this);
00466   return converted;
00467 }
00468 
00469 template <class T>
00470 Sketch<T>::operator Sketch<uchar>() const {
00471   /*
00472   std::cout << "Converting " << this << " '" << getName() << "'"
00473       << " id=" << getId() << ",parent=" << getParentId() << ",refcount=" << data->refcount
00474       << " to Sketch<uchar>\n";
00475   */
00476   Sketch<uchar> converted("uchar("+(*this)->getName()+")", *this);
00477   copyPixels(converted, *this);
00478   return converted;
00479 }
00480 
00481 template <>
00482 Sketch<bool>::operator Sketch<uchar>() const;
00483 
00484 template <>
00485 Sketch<uchar>::operator Sketch<bool>() const;
00486 
00487 template <class T>
00488 Sketch<T>::operator Sketch<uint>() const {
00489   /*
00490   std::cout << "Converting " << this << " '" << getName() << "'"
00491       << " id=" << getId() << ",parent=" << getParentId() << ",refcount=" << data->refcount
00492       << " to Sketch<uint>\n";
00493   */
00494   Sketch<uint> converted("uint("+(*this)->getName()+")", *this);
00495   copyPixels(converted, *this);
00496   return converted;
00497 }
00498 
00499 template <class T>
00500 Sketch<T>::operator Sketch<float>() const {
00501   Sketch<float> converted("float("+(*this)->getName()+")", *this);
00502   copyPixels(converted, *this);
00503   return converted;
00504 }
00505 
00506 //! utility function used by type conversion operators
00507 template<class A, class B>
00508 void copyPixels(Sketch<A>& dest, const Sketch<B>& src)
00509 {
00510   std::valarray<A> &destpix = *dest.pixels;
00511   const std::valarray<B> &srcpix = *src.pixels;
00512   size_t length = src->getSpace().getNumPixels();
00513   for (size_t i = 0; i < length; i++) {
00514     destpix[i] = (A)(srcpix[i]);
00515   }
00516 }
00517 
00518 } // namespace
00519 
00520 /*! @file
00521  * @brief Templated class for an image-like Sketch
00522  * @author neilh (Creator)
00523  *
00524  * $Author: dst $
00525  * $Name: tekkotsu-4_0 $
00526  * $Revision: 1.23 $
00527  * $State: Exp $
00528  * $Date: 2007/08/25 01:49:15 $
00529  */
00530 
00531 #endif

DualCoding 4.0
Generated Thu Nov 22 00:52:36 2007 by Doxygen 1.5.4