Homepage
Demos
Overview
Downloads
Dev. Resources
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 /*! TODO - after RLEGraphics is inplace, replace the 'tid' parameter in FBG's constructor call! */
00010 RLEGenerator::RLEGenerator(unsigned int mysid, FilterBankGenerator* fbg, EventBase::EventTypeID_t /*tid*/)
00011   : FilterBankGenerator("RLEGenerator","RLEGenerator",EventBase::visRLEEGID,mysid,fbg), numRuns(NULL), maxRuns(NULL)
00012 {
00013   //this part is only necessary if you override setNumImages yourself
00014   if(fbg!=NULL) {
00015     numLayers=numChannels=0; //this is to force setNumImages to override settings provided by FilterBankGenerator
00016     setNumImages(fbg->getNumLayers(),fbg->getNumChannels());
00017   }
00018 }
00019 
00020 void
00021 RLEGenerator::processEvent(const EventBase& event) {
00022   FilterBankGenerator::processEvent(event);
00023   if(event.getGeneratorID()==getListenGeneratorID() && event.getSourceID()==getListenSourceID()) {
00024     //Technically, we should do things this way:
00025     /*
00026     if(const SegmentedColorFilterBankEvent * segsrc=dynamic_cast<const SegmentedColorFilterBankEvent *>(&event)) {
00027       erouter->postEvent(new SegmentedColorFilterBankEvent(this,getGeneratorID(),getSourceID(),EventBase::activateETID,*segsrc));
00028       erouter->postEvent(new SegmentedColorFilterBankEvent(this,getGeneratorID(),getSourceID(),EventBase::statusETID,*segsrc));
00029       erouter->postEvent(new SegmentedColorFilterBankEvent(this,getGeneratorID(),getSourceID(),EventBase::deactivateETID,*segsrc));
00030     } else {
00031       erouter->postEvent(new FilterBankEvent(this,getGeneratorID(),getSourceID(),EventBase::activateETID));
00032       erouter->postEvent(new FilterBankEvent(this,getGeneratorID(),getSourceID(),EventBase::statusETID));
00033       erouter->postEvent(new FilterBankEvent(this,getGeneratorID(),getSourceID(),EventBase::deactivateETID));
00034     }
00035     */
00036     //But until RLEGraphics is in place, we'll do it this way so recompression can be triggered
00037     //after drawing into segmented image
00038     if(const SegmentedColorFilterBankEvent * segsrc=dynamic_cast<const SegmentedColorFilterBankEvent *>(&event)) {
00039       erouter->postEvent(new SegmentedColorFilterBankEvent(this,getGeneratorID(),getSourceID(),event.getTypeID(),*segsrc));
00040     } else {
00041       erouter->postEvent(new FilterBankEvent(this,getGeneratorID(),getSourceID(),event.getTypeID()));
00042     }
00043   }
00044 }
00045 
00046 unsigned int
00047 RLEGenerator::getBinSize() const {
00048   unsigned int used=FilterBankGenerator::getBinSize();
00049   used+=strlen("RLEImage")+LoadSave::stringpad;
00050   used+=sizeof(unsigned int);
00051   if(imageValids[selectedSaveLayer][selectedSaveChannel])
00052     used+=XMIT_BYTES_PER_RUN*numRuns[selectedSaveLayer][selectedSaveChannel];
00053   else
00054     used+=XMIT_BYTES_PER_RUN*maxRuns[selectedSaveLayer];
00055   return used;
00056 }
00057 
00058 /*! this isn't really tested, don't rely on it working without a little debugging... specifically, doesn't set parent or next fields*/
00059 unsigned int
00060 RLEGenerator::LoadBuffer(const char buf[], unsigned int len) {
00061   unsigned int origlen=len;
00062   unsigned int used;
00063   std::string tmp;
00064   if(0==(used=FilterBankGenerator::LoadBuffer(buf,len))) return 0;
00065   len-=used; buf+=used;
00066   if(0==(used=decode(tmp,buf,len))) return 0;
00067   len-=used; buf+=used;
00068   if(tmp!="RLEImage") {
00069     serr->printf("Unhandled image type for RLEGenerator: %s",tmp.c_str());
00070     return 0;
00071   } else {
00072     if(0==(used=decode(numRuns[selectedSaveLayer][selectedSaveChannel],buf,len))) return 0;
00073     len-=used; buf+=used;
00074     if(maxRuns[selectedSaveLayer]<numRuns[selectedSaveLayer][selectedSaveChannel])
00075       return 0;
00076     if(images[selectedSaveLayer][selectedSaveChannel]==NULL)
00077       images[selectedSaveLayer][selectedSaveChannel]=createImageCache(selectedSaveLayer,selectedSaveChannel);
00078     run * runs=reinterpret_cast<run*>(images[selectedSaveLayer][selectedSaveChannel]);
00079     if(runs==NULL)
00080       return 0;
00081     unsigned int y=0;
00082     for(unsigned int i=0; i<numRuns[selectedSaveLayer][selectedSaveChannel]; i++) {
00083       if(0==(used=decode(runs[i].color,buf,len))) return 0;
00084       len-=used; buf+=used;
00085       if(0==(used=decode(runs[i].x,buf,len))) return 0;
00086       len-=used; buf+=used;
00087       if(0==(used=decode(runs[i].width,buf,len))) return 0;
00088       len-=used; buf+=used;
00089       if((unsigned int)(runs[i].x+runs[i].width)>=getWidth(selectedSaveLayer))
00090         y++;
00091       runs[i].y=y;
00092     }
00093     imageValids[selectedSaveLayer][selectedSaveChannel]=true;
00094     return origlen-len; 
00095   }
00096 }
00097 
00098 unsigned int
00099 RLEGenerator::SaveBuffer(char buf[], unsigned int len) const {
00100   unsigned int origlen=len;
00101   unsigned int used;
00102   if(0==(used=FilterBankGenerator::SaveBuffer(buf,len))) return 0;
00103   len-=used; buf+=used;
00104   if(0==(used=encode("RLEImage",buf,len))) return 0;
00105   len-=used; buf+=used;
00106   
00107   if(images[selectedSaveLayer][selectedSaveChannel]==NULL) {
00108     serr->printf("RLEGenerator::SaveBuffer() failed because selected image is NULL -- call selectSaveImage first to make sure it's up to date\n");
00109     return 0;
00110   }
00111   if(!imageValids[selectedSaveLayer][selectedSaveChannel]) {
00112     serr->printf("RLEGenerator::SaveBuffer() failed because selected image is invalid -- call selectSaveImage first to make sure it's up to date\n");
00113     return 0;
00114   }
00115   unsigned char* img=images[selectedSaveLayer][selectedSaveChannel];
00116   run * runs=reinterpret_cast<run*>(img);
00117   if(runs==NULL)
00118     return 0;
00119   if(0==(used=encode(numRuns[selectedSaveLayer][selectedSaveChannel],buf,len))) return 0;
00120   len-=used; buf+=used;
00121   for(unsigned int i=0; i<numRuns[selectedSaveLayer][selectedSaveChannel]; i++) {
00122     if(0==(used=encode(runs[i].color,buf,len))) return 0;
00123     len-=used; buf+=used;
00124     if(0==(used=encode(runs[i].x,buf,len))) return 0;
00125     len-=used; buf+=used;
00126     if(0==(used=encode(runs[i].width,buf,len))) return 0;
00127     len-=used; buf+=used;
00128   }
00129   return origlen-len;
00130 }
00131 
00132 void
00133 RLEGenerator::setDimensions() {
00134   FilterBankGenerator::setDimensions();
00135   for(unsigned int i=0; i<numLayers; i++)
00136     maxRuns[i]=calcExpMaxRuns(i);
00137 }
00138 
00139 void
00140 RLEGenerator::setNumImages(unsigned int nLayers, unsigned int nChannels) {
00141   if(nLayers==numLayers && nChannels==numChannels)
00142     return;
00143   FilterBankGenerator::setNumImages(nLayers,nChannels); //calls destruct()...
00144   maxRuns=new unsigned int[numLayers];
00145   numRuns=new unsigned int*[numLayers];
00146   for(unsigned int i=0; i<numLayers; i++) {
00147     maxRuns[i]=calcExpMaxRuns(i);
00148     numRuns[i]=new unsigned int[numChannels];
00149   }
00150 }
00151 
00152 //! simply creates a new data region and returns it
00153 unsigned char *
00154 RLEGenerator::createImageCache(unsigned int layer, unsigned int /*chan*/) const {
00155   return reinterpret_cast<unsigned char*>(new run[maxRuns[layer]]);
00156 }
00157 
00158 //! a single call to the CMVision library to do the work, and we're done.
00159 void
00160 RLEGenerator::calcImage(unsigned int layer, unsigned int chan) {
00161   PROFSECTION("RLEGenerator::calcImage(...)",state->mainProfile);
00162   numRuns[layer][chan] = CMVision::EncodeRuns(reinterpret_cast<run*>(images[layer][chan]),src->getImage(layer,chan),getWidth(layer),getHeight(layer),maxRuns[layer]);
00163   imageValids[layer][chan]=true; // <--- don't forget to do this, otherwise you'll recompute on every access, even if the cache is still valid
00164 }
00165 
00166 void
00167 RLEGenerator::destruct() {
00168   FilterBankGenerator::destruct();
00169   for(unsigned int i=0; i<numLayers; i++)
00170     delete [] numRuns[i];
00171   delete [] numRuns;
00172   numRuns=NULL;
00173   delete [] maxRuns;
00174   maxRuns=NULL;
00175 }
00176 
00177 /*! @file
00178  * @brief Implements RLEGenerator, which generates RLE compressed FilterBankEvents (generally from indexed color images from, say, SegmentedColorGenerator)
00179  * @author alokl (Creator)
00180  * @author ejt (reorganized)
00181  *
00182  * $Author: ejt $
00183  * $Name: tekkotsu-2_4_1 $
00184  * $Revision: 1.11 $
00185  * $State: Exp $
00186  * $Date: 2005/06/13 21:24:11 $
00187  */
00188 

Tekkotsu v2.4.1
Generated Tue Aug 16 16:32:48 2005 by Doxygen 1.4.4