Homepage | Demos | Overview | Downloads | Tutorials | Reference | Credits |
00001 //-*-c++-*- 00002 #ifndef INCLUDED_FilterBankGenerator_h_ 00003 #define INCLUDED_FilterBankGenerator_h_ 00004 00005 #include "Events/EventGeneratorBase.h" 00006 #include "Shared/LoadSave.h" 00007 00008 //! Abstract base class for generators of FilterBankEvents 00009 /*! This is needed to provide an interface for the FilterBankEvent to 00010 * call back when the actual image data is requested from it. This 00011 * facilitates lazy calculation of image data... no sense in 00012 * processing layers or channels which aren't actually going to be 00013 * used... 00014 * 00015 * Also this way we save on allocating/deallocating large memory 00016 * blocks on each event... the buffers allocated here can be reused 00017 * frame to frame. 00018 * 00019 * Larger layer indicies generally indicate higher resolution images 00020 * in a scaling pyramid, but you are free to store your own data 00021 * however you wish. 00022 * 00023 * For serializing, FilterBankGenerators inherit from the LoadSave 00024 * interface. Only one image (selected with setLoadSaveImage()) of 00025 * the bank will loaded or saved at a time. The default LoadSave 00026 * will store some header information for you: 00027 * 00028 * - Creator code: string ("\008FBkImage\0") 00029 * - Width: unsigned int 00030 * - Height: unsigned int 00031 * - Layer: unsigned int 00032 * - Channel: unsigned int 00033 * 00034 * However, you will need to override the LoadSave functions (listed 00035 * below) to provide your own code for interpreting the image data 00036 * itself. You may also want to add a few extra functions to allow 00037 * users to set compression/data format parameters. 00038 * 00039 * If you're doing fancy memory stuff, you probably want to override 00040 * the freeCaches() and destruct() functions so that the default 00041 * implementation won't try to free something it shouldn't. Don't 00042 * forget to call them from your own destructor though, otherwise 00043 * your versions won't get called before the default implementation's 00044 * does. 00045 * 00046 * @see RawCameraGenerator 00047 */ 00048 class FilterBankGenerator : public EventGeneratorBase, public LoadSave { 00049 public: 00050 //! constructor, calls setNumImages(1,1) 00051 FilterBankGenerator() 00052 : EventGeneratorBase(), numLayers(0), numChannels(0), widths(NULL), heights(NULL), skips(NULL), strides(NULL), increments(NULL), images(NULL), imageValids(NULL), selectedSaveLayer(0), selectedSaveChannel(0), frameNumber(0), framesProcessed(0) 00053 { 00054 setNumImages(1,1); 00055 } 00056 00057 //! constructor 00058 FilterBankGenerator(unsigned int layers, unsigned int channels) 00059 : EventGeneratorBase(), numLayers(0), numChannels(0), widths(NULL), heights(NULL), skips(NULL), strides(NULL), increments(NULL), images(NULL), imageValids(NULL), selectedSaveLayer(0), selectedSaveChannel(0), frameNumber(0), framesProcessed(0) 00060 { 00061 setNumImages(layers,channels); 00062 } 00063 00064 //! constructor 00065 FilterBankGenerator(const std::string& name,unsigned int layers, unsigned int channels, EventBase::EventGeneratorID_t srcgid, unsigned int srcsid, EventBase::EventGeneratorID_t mgid, unsigned int msid) 00066 : EventGeneratorBase(name,mgid,msid,srcgid,srcsid), numLayers(0), numChannels(0), widths(NULL), heights(NULL), skips(NULL), strides(NULL), increments(NULL), images(NULL), imageValids(NULL), selectedSaveLayer(0), selectedSaveChannel(0), frameNumber(0), framesProcessed(0) 00067 { 00068 setNumImages(layers,channels); 00069 } 00070 00071 //! destructor 00072 ~FilterBankGenerator() { 00073 freeCaches(); 00074 destruct(); 00075 } 00076 00077 //! returns the number of image layers (e.g. different resolutions available) 00078 virtual unsigned int getNumLayers() const { return numLayers; } 00079 00080 //! returns the number of channels per image (e.g. Y, U, or V components) 00081 virtual unsigned int getNumChannels() const { return numChannels; } 00082 00083 //! returns pointer to the beginning of the image data for the specified layer and channel 00084 /*! this will cause the data to be calculated and cached if it's not already available */ 00085 virtual unsigned char * getImage(unsigned int layer, unsigned int channel) const; 00086 00087 //! returns width (in samples) of the image in a given layer 00088 unsigned int getWidth(unsigned int layer) const { return widths[layer]; } 00089 00090 //! returns height (in samples) of the image in a given layer 00091 unsigned int getHeight(unsigned int layer) const { return heights[layer]; } 00092 00093 //! returns the bytes to skip from the one-past-end of a row to get the beginning of the next 00094 unsigned int getSkip(unsigned int layer) const { return skips[layer]; } 00095 00096 //! returns the bytes to skip from the beginning of one row to get the beginning of the next 00097 /*! This is just for convenience; the stride is just the skip plus the width, but it's precomputed for you for speed and clarity */ 00098 unsigned int getStride(unsigned int layer) const { return strides[layer]; } 00099 00100 //! returns the increment (in bytes) to use to go from one sample to the next 00101 unsigned int getIncrement(unsigned int layer) const { return increments[layer]; } 00102 00103 //! returns the frame number of the current frame, see #frameNumber 00104 unsigned int getFrameNumber() const { return frameNumber; } 00105 00106 //! returns the number of frames processed, see #framesProcessed 00107 unsigned int getFramesProcessed() const { return framesProcessed; } 00108 00109 //! deletes storage of cached images and marks it invalid 00110 /*! you should override this if the images cache pointer isn't actually an array of bytes... 00111 * Don't forget to call it in your subclass's destructor or your version won't get called... */ 00112 virtual void freeCaches(); 00113 00114 //! marks all of the cached images as invalid (but doesn't free their memory) 00115 /*! You probably want to call this right before you send the FilterBankEvent */ 00116 virtual void invalidateCaches(); 00117 00118 //! default implementation ignore events, just so you don't have to define it if you don't receive events 00119 virtual void processEvent(const EventBase & /*event*/) {} 00120 00121 //!@name LoadSave interface 00122 00123 virtual unsigned int getBinSize() const; 00124 00125 virtual unsigned int LoadBuffer(const char buf[], unsigned int len); 00126 00127 virtual unsigned int SaveBuffer(char buf[], unsigned int len) const; 00128 00129 //! not actually part of the LoadSave interface, but allows you to select which image of the bank will be saved 00130 /*! when loading, the saved image's layer and channel will reset this */ 00131 virtual void selectSaveImage(unsigned int layer, unsigned int channel) { selectedSaveLayer=layer; selectedSaveChannel=channel; } 00132 00133 virtual unsigned int getSelectedSaveLayer() const { return selectedSaveLayer; } //!< returns layer to be saved, or layer of last image loaded 00134 virtual unsigned int getSelectedSaveChannel() const { return selectedSaveChannel; } //!< returns channel to be saved, or channel of last image loaded 00135 00136 //@} 00137 00138 00139 protected: 00140 //! resizes the filter bank information storage area, you should override this to do your setup and call it from your constructor 00141 /*! In general, it isn't expected that FilterBankGenerator's should 00142 * necessarily be dynamically resizeable (although it would be 00143 * nice), which is why this isn't public. If yours is, just add 00144 * some pubic accessor functions which call this. In general, the 00145 * included subclasses should be able to handle being resized, but 00146 * there's no reason to do so since the system won't be changing 00147 * its available resolutions at run time. */ 00148 virtual void setNumImages(unsigned int nLayers, unsigned int nChannels); 00149 00150 //! create new image data storage area for the cache - this is only called when the corresponding entry in images is NULL 00151 /*! You should return the pointer you want stored in images to be 00152 * returned by any calls to getFirstRow. Interpretation of the 00153 * data it points to is dependant on the the generator which 00154 * creates it */ 00155 virtual unsigned char * createImageCache(unsigned int layer, unsigned int channel) const=0; 00156 00157 //! should calculate new image data, only called when imageValids indicates the image being requested is dirty 00158 /*! This is where you'll want to put your user-specific code for calculating the image data */ 00159 virtual void calcImage(unsigned int layer, unsigned int channel) const=0; 00160 00161 //! deletes the arrays 00162 virtual void destruct(); 00163 00164 unsigned int numLayers; //!< current number of layers available 00165 unsigned int numChannels; //!< current number of channels available 00166 00167 unsigned int * widths; //!< an array of size numLayers, width (in samples) in pixels of each layer 00168 unsigned int * heights; //!< an array of size numLayers, height (in samples) in pixels of each layer 00169 unsigned int * skips; //!< an array of size numLayers, skip (in bytes) from row end to next row begin 00170 unsigned int * strides; //!< an array of size numLayers, stride (in bytes) from a given column in one row to the same column in the next row 00171 unsigned int * increments;//!< an array of size numLayers, increment (in bytes) to use to get from one sample to the next 00172 00173 mutable unsigned char *** images; //!< an array [numLayers][numChannels], stores pointer to cached image data 00174 mutable bool ** imageValids; //!< an array [numLayers][numChannels], entry is true if cached data is still valid 00175 00176 unsigned int selectedSaveLayer; //!< layer to be manipulated with the LoadSave functions 00177 unsigned int selectedSaveChannel; //!< channel to be manipulated with the LoadSave functions 00178 00179 //! the current frame number - subclasses will need to set to the source's frameNumber when they receive a new frame (probably from processEvent()) 00180 /*! The idea is to use this as a unique serial number for each 00181 * frame. That way you can know if the current image in different 00182 * generators is actually the same camera image before you try to 00183 * compare or combine them. 00184 * 00185 * You could also figure out the number of dropped frames by 00186 * subtracting framesProcessed from this value. Give some leeway 00187 * however, because it takes the first 40-70 frames just to boot 00188 * up, so there's no way they can be processed. 00189 */ 00190 unsigned int frameNumber; 00191 unsigned int framesProcessed; //!< subclasses should increment this any time they make a new filter bank available (probably by throwing an event) 00192 00193 private: 00194 FilterBankGenerator(const FilterBankGenerator& fbk); //!< don't call 00195 const FilterBankGenerator& operator=(const FilterBankGenerator& fbk); //!< don't call 00196 }; 00197 00198 /*! @file 00199 * @brief Describes abstract base class for generators of FilterBankEvents 00200 * @author ejt (Creator) 00201 * 00202 * $Author: ejt $ 00203 * $Name: tekkotsu-2_0 $ 00204 * $Revision: 1.9 $ 00205 * $State: Exp $ 00206 * $Date: 2004/01/08 02:22:34 $ 00207 */ 00208 00209 #endif
Tekkotsu v2.0 |
Generated Wed Jan 21 03:20:28 2004 by Doxygen 1.3.4 |