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

Tekkotsu v5.1CVS
Generated Mon May 9 04:58:50 2016 by Doxygen 1.6.3