Tekkotsu Homepage
Demos
Overview
Downloads
Dev. Resources
Reference
Credits

SketchData.h

Go to the documentation of this file.
00001 //-*-c++-*-
00002 
00003 #ifndef INCLUDED_SketchData_h
00004 #define INCLUDED_SketchData_h
00005 
00006 #include <valarray>
00007 #include <iostream>
00008 #include <stdexcept>
00009 #include <limits> // needed for findMinPlus
00010 #include <map>
00011 
00012 #include "Shared/debuget.h" // needed for ASSERT macros
00013 
00014 #include "SketchTypes.h"
00015 #include "SketchDataRoot.h"
00016 #include "SketchSpace.h"
00017 
00018 namespace DualCoding {
00019 
00020 class SketchSpace;
00021 template<typename T> class SketchPool;
00022 template<typename T> class Sketch;
00023 
00024 //! Holds the pixels for an individual sketch.
00025 
00026 /*! SketchData<T> holds the pixels for an individual sketch of type T, using a valarray<T>.  A collection of
00027     SketchData<T> objects is maintained in a SketchPool<T>.  Basic functions such as indexed access and empty test
00028     that are not implemented as Sketch operators are implemented as SketchData<T> member functions.  Sketch<T>
00029     overrides the -> operator to provide "smart pointer" access to these SketchData<T> functions.   */
00030 
00031 template<class T>
00032 class SketchData : public SketchDataRoot {
00033   //! the valarray which actually stores the image
00034   std::valarray<T> pixels;
00035 
00036   friend class Sketch<T>;
00037   friend class SketchPool<T>;
00038 
00039 public:
00040   //! Constructor.  Don't call this.  SketchData objects should only be created and managed by their SketchSpace
00041   SketchData(SketchSpace *_space);
00042   ~SketchData();
00043 
00044   //! The type of this sketch.
00045   virtual SketchType_t getType() const;  // must go here, not in SketchDataRoot, due to templating
00046 
00047   //! Address of the memory area containing the actual pixel data.
00048   T* getRawPixels() { return &(pixels[0]); }
00049 
00050   //! Address of the memory area containing the actual pixel data.
00051   const T* getRawPixels() const { return &(pixels[0]); }
00052 
00053   //@{
00054   //! Indexed access, with bounds checking
00055   T& at(size_t x);
00056 
00057   //! Subscripted (x,y) access, with bounds checking
00058   T& at(size_t x, size_t y);
00059 
00060   T& operator[] (size_t idx) { return pixels[idx]; };
00061   const T& operator[] (size_t idx) const { return pixels[idx]; };
00062   
00063   T& operator() (size_t x, size_t y) { return pixels[y*space->getWidth() + x]; };
00064   const T& operator() (size_t x, size_t y) const { return pixels[y*space->getWidth() + x]; };
00065   
00066   //@}
00067 
00068   //! Returns true if all pixels are zero.
00069   bool empty() const;
00070 
00071   //!@name Sum/Max/Min
00072   //@{
00073 
00074   //! Sum of pixels
00075   T sum() const;
00076 
00077   //! Max of pixel values
00078   T max() const;
00079 
00080   //! Index of first maximum-value pixel
00081   int findMax() const;
00082 
00083   //! Min of pixel values
00084   T min() const;
00085 
00086   //! Index of first minimum-value pixel
00087   int findMin() const;
00088 
00089   //! Min of non-zero pixel values
00090   T minPlus() const;
00091 
00092   //! Index of first minimum non-zero pixel, or -1 if none
00093   int findMinPlus() const;
00094 
00095   //! Index of first non-zero pixel, or -1 if none
00096   int findTrue() const;
00097 
00098   //! Mode (most common) pixel value
00099   T mode() const;
00100 
00101   //! Mode (most common) non-zero pixel value
00102   T modePlus() const;
00103 
00104   //@}
00105 
00106   virtual size_t savePixels(char buf[], size_t avail) const; //!< handle copying pixels to buffer
00107 
00108 private:
00109   SketchData (const SketchData& other); //!< never call this
00110 };
00111 
00112 template<class T>
00113 SketchData<T>::SketchData(SketchSpace *_space) :
00114   SketchDataRoot(_space), pixels(_space->getNumPixels()+1) {
00115   if  ( getType() == sketchUsint || getType() == sketchUint || getType() == sketchFloat )
00116     colormap = jetMapScaled;
00117   else
00118     colormap = segMap;
00119 }
00120 
00121 template<class T> SketchData<T>::~SketchData() {}
00122 
00123 template <class T>
00124 SketchData<T>::SketchData (const SketchData<T> &other)
00125   : SketchDataRoot(other.space), pixels(other.pixels) {}
00126 
00127 template<>
00128 inline SketchType_t SketchData<bool>:: getType() const { return sketchBool; }
00129 template<>
00130 inline SketchType_t SketchData<unsigned char>::getType() const { return sketchUchar; }
00131 template<>
00132 inline SketchType_t SketchData<unsigned short int>::getType() const { return sketchUsint; }
00133 template<>
00134 inline SketchType_t SketchData<unsigned int>::getType() const { return sketchUint; }
00135 template<>
00136 inline SketchType_t SketchData<float>::getType() const { return sketchFloat; }
00137 template<>
00138 inline SketchType_t SketchData<yuv>::getType() const { return sketchYUV; }
00139 
00140 template<class T>
00141 T& SketchData<T>::at(size_t x) {
00142   if ( x < space->getWidth()*space->getHeight() )
00143     return pixels[x];
00144   else
00145     throw std::out_of_range("Sketch subscript out of bounds");
00146 }
00147 
00148 template <class T>
00149 T& SketchData<T>::at(size_t x, size_t y) {
00150   if ( x < space->getWidth() && y < space->getHeight() )
00151     return pixels[y*space->getWidth()+x];
00152   else
00153     throw std::out_of_range("Sketch subscript out of bounds");
00154 }
00155 
00156 template <class T>
00157 bool SketchData<T>::empty() const {
00158   for ( size_t i=0; i < pixels.size(); i++ )
00159     if ( pixels[i] != 0 )
00160       return false;
00161   return true;
00162 }
00163 
00164 template <class T>
00165 T SketchData<T>::sum() const {
00166   return pixels.sum();
00167 }
00168 
00169 template <class T>
00170 T SketchData<T>::max() const {
00171   return pixels.max();
00172 }
00173 
00174 template <class T>
00175 int SketchData<T>::findMax() const {
00176   T maxval = pixels[0];
00177   int maxidx = -1;
00178   const unsigned int length = pixels.size();
00179   for (unsigned int i = 1; i<length; i++)
00180     if ( pixels[i] > maxval ) {
00181       maxidx = i;
00182       maxval = pixels[i];
00183     }
00184   return maxidx;
00185 }
00186 
00187 template <class T>
00188 T SketchData<T>::min() const {
00189   return pixels.min();
00190 }
00191 
00192 template <class T>
00193 int SketchData<T>::findMin() const {
00194   T minval = pixels[0];
00195   int minidx = 0;
00196   const unsigned int length = pixels.size();
00197   for (unsigned int i = 1; i<length; i++)
00198     if ( pixels[i] < minval ) {
00199       minidx = i;
00200       minval = pixels[minidx];
00201     }
00202   return minidx;
00203 }
00204 
00205 template <class T>
00206 T SketchData<T>::minPlus() const {
00207   T result = 0;
00208   unsigned int i = 0;
00209   const unsigned int length = pixels.size();
00210   // find first positive value
00211   for (; i<length; i++)
00212     if ( pixels[i] > 0 ) {
00213       result = pixels[i];
00214       break;
00215     }
00216   // now check for values less than this
00217   for (; i<length; i++)
00218     if ( pixels[i] > 0 )
00219       if ( result < pixels[i] )
00220   result = pixels[i];
00221   return result;
00222 }
00223 
00224 template <class T>
00225 int SketchData<T>::findMinPlus() const {
00226   T minval=std::numeric_limits<T>::max();
00227   int minidx = -1;
00228   const unsigned int length = pixels.size();
00229   // count backwards so we return the earliest value even if it's std::numeric_limits<T>::max();
00230   for (unsigned int i=length; i!=0; ) {
00231     --i;
00232     if ( pixels[i] != 0 && pixels[i] <= minval ) {
00233       minidx = i;
00234       minval = pixels[i];
00235     }
00236   }
00237   return minidx;
00238 }
00239 
00240 template <class T>
00241 int SketchData<T>::findTrue() const {
00242   const unsigned int length = pixels.size();
00243   for (unsigned int i=0; i<length; i++)
00244     if ( pixels[i] != 0 )
00245       return i;
00246   return -1;
00247 }
00248 
00249 template <class T>
00250 T SketchData<T>::mode() const {
00251   std::map<T,size_t> hist;
00252   const T* p=&pixels[0], *end=&pixels[pixels.size()];
00253   while(p!=end)
00254     hist[*p++]++;
00255   T maxval=T();
00256   size_t maxcnt=0;
00257   for(typename std::map<T,size_t>::const_iterator it=hist.begin(); it!=hist.end(); ++it) {
00258     if(maxcnt<=it->second) {
00259       maxval=it->first;
00260       maxcnt=it->second;
00261     }
00262   }
00263   return maxval;
00264 }
00265 
00266 template <class T>
00267 T SketchData<T>::modePlus() const {
00268   std::map<T,size_t> hist;
00269   for(const T* p=&pixels[0], *end=&pixels[pixels.size()]; p!=end; ++p)
00270     if(*p!=0)
00271       hist[*p]++;
00272   T maxval=T();
00273   size_t maxcnt=0;
00274   for(typename std::map<T,size_t>::const_iterator it=hist.begin(); it!=hist.end(); ++it) {
00275     if(maxcnt<=it->second) {
00276       maxval=it->first;
00277       maxcnt=it->second;
00278     }
00279   }
00280   return maxval;
00281 }
00282 
00283 
00284 // ================================================================
00285 
00286 template <class T>
00287 size_t SketchData<T>::savePixels(char buf[], size_t avail) const
00288 {
00289   const size_t imglength  = getWidth() * getHeight() * sizeof(T);
00290   ASSERTRETVAL(imglength<=avail,"Insufficient buffer space for image",0);
00291   memcpy(buf,(const unsigned char*)&(pixels[0]),imglength);
00292   return imglength;
00293 }
00294 
00295 template<>
00296 inline size_t SketchData<float>::savePixels(char buf[], size_t avail) const
00297 {
00298   const size_t imglength  = getWidth() * getHeight() * 4;
00299   ASSERTRETVAL(imglength<avail,"Insufficient buffer space for image",0);
00300   float temp;
00301   const char* tptr = (const char*)(&temp);
00302   char *bufptr = buf;
00303   const unsigned int np = getNumPixels();
00304   for(unsigned int i=0; i<np; i++) {
00305     //temp = std::min(int(fmax(0.f, pixels[i])), 0x7fffff);
00306     temp = pixels[i];
00307     *bufptr++ = tptr[0];
00308     *bufptr++ = tptr[1];
00309     *bufptr++ = tptr[2];
00310     *bufptr++ = tptr[3];
00311   }
00312   return imglength;
00313 }
00314 
00315 #ifdef __POWERPC__
00316 //bool can be 4 bytes on PowerPC systems
00317 template<>
00318 inline unsigned int SketchData<bool>::savePixels(char buf[], unsigned int avail) const
00319 {
00320   const unsigned int imglength  = getWidth() * getHeight() * sizeof(char);
00321   ASSERTRETVAL(imglength<avail,"Insufficient buffer space for image",0);
00322   if(sizeof(bool)==sizeof(char))
00323     memcpy(buf,(const unsigned char*)&(pixels[0]),imglength);
00324   else
00325     for(unsigned int i=0; i<imglength; ++i)
00326       buf[i]=pixels[i]; //do manual copy to ensure one byte per pixel
00327   return imglength;
00328 }
00329 #endif
00330 
00331 } // namespace
00332 
00333 /*! @file
00334  * @brief A resource which holds the image date for a Sketch, managed collectively by a SketchSpace
00335  * @author neilh (Creator)
00336  */
00337 
00338 #endif

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