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

Tekkotsu v4.0
Generated Thu Nov 22 00:54:55 2007 by Doxygen 1.5.4