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

Tekkotsu v2.1
Generated Tue Mar 16 23:19:13 2004 by Doxygen 1.3.5