Homepage Demos Overview Downloads Tutorials Reference
Credits

CDTGenerator.cc

Go to the documentation of this file.
00001 #include "CDTGenerator.h"
00002 #include "Events/DataEvent.h"
00003 #include "Events/EventRouter.h"
00004 #include "Events/SegmentedColorFilterBankEvent.h"
00005 #include "Wireless/Wireless.h"
00006 #include "Shared/Config.h"
00007 #include "Shared/WorldState.h"
00008 
00009 #include <OPENR/ODataFormats.h>
00010 #include <OPENR/OFbkImage.h>
00011 
00012 #include "Shared/debuget.h"
00013 
00014 CDTGenerator::CDTGenerator(unsigned int numRawLayers, unsigned int numCalcLayers, EventBase::EventGeneratorID_t gid, unsigned int sid, unsigned int mysid)
00015   : FilterBankGenerator("CDTGenerator",numCalcLayers,NUM_CHANNELS,gid,sid,EventBase::visSegmentEGID,mysid), numRealLayers(numRawLayers), layers(NULL), imageInfos(NULL)
00016 {
00017   setNumImages(numLayers,numChannels);
00018 }
00019 
00020 CDTGenerator::~CDTGenerator() {
00021   freeCaches();
00022   destruct();
00023 }
00024 
00025 /*! The const casts in this function are regretable but necessary
00026  *  since the OPEN-R OFbkImage constructor requires mutable
00027  *  arguments, even though it shouldn't be modifying the data
00028  */
00029 void
00030 CDTGenerator::processEvent(const EventBase& event) {
00031   typedef DataEvent<const OFbkImageVectorData*> OFbkEvent;
00032   const OFbkEvent& fbkevent=dynamic_cast<const OFbkEvent& >(event);
00033   OFbkImageVectorData& fbkdat=*const_cast<OFbkImageVectorData*>(fbkevent.getData());
00034   for(unsigned int res=0; res<numRealLayers; res++) {
00035     layers[numLayers-1-res] = fbkdat.GetData(res);
00036     imageInfos[numLayers-1-res] = fbkdat.GetInfo(res);
00037   }
00038   {
00039     const OFbkImage img(const_cast<OFbkImageInfo*>(imageInfos[numLayers-2]), const_cast<unsigned char*>(layers[numLayers-2]), ofbkimageBAND_CDT);
00040     //I have to do this crazy thing because apparently img.FieldCounter() doesn't work
00041     frameNumber=*(int*)(img.Pointer()+(img.Height()-1)*(img.Skip()+img.Width()));
00042   }
00043   unsigned int numNotRealLayers=numLayers-numRealLayers;
00044   for(unsigned int res=numNotRealLayers; res<numLayers; res++) {
00045     widths[res] = imageInfos[res]->width;
00046     heights[res] = imageInfos[res]->height;
00047 
00048     const OFbkImage img(const_cast<OFbkImageInfo*>(imageInfos[res]), const_cast<unsigned char*>(layers[res]), ofbkimageBAND_CDT);
00049     skips[res]=img.Skip();
00050     strides[res]=skips[res]+widths[res];
00051 
00052     ASSERT(static_cast<unsigned int>(img.Width())==getWidth(res),"Widths don't match");
00053     ASSERT(static_cast<unsigned int>(img.Height())==getHeight(res),"Heights don't match");
00054   }
00055   if(numNotRealLayers>0) {
00056     if(widths[numNotRealLayers-1]*2!=widths[numNotRealLayers] || heights[numNotRealLayers]*2!=heights[numNotRealLayers]) {
00057       //|| widths[numLayers-2-numRealLayers]*2!=widths[numNotRealLayers]
00058       //|| heights[numLayers-2-numRealLayers]*2!=heights[numNotRealLayers]) {
00059       //set the width and height of non-real layers (since they don't match what they should be)
00060       ASSERT(widths[numLayers-1]==0,"Strange, the image width changed after initial setting" << widths[numLayers-1]);
00061       setDimensions();
00062     }
00063   }
00064 
00065   invalidateCaches();
00066   framesProcessed++;
00067   // todo - i wish we had some color infomation to pass here so we could use the event for CMVision's RLE, etc.
00068   erouter->postEvent(new SegmentedColorFilterBankEvent(this,getGeneratorID(),getSourceID(),NULL,0,NULL,NULL));
00069 }
00070 
00071 unsigned int
00072 CDTGenerator::getBinSize() const {
00073   unsigned int used=FilterBankGenerator::getBinSize();
00074   // todo - once we have color information - we could make this interoperable with SegmentedColorGenerator
00075   // by following the same serialization format
00076   used+=strlen("CDTImage")+LoadSave::stringpad;
00077   used+=widths[selectedSaveLayer]*heights[selectedSaveLayer];
00078   return used;
00079 }
00080 
00081 unsigned int
00082 CDTGenerator::LoadBuffer(const char [] /*buf*/, unsigned int /*len*/) {
00083   //all our memory is in system controlled buffers - we probably shouldn't overwrite it...
00084   serr->printf("Can't load into CDTGenerator");
00085   return 0;
00086 }
00087 
00088 unsigned int
00089 CDTGenerator::SaveBuffer(char buf[], unsigned int len) const {
00090   unsigned int origlen=len;
00091   unsigned int used;
00092   if(0==(used=FilterBankGenerator::SaveBuffer(buf,len))) return 0;
00093   len-=used; buf+=used;
00094   // todo - once we have color information - we could make this interoperable with SegmentedColorGenerator
00095   // by following the same serialization format
00096   if(0==(used=encode("CDTImage",buf,len))) return 0;
00097   len-=used; buf+=used;
00098   
00099   unsigned char* img=getImage(selectedSaveLayer,selectedSaveChannel);
00100   used=widths[selectedSaveLayer]*heights[selectedSaveLayer];
00101   if(used>len)
00102     return 0;
00103   unsigned int inc=getIncrement(selectedSaveLayer);
00104   if(inc==1) {
00105     //special case, straight copy
00106     for(unsigned int y=0; y<heights[selectedSaveLayer]; y++) {
00107       unsigned char* const rowend=img+widths[selectedSaveLayer];
00108       while(img!=rowend)
00109         *buf++=*img++;
00110       img+=getSkip(selectedSaveLayer);
00111     }
00112   } else {
00113     //otherwise, interleaved or subsampling
00114     for(unsigned int y=0; y<heights[selectedSaveLayer]; y++) {
00115       unsigned char* const rowend=img+widths[selectedSaveLayer]*inc;
00116       while(img!=rowend) {
00117         *buf++=*img;
00118         img+=inc;
00119       }
00120       img+=getSkip(selectedSaveLayer);
00121     }
00122   }
00123   len-=used;
00124   
00125   return origlen-len;
00126 }
00127 
00128 void
00129 CDTGenerator::setDimensions() {
00130   freeCaches();
00131   unsigned int numNotRealLayers=numLayers-numRealLayers;
00132   for(unsigned int res=0; res<numNotRealLayers; res++) {
00133     widths[res] = imageInfos[numNotRealLayers]->width>>(numNotRealLayers-res);
00134     heights[res] = imageInfos[numNotRealLayers]->height>>(numNotRealLayers-res);
00135     ASSERT(widths[res]*increments[res]==widths[numNotRealLayers],"widths*increments doesn't match total width");
00136     strides[res]=strides[numNotRealLayers]*increments[res];
00137     skips[res]=skips[numNotRealLayers]+strides[res]-strides[numNotRealLayers];
00138   }
00139   strides[numLayers-1]=widths[numLayers-1]=widths[numLayers-2]*2;
00140   heights[numLayers-1]=heights[numLayers-2]*2;
00141 }
00142 
00143 void 
00144 CDTGenerator::freeCaches() {
00145   for(unsigned int i=0; i<numLayers; i++) {
00146     for(unsigned int j=0; j<numChannels; j++) {
00147       images[i][j]=NULL;
00148       imageValids[i][j]=false;
00149     }
00150   }
00151   FilterBankGenerator::freeCaches();
00152 }
00153 
00154 void
00155 CDTGenerator::setNumImages(unsigned int nLayers, unsigned int nChannels) {
00156   FilterBankGenerator::setNumImages(nLayers,nChannels);
00157   layers=new unsigned char*[numLayers];
00158   imageInfos=new const OFbkImageInfo*[numLayers];
00159   unsigned int numNotRealLayers=numLayers-numRealLayers;
00160   for(unsigned int res=0; res<numLayers; res++) {
00161     layers[res]=NULL;
00162     imageInfos[res]=NULL;
00163     if(res<numNotRealLayers)
00164       increments[res]=1<<(numNotRealLayers-res);
00165   }
00166 }
00167 
00168 unsigned char *
00169 CDTGenerator::createImageCache(unsigned int /*layer*/, unsigned int /*chan*/) const {
00170   return NULL; // calcImage will set the cache itself
00171 }
00172 
00173 void
00174 CDTGenerator::calcImage(unsigned int layer, unsigned int chan) const {
00175   PROFSECTION("CDTGenerator::calcImage(...)",state->mainProfile);
00176   unsigned int numNotRealLayers=numLayers-numRealLayers;
00177   if(layer>=numNotRealLayers) {
00178     unsigned int fbkdatChan=ofbkimageBAND_CDT;
00179     const OFbkImage img(const_cast<OFbkImageInfo*>(imageInfos[layer]), const_cast<unsigned char*>(layers[layer]), fbkdatChan);
00180     images[layer][chan]=img.Pointer();
00181 
00182     //I'm not sure if this is needed for CDT images themselves - haven't used it yet
00183     //so this section is commented out for now just in case.
00184     /*
00185       //this part restores pixels over written with the CDT table and
00186       //frame count.  Yes, we are modifying the original image passed
00187       //from the system here...
00188       if(config->vision.restore_image) {
00189         const unsigned int numPix=16;
00190         if(layer==numLayers-2) {
00191           unsigned char * s=images[layer][chan]+getStride(layer)*(getHeight(layer)-2);
00192           unsigned char * d=images[layer][chan]+getStride(layer)*(getHeight(layer)-1);
00193           for(unsigned int i=0; i<numPix; i++)
00194             *d++=*s++;
00195         } else {
00196           unsigned int inc=1<<(numLayers-2-layer);
00197           unsigned char * s;
00198           //unsigned char * s=getImage(numLayers-2,chan)+getStride(numLayers-2)*(getHeight(numLayers-2)-inc);
00199           //...or an attempt to possibly avoid a trivial amount of recomputation....
00200           if(!imageValids[numLayers-2][chan]) {
00201             const OFbkImage simg(const_cast<OFbkImageInfo*>(imageInfos[numLayers-2]), const_cast<unsigned char*>(layers[numLayers-2]), fbkdatChan);
00202             s=simg.Pointer();
00203           } else {
00204             s=images[numLayers-2][chan];
00205           }
00206           s+=getStride(numLayers-2)*(getHeight(numLayers-2)-inc);
00207           unsigned char * d=images[layer][chan]+getStride(layer)*(getHeight(layer)-1);
00208           for(unsigned int i=0; i<numPix; i++) {
00209             *d++=*s;
00210             s+=inc;
00211           }
00212         }
00213       }
00214     */
00215   } else {
00216     //we don't need to do the restoration in the previous section
00217     //here because these layers skip the last row
00218     unsigned int fbkdatChan=ofbkimageBAND_CDT;
00219     const OFbkImage img(const_cast<OFbkImageInfo*>(imageInfos[numNotRealLayers]), const_cast<unsigned char*>(layers[numNotRealLayers]), fbkdatChan);
00220     images[layer][chan]=img.Pointer();
00221   }
00222   imageValids[layer][chan]=true;
00223 }
00224 
00225 void
00226 CDTGenerator::destruct() {
00227   FilterBankGenerator::destruct();
00228   delete [] layers;
00229   layers=NULL;
00230   delete [] imageInfos;
00231   imageInfos=NULL;
00232 }
00233 
00234 /*! @file
00235  * @brief Implements CDTGenerator, which generates SegmentedColorFilterBankEvents with images provided from the system
00236  * @author ejt (Creator)
00237  *
00238  * $Author: ejt $
00239  * $Name: tekkotsu-2_0 $
00240  * $Revision: 1.5 $
00241  * $State: Exp $
00242  * $Date: 2004/01/18 10:16:59 $
00243  */
00244 

Tekkotsu v2.0
Generated Wed Jan 21 03:20:27 2004 by Doxygen 1.3.4