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

Tekkotsu v2.2.1
Generated Tue Nov 23 16:36:37 2004 by Doxygen 1.3.9.1