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<usint>
00112   operator Sketch<usint>() const;
00113 
00114   //! operator for implicity or explicitly converting to Sketch<uint>
00115   operator Sketch<uint>() const;
00116 
00117   //! operator for implicity or explicitly converting to Sketch<float>
00118   operator Sketch<float>() const;
00119 
00120 };
00121 
00122 // ****************************************************************
00123 
00124 
00125 } // namespace
00126 
00127 #include "SketchData.h"
00128 #include "SketchIndices.h"
00129 #include "SketchSpace.h"
00130 
00131 namespace visops {
00132   template <class T> DualCoding::Sketch<T> copy(const DualCoding::Sketch<T>& other);
00133 }
00134 
00135 namespace DualCoding {
00136 
00137 // First constructor: requires a SketchSpace
00138 template <class T>
00139 Sketch<T>::Sketch(SketchSpace &_space, const std::string &_name)
00140   : SketchRoot(), width(_space.getWidth()), height(_space.getHeight()),
00141     data(_space.get_pool(*this).getFreeElement()),
00142     pixels(&data->pixels)
00143 {
00144   data->name = _name;
00145   data->id = getNewId();
00146   data->parentId = 0;
00147   data->viewable = false;
00148   data->colormap = segMap;
00149   ++data->refcount;
00150   (*pixels)[_space.dummy] = T();
00151   /*
00152   std::cout << "Creating new Sketch " << this << " '" << data->name << "'"
00153       << " [" << data << "]"
00154       << " id=" << getId() << ",parent=" << getParentId()
00155       << ",refcount=" << data->refcount << std::endl;
00156   */
00157 }
00158 
00159 // Second constructor: requires a parent sketch
00160 template <class T>
00161 Sketch<T>::Sketch(const std::string& _name, const SketchRoot& _parent)
00162   : SketchRoot(), width(), height(), data(NULL), pixels(NULL) {
00163   SketchSpace& space = _parent.rootGetSpace();
00164   width = space.getWidth();
00165   height = space.getHeight();
00166   data = space.get_pool(*this).getFreeElement();
00167   data->name = _name;
00168   data->id = getNewId();
00169   data->inheritFrom(*_parent.rootGetData());
00170   data->viewable = false;
00171   ++data->refcount;
00172   pixels = &data->pixels;
00173   (*pixels)[space.dummy] = T();
00174   /*
00175   std::cout << "Creating new Sketch " << this << " '" << data->name << "'"
00176       << " [" << data << "]"
00177       << " id=" << getId() << ",parent=" << getParentId()
00178       << ",refcount=" << data->refcount << std::endl;
00179   */
00180 }
00181 
00182 // Dummy constructor
00183 template <typename T>
00184 Sketch<T>::Sketch()
00185   : SketchRoot(), width(), height(), data(NULL), pixels(NULL) {}
00186 
00187 // Retrieve existing sketch
00188 template <typename T>
00189 Sketch<T>::Sketch(const std::string &name, SketchSpace &space)
00190   : SketchRoot(), width(space.getWidth()), height(space.getHeight()), 
00191    data(space.get_pool(*this).findSketchData(name)), 
00192    pixels(data != NULL ? &data->pixels : NULL) {
00193   if ( data != NULL )
00194    ++data->refcount;
00195 }
00196 
00197 #define NEW_SKETCH_N(name,T,value) DualCoding::Sketch<T> name(value,#name,false);
00198 #define NEW_SKETCH(name,T,value) DualCoding::Sketch<T> name(value,#name,true);
00199 #define GET_SKETCH(name,T,space) DualCoding::Sketch<T> name(#name,space);
00200 
00201 template <class T>
00202 Sketch<T>::Sketch(const Sketch<T> &other)
00203   : SketchRoot(),
00204     width(other.width), height(other.height),
00205     data(other.data), pixels(other.pixels) 
00206 {
00207   if ( isValid() ) {
00208     ++data->refcount;
00209   /*
00210   std::cout << "Copying Sketch " << this << " '"
00211       << "'  <--  Sketch '" << other.data->name << "'"
00212       << " [" << data << "]"
00213       << " id=" << getId() << ",parent=" << getParentId()
00214       << ",refcount=" << data->refcount << std::endl;
00215   */
00216   }
00217 }
00218 
00219 // Shallow copy constructor: does not copy the underlying pixels.
00220 template <class T>
00221 Sketch<T>::Sketch(const Sketch<T> &other, const std::string &name, bool viewable)
00222   : SketchRoot(),
00223     width(other.width), height(other.height),
00224     data(other.data), pixels(other.pixels) 
00225 {
00226   if ( isValid() ) {
00227     ++data->refcount;
00228     data->setName(name);
00229     if ( viewable )
00230       data->setViewable(viewable);
00231   }
00232 }
00233 
00234 
00235 // Destructor
00236 template <class T> Sketch<T>::~Sketch() {
00237   if ( isValid() ) {
00238   /*
00239   std::cout << "Deleting Sketch " << this << " '" << getName() << "'"
00240       << " [" << data << "]"
00241       << " id=" << getId() << ",parent=" << getParentId()
00242       << ",viewable=" << isViewable()
00243       << ",refcount=" << data->refcount << std::endl;
00244   */
00245     --data->refcount;
00246     if ( data->refcount == 0 && ! data->viewable && data->refreshTag < data->space->getRefreshCounter() ) {
00247       data->clearPending = false;
00248     }
00249   }
00250 }
00251 
00252 template <class T>
00253 void Sketch<T>::checkValid() const {
00254   if ( ! isValid() )
00255     std::cerr << "ERROR!  Attempt to dereference an invalid Sketch." << std::endl;
00256 }
00257 
00258 // Parallel indexed access via operator[]
00259 
00260 template <class T>
00261 const Sketch<T> Sketch<T>::operator[] (const Sketch<uint>& indirection) const
00262 {
00263   checkValid();
00264   Sketch<T> result(*(data->space), "shift("+(*this)->getName()+","+indirection->getName()+")");
00265   result->setParentId((*this)->getParentId());
00266   result->setColorMap((*this)->getColorMap());
00267   for (size_t i = 0; i < pixels->size(); i++) {
00268     (*result.pixels)[i] = (*pixels)[indirection[i]];
00269   }
00270   return result;
00271 }
00272 
00273 template <class T>
00274 Sketch<T>& Sketch<T>::setIndices(const SketchIndices& indices, const T& value) {
00275   checkValid();
00276   for (SketchIndices::CI it = indices.table.begin(); it != indices.table.end(); ++it)
00277     (*pixels)[*it] = value;
00278   return *this;
00279 }
00280 
00281 template <class T>
00282 void Sketch<T>::bind(const Sketch<T>& other)
00283 {
00284   if ( isValid() )
00285     --data->refcount;
00286   data = other.data;
00287   ++data->refcount;
00288   pixels = other.pixels;
00289   width = other.width;
00290   height = other.height;
00291 }
00292 
00293 template <class T>
00294 Sketch<T>& Sketch<T>::operator= (const Sketch<T>& other) {
00295   if ( isValid() )
00296     if ( other.isValid() ) {
00297       *pixels = *other.pixels;  // deep assignment copies the pixels
00298       data->parentId = other.data->parentId;
00299     } else {
00300       if ( --data->refcount == 0 && data->refreshTag < data->space->getRefreshCounter() ) {
00301   data->setViewable(false);
00302   data->clearPending = false;
00303       }
00304       pixels = NULL;
00305       data = NULL;
00306     }
00307   else
00308     if ( other.isValid() )
00309       bind(::visops::copy(other));
00310   return *this;
00311 }
00312 
00313 template <class T>
00314 Sketch<T>& Sketch<T>::operator= (const T& value) { 
00315   checkValid();
00316   *pixels = value; 
00317   return *this;
00318 }
00319 
00320 
00321 //================================================================
00322 
00323 //! non-member math operators
00324 //@{
00325 
00326 #define DEF_MATHOPS_H(_T1, _T2, _Result) \
00327   DEF_MATHOP_H( +, _T1, _T2, _Result ) \
00328   DEF_MATHOP_H( -, _T1, _T2, _Result ) \
00329   DEF_MATHOP_H( *, _T1, _T2, _Result ) \
00330   DEF_MATHOP_H( /, _T1, _T2, _Result )
00331 
00332 #define DEF_MATHOP_H(_Op, _T1, _T2, _Result) \
00333 Sketch<_Result> operator _Op (const Sketch<_T1> &lhs, const Sketch<_T2> &rhs); \
00334 Sketch<_Result> operator _Op (const Sketch<_T1> &lhs, const _T2 value);
00335 
00336 // DEF_MATHOPS_H(bool, bool, bool) disallowed because valarray<bool> doesn't provide arithmetic
00337 DEF_MATHOPS_H(bool, uchar, uchar)
00338 DEF_MATHOPS_H(bool, uint, uint)
00339 DEF_MATHOPS_H(bool, float, float)
00340 
00341 DEF_MATHOPS_H(uchar, bool, uchar)
00342 DEF_MATHOPS_H(uchar, uchar, uchar)
00343 DEF_MATHOPS_H(uchar, uint, uint)
00344 DEF_MATHOPS_H(uchar, float, float)
00345 
00346 DEF_MATHOPS_H(usint, bool, usint)
00347 DEF_MATHOPS_H(usint, uchar, usint)
00348 DEF_MATHOPS_H(usint, usint, usint)
00349 DEF_MATHOPS_H(usint, float, float)
00350 
00351 DEF_MATHOPS_H(uint, bool, uint)
00352 DEF_MATHOPS_H(uint, uchar, uint)
00353 DEF_MATHOPS_H(uint, uint, uint)
00354 DEF_MATHOPS_H(uint, float, float)
00355 
00356 DEF_MATHOPS_H(float, bool, float)
00357 DEF_MATHOPS_H(float, uchar, float)
00358 DEF_MATHOPS_H(float, uint, float)
00359 DEF_MATHOPS_H(float, float, float)
00360 
00361 #undef DEF_MATHOPS_H
00362 #undef DEF_MATHOP_H
00363 
00364 #define DEF_MATHOPS_INT_H(_T1) \
00365   DEF_MATHOP_INT_H( +, _T1) \
00366   DEF_MATHOP_INT_H( -, _T1) \
00367   DEF_MATHOP_INT_H( *, _T1) \
00368   DEF_MATHOP_INT_H( /, _T1)
00369 
00370 #define DEF_MATHOP_INT_H(_Op, _T1) \
00371 Sketch<_T1> operator _Op (const Sketch<_T1>& lhs, const int value);
00372 
00373 //DEF_MATHOPS_INT_H(bool, uchar) disallowed because valarray won't mix types
00374 DEF_MATHOPS_INT_H(uchar)
00375 DEF_MATHOPS_INT_H(usint)
00376 DEF_MATHOPS_INT_H(uint)
00377 DEF_MATHOPS_INT_H(float)
00378 
00379 #undef DEF_MATHOPS_INT_H
00380 #undef DEF_MATHOP_INT_H
00381 
00382 #define DEF_MATHBOOL_INT_H(_Op) \
00383 Sketch<uchar> operator _Op (const Sketch<bool>& lhs, const int value);
00384 
00385 DEF_MATHBOOL_INT_H( + )
00386 DEF_MATHBOOL_INT_H( - )
00387 DEF_MATHBOOL_INT_H( * )
00388 DEF_MATHBOOL_INT_H( / )
00389 
00390 #undef DEF_MATHBOOL_INT_H
00391 
00392 template <class T> Sketch<T>& Sketch<T>::operator+= (const Sketch<T>& other) { *pixels += *other.pixels; return *this; }
00393 template <class T> Sketch<T>& Sketch<T>::operator-= (const Sketch<T>& other) { *pixels -= *other.pixels; return *this; }
00394 template <class T> Sketch<T>& Sketch<T>::operator*= (const Sketch<T>& other) { *pixels *= *other.pixels; return *this; }
00395 template <class T> Sketch<T>& Sketch<T>::operator/= (const Sketch<T>& other) { *pixels /= *other.pixels; return *this; }
00396 
00397 template <class T> Sketch<T>& Sketch<T>::operator+= (const T value) {*pixels += (T)value; return *this; }
00398 template <class T> Sketch<T>& Sketch<T>::operator-= (const T value) {*pixels -= (T)value; return *this; }
00399 template <class T> Sketch<T>& Sketch<T>::operator*= (const T value) {*pixels *= (T)value; return *this; }
00400 template <class T> Sketch<T>& Sketch<T>::operator/= (const T value) {*pixels /= (T)value; return *this; }
00401 
00402 template <class T> Sketch<T>& Sketch<T>::operator+= (const int value) {*pixels += T(value); return *this; }
00403 template <class T> Sketch<T>& Sketch<T>::operator-= (const int value) {*pixels -= T(value); return *this; }
00404 template <class T> Sketch<T>& Sketch<T>::operator*= (const int value) {*pixels *= T(value); return *this; }
00405 template <class T> Sketch<T>& Sketch<T>::operator/= (const int value) {*pixels /= T(value); return *this; }
00406 
00407   //@}
00408 
00409 
00410   //! non-member logical operators
00411   //@{
00412 #define DEFINE_LOGICAL_OPERATOR(_Op)                       \
00413 template <class T>                     \
00414 Sketch<bool> operator _Op (const Sketch<T>& lhs, const Sketch<T>& rhs) {             \
00415   Sketch<bool> result(lhs->getName() + #_Op + rhs->getName(), lhs);                  \
00416     *(result.pixels) = *(lhs.pixels) _Op *(rhs.pixels);                  \
00417     return result;                                                                   \
00418 }                        \
00419 /* continued... */                     \
00420 template <class T>                     \
00421 Sketch<bool> operator _Op (const Sketch<T>& lhs, const T value) {        \
00422   Sketch<bool> result(lhs->getName() + #_Op "scalar", lhs);                          \
00423     *(result.pixels) = *(lhs.pixels) _Op value;              \
00424     return result;                     \
00425 }                        \
00426 /* continued... */                     \
00427 template <class T>                     \
00428 Sketch<bool> operator _Op (const Sketch<T>& lhs, const int value) {        \
00429   Sketch<bool> result(lhs->getName() + #_Op "scalar", lhs);                          \
00430     *(result.pixels) = *(lhs.pixels) _Op T(value);             \
00431     return result;                     \
00432 }
00433 
00434   DEFINE_LOGICAL_OPERATOR( == )
00435   DEFINE_LOGICAL_OPERATOR( != )
00436   DEFINE_LOGICAL_OPERATOR( <  )
00437   DEFINE_LOGICAL_OPERATOR( >  )
00438   DEFINE_LOGICAL_OPERATOR( <= )
00439   DEFINE_LOGICAL_OPERATOR( >= )
00440   DEFINE_LOGICAL_OPERATOR( & )
00441   DEFINE_LOGICAL_OPERATOR( | )
00442   DEFINE_LOGICAL_OPERATOR( ^ )
00443 #undef DEFINE_LOGICAL_OPERATOR
00444 //@}
00445 
00446 template <class T>
00447 Sketch<bool> Sketch<T>::operator! () const {
00448   Sketch<bool> result("operator!",*this);
00449   *(result.pixels) = !(*pixels);
00450   return result;
00451 }
00452 
00453 //! Logical assignment operators.
00454 //@{
00455 Sketch<bool>& operator&= (Sketch<bool>& arg1, Sketch<bool> const& arg2);
00456 Sketch<bool>& operator|= (Sketch<bool>& arg1, Sketch<bool> const& arg2);
00457 Sketch<bool>& operator^= (Sketch<bool>& arg1, Sketch<bool> const& arg2);
00458 //@}
00459 
00460 template <class T>
00461 void Sketch<T>::printVals() const {
00462   std::cout << ((*this)->getName() +":") << std::endl;
00463   for (size_t i = 0; i < pixels->size(); i++) {
00464     if ((i % width) == 0)
00465       std::cout << std::endl;
00466     std::cout << (*pixels)[i] << ' ';
00467   }
00468   std::cout << std::endl;
00469 }
00470 
00471 // Type coercion
00472 
00473 template <class T>
00474 Sketch<T>::operator Sketch<bool>() const {
00475   Sketch<bool> converted("bool(" + (*this)->getName() + ")", *this);
00476   copyPixels(converted, *this);
00477   return converted;
00478 }
00479 
00480 template <class T>
00481 Sketch<T>::operator Sketch<uchar>() const {
00482   /*
00483   std::cout << "Converting " << this << " '" << getName() << "'"
00484       << " id=" << getId() << ",parent=" << getParentId() << ",refcount=" << data->refcount
00485       << " to Sketch<uchar>\n";
00486   */
00487   Sketch<uchar> converted("uchar("+(*this)->getName()+")", *this);
00488   copyPixels(converted, *this);
00489   return converted;
00490 }
00491 
00492 template <>
00493 Sketch<bool>::operator Sketch<uchar>() const;
00494 
00495 template <>
00496 Sketch<uchar>::operator Sketch<bool>() const;
00497 
00498 template <class T>
00499 Sketch<T>::operator Sketch<usint>() const {
00500   Sketch<usint> converted("usint("+(*this)->getName()+")", *this);
00501   copyPixels(converted, *this);
00502   return converted;
00503 }
00504 
00505 template <class T>
00506 Sketch<T>::operator Sketch<uint>() const {
00507   Sketch<uint> converted("uint("+(*this)->getName()+")", *this);
00508   copyPixels(converted, *this);
00509   return converted;
00510 }
00511 
00512 template <class T>
00513 Sketch<T>::operator Sketch<float>() const {
00514   Sketch<float> converted("float("+(*this)->getName()+")", *this);
00515   copyPixels(converted, *this);
00516   return converted;
00517 }
00518 
00519 //! utility function used by type conversion operators
00520 template<class A, class B>
00521 void copyPixels(Sketch<A>& dest, const Sketch<B>& src)
00522 {
00523   std::valarray<A> &destpix = *dest.pixels;
00524   const std::valarray<B> &srcpix = *src.pixels;
00525   size_t length = src->getSpace().getNumPixels();
00526   for (size_t i = 0; i < length; i++) {
00527     destpix[i] = (A)(srcpix[i]);
00528   }
00529 }
00530 
00531 } // namespace
00532 
00533 /*! @file
00534  * @brief Templated class for an image-like Sketch
00535  * @author neilh (Creator)
00536  */
00537 
00538 #endif

DualCoding 5.1CVS
Generated Mon May 9 04:56:27 2016 by Doxygen 1.6.3