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/Profiler.h"
00008 #include "Shared/ProjectInterface.h"
00009
00010 #include "Shared/ODataFormats.h"
00011 #include "OFbkImage.h"
00012
00013 #include "Shared/debuget.h"
00014
00015 CDTGenerator::CDTGenerator(unsigned int numRawLayers, unsigned int numCalcLayers, unsigned int mysid, EventBase::EventGeneratorID_t gid, unsigned int sid)
00016 : FilterBankGenerator("CDTGenerator",EventBase::visSegmentEGID,mysid,gid,sid), numRealLayers(numRawLayers), layers(NULL), imageInfos(NULL)
00017 {
00018
00019
00020
00021
00022
00023 unsetAutoListen();
00024
00025 setNumImages(numCalcLayers,NUM_CHANNELS);
00026 }
00027
00028
00029
00030
00031
00032 void
00033 CDTGenerator::doEvent() {
00034 if(event->getGeneratorID()!=getListenGeneratorID() || event->getSourceID()!=getListenSourceID())
00035 return;
00036 if(event->getTypeID()==EventBase::activateETID) {
00037 typedef DataEvent<const OFbkImageVectorData*> OFbkEvent;
00038 const OFbkEvent& fbkevent=dynamic_cast<const OFbkEvent& >(*event);
00039 OFbkImageVectorData& fbkdat=*const_cast<OFbkImageVectorData*>(fbkevent.getData());
00040 for(unsigned int res=0; res<numRealLayers; res++) {
00041 layers[numLayers-1-res] = fbkdat.GetData(res);
00042 imageInfos[numLayers-1-res] = fbkdat.GetInfo(res);
00043 }
00044 {
00045 const OFbkImage img(const_cast<OFbkImageInfo*>(imageInfos[numLayers-2]), const_cast<unsigned char*>(layers[numLayers-2]), ofbkimageBAND_CDT);
00046
00047 sysFrameNumber=frameNumber=*(int*)(img.Pointer()+(img.Height()-1)*(img.Skip()+img.Width()));
00048 }
00049 unsigned int numNotRealLayers=numLayers-numRealLayers;
00050 bool dimchange=false;
00051 for(unsigned int res=numNotRealLayers; res<numLayers; res++) {
00052 if(widths[res]!=imageInfos[res]->width || heights[res]!=imageInfos[res]->height) {
00053 dimchange=true;
00054 serr->printf("WARNING: the image dimensions changed, now %dx%d\n",widths[numLayers-1],heights[numLayers-1]);
00055 widths[res] = imageInfos[res]->width;
00056 heights[res] = imageInfos[res]->height;
00057 }
00058
00059 const OFbkImage img(const_cast<OFbkImageInfo*>(imageInfos[res]), const_cast<unsigned char*>(layers[res]), ofbkimageBAND_CDT);
00060 skips[res]=img.Skip();
00061 strides[res]=skips[res]+widths[res];
00062
00063 ASSERT(static_cast<unsigned int>(img.Width())==getWidth(res),"Widths don't match");
00064 ASSERT(static_cast<unsigned int>(img.Height())==getHeight(res),"Heights don't match");
00065 }
00066 if(numNotRealLayers>0) {
00067 if(widths[numNotRealLayers-1]*2!=widths[numNotRealLayers] || heights[numNotRealLayers]*2!=heights[numNotRealLayers]) {
00068
00069
00070
00071 serr->printf("WARNING: the image dimensions don't match values predicted by RobotInfo consts, \"full\" layer now %dx%d\n",widths[ProjectInterface::fullLayer],heights[ProjectInterface::fullLayer]);
00072 dimchange=true;
00073 } else if(strides[0]==0) {
00074 dimchange=true;
00075 }
00076 }
00077 if(dimchange)
00078 setDimensions();
00079
00080 invalidateCaches();
00081 framesProcessed++;
00082 }
00083
00084 erouter->postEvent(SegmentedColorFilterBankEvent(this,getGeneratorID(),getSourceID(),event->getTypeID(),NULL,0,NULL,NULL));
00085 }
00086
00087 unsigned int
00088 CDTGenerator::getBinSize() const {
00089 unsigned int used=FilterBankGenerator::getBinSize();
00090
00091
00092 used+=strlen("CDTImage")+LoadSave::stringpad;
00093 used+=widths[selectedSaveLayer]*heights[selectedSaveLayer];
00094 return used;
00095 }
00096
00097 unsigned int
00098 CDTGenerator::loadBuffer(const char [] , unsigned int , const char* filename) {
00099
00100 serr->printf("Can't load into CDTGenerator: %s",filename);
00101 return 0;
00102 }
00103
00104 unsigned int
00105 CDTGenerator::saveBuffer(char buf[], unsigned int len) const {
00106 unsigned int origlen=len;
00107 unsigned int used;
00108 if(0==(used=FilterBankGenerator::saveBuffer(buf,len))) return 0;
00109 len-=used; buf+=used;
00110
00111
00112 if(0==(used=encode("CDTImage",buf,len))) return 0;
00113 len-=used; buf+=used;
00114
00115 if(images[selectedSaveLayer][selectedSaveChannel]==NULL) {
00116 serr->printf("CDTImage::saveBuffer() failed because selected image is NULL -- call selectSaveImage first to make sure it's up to date\n");
00117 return 0;
00118 }
00119 if(!imageValids[selectedSaveLayer][selectedSaveChannel]) {
00120 serr->printf("CDTImage::saveBuffer() failed because selected image is invalid -- call selectSaveImage first to make sure it's up to date\n");
00121 return 0;
00122 }
00123 unsigned char* img=images[selectedSaveLayer][selectedSaveChannel];
00124 used=widths[selectedSaveLayer]*heights[selectedSaveLayer];
00125 if(used>len)
00126 return 0;
00127 unsigned int inc=getIncrement(selectedSaveLayer);
00128 if(inc==1) {
00129
00130 for(unsigned int y=0; y<heights[selectedSaveLayer]; y++) {
00131 unsigned char* const rowend=img+widths[selectedSaveLayer];
00132 while(img!=rowend)
00133 *buf++=*img++;
00134 img+=getSkip(selectedSaveLayer);
00135 }
00136 } else {
00137
00138 for(unsigned int y=0; y<heights[selectedSaveLayer]; y++) {
00139 unsigned char* const rowend=img+widths[selectedSaveLayer]*inc;
00140 while(img!=rowend) {
00141 *buf++=*img;
00142 img+=inc;
00143 }
00144 img+=getSkip(selectedSaveLayer);
00145 }
00146 }
00147 len-=used;
00148
00149 return origlen-len;
00150 }
00151
00152 void
00153 CDTGenerator::setDimensions() {
00154 freeCaches();
00155 unsigned int numNotRealLayers=numLayers-numRealLayers;
00156 for(unsigned int res=0; res<numNotRealLayers; res++) {
00157 widths[res] = imageInfos[numNotRealLayers]->width>>(numNotRealLayers-res);
00158 heights[res] = imageInfos[numNotRealLayers]->height>>(numNotRealLayers-res);
00159 ASSERT(widths[res]*increments[res]==widths[numNotRealLayers],"widths*increments doesn't match total width");
00160 strides[res]=strides[numNotRealLayers]*increments[res];
00161 skips[res]=skips[numNotRealLayers]+strides[res]-strides[numNotRealLayers];
00162 }
00163 strides[numLayers-1]=widths[numLayers-1]=widths[numLayers-2]*2;
00164 heights[numLayers-1]=heights[numLayers-2]*2;
00165 }
00166
00167 void
00168 CDTGenerator::freeCaches() {
00169 for(unsigned int i=0; i<numLayers; i++) {
00170 for(unsigned int j=0; j<numChannels; j++) {
00171 images[i][j]=NULL;
00172 imageValids[i][j]=false;
00173 }
00174 }
00175 FilterBankGenerator::freeCaches();
00176 }
00177
00178 void
00179 CDTGenerator::setNumImages(unsigned int nLayers, unsigned int nChannels) {
00180 if(nLayers==numLayers && nChannels==numChannels)
00181 return;
00182 FilterBankGenerator::setNumImages(nLayers,nChannels);
00183 layers=new unsigned char*[numLayers];
00184 imageInfos=new const OFbkImageInfo*[numLayers];
00185 unsigned int numNotRealLayers=numLayers-numRealLayers;
00186 for(unsigned int res=0; res<numLayers; res++) {
00187 layers[res]=NULL;
00188 imageInfos[res]=NULL;
00189 if(res<numNotRealLayers)
00190 increments[res]=1<<(numNotRealLayers-res);
00191 }
00192 }
00193
00194 unsigned char *
00195 CDTGenerator::createImageCache(unsigned int , unsigned int ) const {
00196 return NULL;
00197 }
00198
00199 void
00200 CDTGenerator::calcImage(unsigned int layer, unsigned int chan) {
00201 PROFSECTION("CDTGenerator::calcImage(...)",*mainProfiler);
00202 unsigned int numNotRealLayers=numLayers-numRealLayers;
00203 if(layer>=numNotRealLayers) {
00204 unsigned int fbkdatChan=ofbkimageBAND_CDT;
00205 const OFbkImage img(const_cast<OFbkImageInfo*>(imageInfos[layer]), const_cast<unsigned char*>(layers[layer]), fbkdatChan);
00206 images[layer][chan]=img.Pointer();
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241 } else {
00242
00243
00244 unsigned int fbkdatChan=ofbkimageBAND_CDT;
00245 const OFbkImage img(const_cast<OFbkImageInfo*>(imageInfos[numNotRealLayers]), const_cast<unsigned char*>(layers[numNotRealLayers]), fbkdatChan);
00246 images[layer][chan]=img.Pointer();
00247 }
00248 imageValids[layer][chan]=true;
00249 }
00250
00251 void
00252 CDTGenerator::destruct() {
00253 FilterBankGenerator::destruct();
00254 delete [] layers;
00255 layers=NULL;
00256 delete [] imageInfos;
00257 imageInfos=NULL;
00258 }
00259
00260
00261
00262
00263
00264