Homepage Demos Overview Downloads Tutorials Reference
Credits

RLEGenerator.cc

Go to the documentation of this file.
00001 #include "RLEGenerator.h"
00002 #include "Events/EventRouter.h"
00003 #include "Events/SegmentedColorFilterBankEvent.h"
00004 #include "Wireless/Wireless.h"
00005 #include "Shared/WorldState.h"
00006 
00007 #include "Shared/debuget.h"
00008 
00009 RLEGenerator::RLEGenerator(EventBase::EventGeneratorID_t gid, unsigned int sid, unsigned int mysid)
00010   : FilterBankGenerator("RLEGenerator",0,0,gid,sid,EventBase::visRLEEGID,mysid), src(NULL), numRuns(NULL), maxRuns(NULL)
00011 {
00012   setNumImages(numLayers,numChannels);
00013 }
00014 
00015 RLEGenerator::~RLEGenerator() {
00016   freeCaches();
00017   destruct();
00018 }
00019 
00020 void
00021 RLEGenerator::processEvent(const EventBase& event) {
00022   const FilterBankEvent& fbkevent=dynamic_cast<const FilterBankEvent& >(event);
00023   src=fbkevent.getSource();
00024   frameNumber=src->getFrameNumber();
00025   if(src->getNumLayers()!=numLayers || src->getNumChannels()!=numChannels)
00026     setNumImages(src->getNumLayers(),src->getNumChannels());
00027   if(src->getWidth(numLayers-1)!=getWidth(numLayers-1))
00028     setDimensions();
00029 
00030   invalidateCaches();
00031   framesProcessed++;
00032   if(const SegmentedColorFilterBankEvent * segsrc=dynamic_cast<const SegmentedColorFilterBankEvent *>(&fbkevent))
00033     erouter->postEvent(new SegmentedColorFilterBankEvent(this,getGeneratorID(),getSourceID(),*segsrc));
00034   else
00035     erouter->postEvent(new FilterBankEvent(this,getGeneratorID(),getSourceID()));
00036 }
00037 
00038 unsigned int
00039 RLEGenerator::getBinSize() const {
00040   unsigned int used=FilterBankGenerator::getBinSize();
00041   used+=strlen("RLEImage")+LoadSave::stringpad;
00042   used+=sizeof(unsigned int);
00043   if(imageValids[selectedSaveLayer][selectedSaveChannel])
00044     used+=XMIT_BYTES_PER_RUN*numRuns[selectedSaveLayer][selectedSaveChannel];
00045   else
00046     used+=XMIT_BYTES_PER_RUN*maxRuns[selectedSaveLayer];
00047   return used;
00048 }
00049 
00050 /*! this isn't really tested, don't rely on it working without a little debugging... specifically, doesn't set parent or next fields*/
00051 unsigned int
00052 RLEGenerator::LoadBuffer(const char buf[], unsigned int len) {
00053   unsigned int origlen=len;
00054   unsigned int used;
00055   std::string tmp;
00056   if(0==(used=FilterBankGenerator::LoadBuffer(buf,len))) return 0;
00057   len-=used; buf+=used;
00058   if(0==(used=decode(tmp,buf,len))) return 0;
00059   len-=used; buf+=used;
00060   if(tmp!="RLEImage") {
00061     serr->printf("Unhandled image type for RLEGenerator: %s",tmp.c_str());
00062     return 0;
00063   } else {
00064     if(0==(used=decode(numRuns[selectedSaveLayer][selectedSaveChannel],buf,len))) return 0;
00065     len-=used; buf+=used;
00066     if(maxRuns[selectedSaveLayer]<numRuns[selectedSaveLayer][selectedSaveChannel])
00067       return 0;
00068     if(images[selectedSaveLayer][selectedSaveChannel]==NULL)
00069       images[selectedSaveLayer][selectedSaveChannel]=createImageCache(selectedSaveLayer,selectedSaveChannel);
00070     run * runs=reinterpret_cast<run*>(images[selectedSaveLayer][selectedSaveChannel]);
00071     if(runs==NULL)
00072       return 0;
00073     unsigned int y=0;
00074     for(unsigned int i=0; i<numRuns[selectedSaveLayer][selectedSaveChannel]; i++) {
00075       if(0==(used=decode(runs[i].color,buf,len))) return 0;
00076       len-=used; buf+=used;
00077       if(0==(used=decode(runs[i].x,buf,len))) return 0;
00078       len-=used; buf+=used;
00079       if(0==(used=decode(runs[i].width,buf,len))) return 0;
00080       len-=used; buf+=used;
00081       if((unsigned int)(runs[i].x+runs[i].width)>=getWidth(selectedSaveLayer))
00082         y++;
00083       runs[i].y=y;
00084     }
00085     imageValids[selectedSaveLayer][selectedSaveChannel]=true;
00086     return origlen-len; 
00087   }
00088 }
00089 
00090 unsigned int
00091 RLEGenerator::SaveBuffer(char buf[], unsigned int len) const {
00092   unsigned int origlen=len;
00093   unsigned int used;
00094   if(0==(used=FilterBankGenerator::SaveBuffer(buf,len))) return 0;
00095   len-=used; buf+=used;
00096   if(0==(used=encode("RLEImage",buf,len))) return 0;
00097   len-=used; buf+=used;
00098   
00099   run * runs=reinterpret_cast<run*>(getImage(selectedSaveLayer,selectedSaveChannel));
00100   if(runs==NULL)
00101     return 0;
00102   if(0==(used=encode(numRuns[selectedSaveLayer][selectedSaveChannel],buf,len))) return 0;
00103   len-=used; buf+=used;
00104   for(unsigned int i=0; i<numRuns[selectedSaveLayer][selectedSaveChannel]; i++) {
00105     if(0==(used=encode(runs[i].color,buf,len))) return 0;
00106     len-=used; buf+=used;
00107     if(0==(used=encode(runs[i].x,buf,len))) return 0;
00108     len-=used; buf+=used;
00109     if(0==(used=encode(runs[i].width,buf,len))) return 0;
00110     len-=used; buf+=used;
00111   }
00112   return origlen-len;
00113 }
00114 
00115 void
00116 RLEGenerator::setDimensions() {
00117   for(unsigned int i=0; i<numLayers; i++) {
00118     widths[i]=src->getWidth(i);
00119     heights[i]=src->getHeight(i);
00120     maxRuns[i]=calcExpMaxRuns(i);
00121   } 
00122 }
00123 
00124 void
00125 RLEGenerator::setNumImages(unsigned int nLayers, unsigned int nChannels) {
00126   FilterBankGenerator::setNumImages(nLayers,nChannels);
00127   maxRuns=new unsigned int[numLayers];
00128   numRuns=new unsigned int*[numLayers];
00129   for(unsigned int i=0; i<numLayers; i++) {
00130     maxRuns[i]=calcExpMaxRuns(i);
00131     numRuns[i]=new unsigned int[numChannels];
00132   }
00133 }
00134 
00135 //! simply creates a new data region and returns it
00136 unsigned char *
00137 RLEGenerator::createImageCache(unsigned int layer, unsigned int /*chan*/) const {
00138   return reinterpret_cast<unsigned char*>(new run[maxRuns[layer]]);
00139 }
00140 
00141 //! a single call to the CMVision library to do the work, and we're done.
00142 void
00143 RLEGenerator::calcImage(unsigned int layer, unsigned int chan) const {
00144   PROFSECTION("RLEGenerator::calcImage(...)",state->mainProfile);
00145   numRuns[layer][chan] = CMVision::EncodeRuns(reinterpret_cast<run*>(images[layer][chan]),src->getImage(layer,chan),getWidth(layer),getHeight(layer),maxRuns[layer]);
00146   imageValids[layer][chan]=true; // <--- don't forget to do this, otherwise you'll recompute on every access, even if the cache is still valid
00147 }
00148 
00149 void
00150 RLEGenerator::destruct() {
00151   FilterBankGenerator::destruct();
00152   for(unsigned int i=0; i<numLayers; i++)
00153     delete [] numRuns[i];
00154   delete [] numRuns;
00155   numRuns=NULL;
00156   delete [] maxRuns;
00157   maxRuns=NULL;
00158 }
00159 
00160 /*! @file
00161  * @brief Implements RLEGenerator, which generates RLE compressed FilterBankEvents (generally from indexed color images from, say, SegmentedColorGenerator)
00162  * @author alokl (Creator)
00163  * @author ejt (reorganized)
00164  *
00165  * $Author: ejt $
00166  * $Name: tekkotsu-2_0_1+Doc $
00167  * $Revision: 1.6 $
00168  * $State: Exp $
00169  * $Date: 2004/02/05 02:37:09 $
00170  */
00171 

Tekkotsu v2.0.1+Doc
Generated Mon Feb 9 22:16:50 2004 by Doxygen 1.3.5