00001 #include "RawCameraGenerator.h"
00002 #include "Events/DataEvent.h"
00003 #include "Events/EventRouter.h"
00004 #include "Events/FilterBankEvent.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 #include <float.h>
00016
00017 RawCameraGenerator::RawCameraGenerator(unsigned int numRawLayers, unsigned int numCalcLayers, unsigned int mysid, EventBase::EventGeneratorID_t gid, unsigned int sid)
00018 : FilterBankGenerator("RawCameraGenerator",EventBase::visRawCameraEGID,mysid,gid,sid), numRealLayers(numRawLayers), layers(NULL), imageInfos(NULL)
00019 {
00020
00021
00022
00023
00024
00025 unsetAutoListen();
00026
00027 setNumImages(numCalcLayers,NUM_CHANNELS);
00028 }
00029
00030
00031
00032
00033
00034 void
00035 RawCameraGenerator::doEvent() {
00036 if(event->getGeneratorID()!=getListenGeneratorID() || event->getSourceID()!=getListenSourceID())
00037 return;
00038 if(event->getTypeID()==EventBase::activateETID) {
00039 typedef DataEvent<const OFbkImageVectorData*> OFbkEvent;
00040 const OFbkEvent& fbkevent=dynamic_cast<const OFbkEvent& >(*event);
00041 OFbkImageVectorData& fbkdat=*const_cast<OFbkImageVectorData*>(fbkevent.getData());
00042 for(unsigned int res=0; res<numRealLayers; res++) {
00043 layers[numLayers-2-res] = fbkdat.GetData(res);
00044 imageInfos[numLayers-2-res] = fbkdat.GetInfo(res);
00045 }
00046 {
00047 const OFbkImage img(const_cast<OFbkImageInfo*>(imageInfos[numLayers-2]), const_cast<unsigned char*>(layers[numLayers-2]), ofbkimageBAND_Y);
00048
00049 sysFrameNumber=frameNumber=*(int*)(img.Pointer()+(img.Height()-1)*(img.Skip()+img.Width()));
00050 }
00051 unsigned int numNotRealLayers=numLayers-1-numRealLayers;
00052 bool dimchange=false;
00053 for(unsigned int res=numNotRealLayers; res<numLayers-1; res++) {
00054 if(widths[res]!=imageInfos[res]->width || heights[res]!=imageInfos[res]->height) {
00055 dimchange=true;
00056 serr->printf("WARNING: the image dimensions changed, now %dx%d\n",widths[numLayers-1],heights[numLayers-1]);
00057 widths[res] = imageInfos[res]->width;
00058 heights[res] = imageInfos[res]->height;
00059 }
00060
00061 const OFbkImage img(const_cast<OFbkImageInfo*>(imageInfos[res]), const_cast<unsigned char*>(layers[res]), ofbkimageBAND_Y);
00062 skips[res]=img.Skip();
00063 strides[res]=skips[res]+widths[res];
00064
00065 ASSERT(static_cast<unsigned int>(img.Width())==getWidth(res),"Widths don't agree for layer "<<res);
00066 ASSERT(static_cast<unsigned int>(img.Height())==getHeight(res),"Heights don't agree for layer "<<res);
00067 }
00068 if(widths[numLayers-2]*2!=widths[numLayers-1] || heights[numLayers-2]*2!=heights[numLayers-1]) {
00069
00070
00071
00072 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]);
00073 freeCaches();
00074 dimchange=true;
00075 } else if(strides[numLayers-1]==0) {
00076
00077 dimchange=true;
00078 }
00079 if(dimchange)
00080 setDimensions();
00081 float testaspect=widths[numLayers-2]/(float)heights[numLayers-2];
00082 if(fabs(testaspect-config->vision.aspectRatio)>FLT_EPSILON) {
00083 serr->printf("WARNING: the image aspect ratio changed, was %g, now %g (diff %g)\n",*config->vision.aspectRatio,testaspect,testaspect-*config->vision.aspectRatio);
00084 config->vision.aspectRatio=testaspect;
00085 }
00086
00087 invalidateCaches();
00088 framesProcessed++;
00089 }
00090 erouter->postEvent(FilterBankEvent(this,getGeneratorID(),getSourceID(),event->getTypeID()));
00091 }
00092
00093 unsigned int
00094 RawCameraGenerator::getBinSize() const {
00095 unsigned int used=FilterBankGenerator::getBinSize();
00096 used+=strlen("RawImage")+LoadSave::stringpad;
00097 used+=widths[selectedSaveLayer]*heights[selectedSaveLayer];
00098 return used;
00099 }
00100
00101 unsigned int
00102 RawCameraGenerator::loadBuffer(const char buf[], unsigned int len, const char* filename) {
00103 unsigned int origlen=len;
00104 std::string tmp;
00105 if(!checkInc(FilterBankGenerator::loadBuffer(buf,len,filename),buf,len)) return 0;
00106 if(!decodeInc(tmp,buf,len)) return 0;
00107 if(tmp!="RawImage") {
00108 serr->printf("Unhandled image type for RawCameraGenerator: %s",tmp.c_str());
00109 return 0;
00110 } else if(selectedSaveLayer!=numLayers-1) {
00111 serr->printf("Can't load into RawCameraGenerator layer %d!=%d",selectedSaveLayer,numLayers-1);
00112 return 0;
00113 } else {
00114 if(images[selectedSaveLayer][selectedSaveChannel]==NULL)
00115 images[selectedSaveLayer][selectedSaveChannel]=createImageCache(selectedSaveLayer,selectedSaveChannel);
00116 unsigned char* img=images[selectedSaveLayer][selectedSaveChannel];
00117 unsigned int used=widths[selectedSaveLayer]*heights[selectedSaveLayer];
00118 ASSERTRETVAL(used<=len,"buffer too small",0);
00119 memcpy(img,buf,used);
00120 len-=used; buf+=used;
00121 imageValids[selectedSaveLayer][selectedSaveChannel]=true;
00122 return origlen-len;
00123 }
00124 }
00125
00126 unsigned int
00127 RawCameraGenerator::saveBuffer(char buf[], unsigned int len) const {
00128 unsigned int origlen=len;
00129 if(!checkInc(FilterBankGenerator::saveBuffer(buf,len),buf,len)) return 0;
00130 if(!encodeInc("RawImage",buf,len)) return 0;
00131
00132 if(images[selectedSaveLayer][selectedSaveChannel]==NULL) {
00133 serr->printf("RawCameraGenerator::saveBuffer() failed because selected image is NULL -- call selectSaveImage first to make sure it's up to date\n");
00134 return 0;
00135 }
00136 if(!imageValids[selectedSaveLayer][selectedSaveChannel]) {
00137 serr->printf("RawCameraGenerator::saveBuffer() failed because selected image is invalid -- call selectSaveImage first to make sure it's up to date\n");
00138 return 0;
00139 }
00140 unsigned char* img=images[selectedSaveLayer][selectedSaveChannel];
00141 unsigned int used=widths[selectedSaveLayer]*heights[selectedSaveLayer];
00142 ASSERTRETVAL(used<=len,"buffer too small",0);
00143 unsigned int inc=getIncrement(selectedSaveLayer);
00144 if(inc==1) {
00145
00146 for(unsigned int y=0; y<heights[selectedSaveLayer]; y++) {
00147 memcpy(buf,img,widths[selectedSaveLayer]);
00148 buf+=widths[selectedSaveLayer];
00149 img+=getStride(selectedSaveLayer);
00150 }
00151 } else {
00152
00153 for(unsigned int y=0; y<heights[selectedSaveLayer]; y++) {
00154 unsigned char* const rowend=img+widths[selectedSaveLayer]*inc;
00155 while(img!=rowend) {
00156 *buf++=*img;
00157 img+=inc;
00158 }
00159 img+=getSkip(selectedSaveLayer);
00160 }
00161 }
00162 len-=used;
00163
00164 return origlen-len;
00165 }
00166
00167 unsigned int
00168 RawCameraGenerator::saveFileStream(FILE * f) const {
00169 unsigned int totalused=0;
00170 unsigned int used;
00171 {
00172 unsigned int sz=FilterBankGenerator::getBinSize();
00173 char * buf = new char[sz];
00174 memset(buf,0xF0,sz);
00175 if(buf==NULL) {
00176 std::cout << "*** WARNING could not allocate " << sz << " bytes for loadFile";
00177 return 0;
00178 }
00179 unsigned int resp=FilterBankGenerator::saveBuffer(buf,sz);
00180 if(resp==0) {
00181 std::cout << "*** WARNING saveBuffer didn't write any data (possibly due to overflow or other error)" << std::endl;
00182 fwrite(buf,1,sz,f);
00183 } else {
00184 unsigned int wrote=fwrite(buf,1,resp,f);
00185 if(wrote!=resp)
00186 std::cout << "*** WARNING short write (wrote " << wrote << ", expected " << resp << ")" << std::endl;
00187 }
00188 delete [] buf;
00189 used=resp;
00190 }
00191 if(0==used) return 0;
00192 totalused+=used;
00193 if(0==(used=encode("RawImage",f))) return 0;
00194 totalused+=used;
00195
00196 if(images[selectedSaveLayer][selectedSaveChannel]==NULL) {
00197 serr->printf("RawCameraGenerator::saveBuffer() failed because selected image is NULL -- call selectSaveImage first to make sure it's up to date\n");
00198 return 0;
00199 }
00200 if(!imageValids[selectedSaveLayer][selectedSaveChannel]) {
00201 serr->printf("RawCameraGenerator::saveBuffer() failed because selected image is invalid -- call selectSaveImage first to make sure it's up to date\n");
00202 return 0;
00203 }
00204 unsigned char* img=images[selectedSaveLayer][selectedSaveChannel];
00205 used=widths[selectedSaveLayer]*heights[selectedSaveLayer];
00206 unsigned int inc=getIncrement(selectedSaveLayer);
00207 if(inc==1) {
00208
00209 sout->printf("Saving %d by %d\n",widths[selectedSaveLayer],heights[selectedSaveLayer]);
00210 for(unsigned int y=0; y<heights[selectedSaveLayer]; y++) {
00211 if(fwrite(img,widths[selectedSaveLayer],1,f)==0) {
00212 serr->printf("short write on image data - ran out of space?\n");
00213 return 0;
00214 }
00215 img+=getStride(selectedSaveLayer);
00216 }
00217 } else {
00218
00219 for(unsigned int y=0; y<heights[selectedSaveLayer]; y++) {
00220 unsigned char* const rowend=img+widths[selectedSaveLayer]*inc;
00221 while(img!=rowend) {
00222 if(fputc(*img,f)==EOF) {
00223 serr->printf("short write on image data - ran out of space?\n");
00224 return 0;
00225 }
00226 img+=inc;
00227 }
00228 img+=getSkip(selectedSaveLayer);
00229 }
00230 }
00231 totalused+=used;
00232
00233 return totalused;
00234 }
00235
00236 void
00237 RawCameraGenerator::setDimensions() {
00238 freeCaches();
00239 unsigned int numNotRealLayers=numLayers-1-numRealLayers;
00240 for(unsigned int res=0; res<numNotRealLayers; res++) {
00241 widths[res] = imageInfos[numNotRealLayers]->width>>(numNotRealLayers-res);
00242 heights[res] = imageInfos[numNotRealLayers]->height>>(numNotRealLayers-res);
00243 ASSERT(widths[res]*increments[res]==widths[numNotRealLayers],"widths*increments doesn't match total width");
00244 strides[res]=strides[numNotRealLayers]*increments[res];
00245 skips[res]=skips[numNotRealLayers]+strides[res]-strides[numNotRealLayers];
00246 }
00247 strides[numLayers-1]=widths[numLayers-1]=widths[numLayers-2]*2;
00248 heights[numLayers-1]=heights[numLayers-2]*2;
00249 }
00250
00251 void
00252 RawCameraGenerator::freeCaches() {
00253 #ifdef PLATFORM_APERIOS
00254 const unsigned int numRefLayers=numLayers;
00255 #else
00256 const unsigned int numRefLayers=numLayers-1;
00257 #endif
00258 for(unsigned int i=0; i<numRefLayers; i++) {
00259 for(unsigned int j=0; j<numChannels; j++) {
00260 images[i][j]=NULL;
00261 imageValids[i][j]=false;
00262 }
00263 }
00264 FilterBankGenerator::freeCaches();
00265 }
00266
00267 void
00268 RawCameraGenerator::setNumImages(unsigned int nLayers, unsigned int nChannels) {
00269 if(nLayers==numLayers && nChannels==numChannels)
00270 return;
00271 FilterBankGenerator::setNumImages(nLayers,nChannels);
00272 layers=new unsigned char*[numLayers];
00273 imageInfos=new const OFbkImageInfo*[numLayers];
00274 unsigned int numNotRealLayers=numLayers-1-numRealLayers;
00275 for(unsigned int res=0; res<numLayers; res++) {
00276 layers[res]=NULL;
00277 imageInfos[res]=NULL;
00278 if(res<numNotRealLayers)
00279 increments[res]=1<<(numNotRealLayers-res);
00280 }
00281 }
00282
00283 unsigned char *
00284 RawCameraGenerator::createImageCache(unsigned int layer, unsigned int chan) const {
00285 if(layer==numLayers-1) {
00286 #ifdef PLATFORM_APERIOS
00287 return const_cast<unsigned char*>(&dblRes[chan][0][0]);
00288 #else
00289 return new unsigned char[widths[layer]*heights[layer]];
00290 #endif
00291 } else
00292 return NULL;
00293 }
00294
00295 void
00296 RawCameraGenerator::calcImage(unsigned int layer, unsigned int chan) {
00297 PROFSECTION("RawCameraGenerator::calcImage(...)",*mainProfiler);
00298 unsigned int numNotRealLayers=numLayers-1-numRealLayers;
00299 if(layer==numLayers-1) {
00300
00301 if(chan==CHAN_Y)
00302 reconstructImage();
00303 else
00304 upsampleImage(static_cast<channel_id_t>(chan));
00305 } else {
00306 if(layer>=numNotRealLayers) {
00307 unsigned int fbkdatChan=mapChannelID(static_cast<channel_id_t>(chan));
00308 const OFbkImage img(const_cast<OFbkImageInfo*>(imageInfos[layer]), const_cast<unsigned char*>(layers[layer]), fbkdatChan);
00309 images[layer][chan]=img.Pointer();
00310
00311
00312
00313
00314 if(config->vision.restore_image) {
00315 const unsigned int numPix=16;
00316 if(layer==numLayers-2) {
00317 unsigned char * s=images[layer][chan]+getStride(layer)*(getHeight(layer)-2);
00318 unsigned char * d=images[layer][chan]+getStride(layer)*(getHeight(layer)-1);
00319 for(unsigned int i=0; i<numPix; i++)
00320 *d++=*s++;
00321 } else {
00322 unsigned int inc=1<<(numLayers-2-layer);
00323 unsigned char * s;
00324
00325
00326 if(!imageValids[numLayers-2][chan]) {
00327 const OFbkImage simg(const_cast<OFbkImageInfo*>(imageInfos[numLayers-2]), const_cast<unsigned char*>(layers[numLayers-2]), fbkdatChan);
00328 s=simg.Pointer();
00329 } else {
00330 s=images[numLayers-2][chan];
00331 }
00332 s+=getStride(numLayers-2)*(getHeight(numLayers-2)-inc);
00333 unsigned char * d=images[layer][chan]+getStride(layer)*(getHeight(layer)-1);
00334 for(unsigned int i=0; i<numPix; i++) {
00335 *d++=*s;
00336 s+=inc;
00337 }
00338 }
00339 }
00340 } else {
00341
00342
00343 unsigned int fbkdatChan=mapChannelID(static_cast<channel_id_t>(chan));
00344 const OFbkImage img(const_cast<OFbkImageInfo*>(imageInfos[numNotRealLayers]), const_cast<unsigned char*>(layers[numNotRealLayers]), fbkdatChan);
00345 images[layer][chan]=img.Pointer();
00346 }
00347 }
00348 imageValids[layer][chan]=true;
00349 }
00350
00351 void
00352 RawCameraGenerator::destruct() {
00353 FilterBankGenerator::destruct();
00354 delete [] layers;
00355 layers=NULL;
00356 delete [] imageInfos;
00357 imageInfos=NULL;
00358 }
00359
00360 unsigned int
00361 RawCameraGenerator::mapChannelID(channel_id_t chan) {
00362 switch(chan) {
00363 case CHAN_Y:
00364 return ofbkimageBAND_Y;
00365 case CHAN_U:
00366 return ofbkimageBAND_Cb;
00367 case CHAN_V:
00368 return ofbkimageBAND_Cr;
00369 case CHAN_Y_DY:
00370 return ofbkimageBAND_Y_LH;
00371 case CHAN_Y_DX:
00372 return ofbkimageBAND_Y_HL;
00373 case CHAN_Y_DXDY:
00374 return ofbkimageBAND_Y_HH;
00375 default:
00376 std::cout << "RawCameraGenerator::mapChannelID bad channel" << std::endl;
00377 return ofbkimageBAND_Y;;
00378 }
00379 }
00380
00381 void
00382 RawCameraGenerator::upsampleImage(channel_id_t chan) {
00383 const unsigned int dblLayer=numLayers-1;
00384 const unsigned int srcLayer=dblLayer-1;
00385 const unsigned int width=widths[dblLayer];
00386 const unsigned int height=heights[dblLayer];
00387
00388 unsigned char * cur=images[dblLayer][chan];
00389 ASSERTRET(cur!=NULL,"destination layer is NULL");
00390 unsigned char * orig=getImage(srcLayer,chan);
00391 ASSERTRET(orig!=NULL,"source layer is NULL");
00392
00393 unsigned char * const imgend=cur+width*height;
00394 while(cur!=imgend) {
00395 unsigned char * const row=cur;
00396 unsigned char * const rowend=cur+width;
00397 while(cur!=rowend) {
00398 *cur++=*orig;
00399 *cur++=*orig++;
00400 }
00401 memcpy(cur,row,width);
00402 cur+=width;
00403 orig+=getSkip(srcLayer);
00404 }
00405 }
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422 void
00423 RawCameraGenerator::reconstructImage() {
00424 byte* yLLPtr = getImage(numLayers-2,CHAN_Y);
00425 byte* yLHPtr = getImage(numLayers-2,CHAN_Y_DY);
00426 byte* yHLPtr = getImage(numLayers-2,CHAN_Y_DX);
00427 byte* yHHPtr = getImage(numLayers-2,CHAN_Y_DXDY);
00428
00429 unsigned int w = getWidth(numLayers-2);
00430 unsigned int h = getWidth(numLayers-2);
00431 unsigned int skip = getSkip(numLayers-2);
00432
00433 unsigned char* img = images[numLayers-1][CHAN_Y];
00434 ASSERTRET(img!=NULL,"image destination NULL");
00435
00436 unsigned char* iptr0 = img;
00437 unsigned char* iptr1 = iptr0 + 2*w;
00438
00439 for (unsigned int y = 0; y < h; y++) {
00440 for (unsigned int x = 0; x < w; x++) {
00441
00442
00443
00444 short yLL = (short)*yLLPtr++;
00445 short yLH = (short)*yLHPtr++ - 128;
00446 short yHL = (short)*yHLPtr++ - 128;
00447 short yHH = (short)*yHHPtr++ - 128;
00448
00449 short a = yLL + yLH + yHL + yHH;
00450 short b = 2 * (yLL + yLH);
00451 short c = 2 * (yLL + yHL);
00452 short d = 2 * (yLL + yHH);
00453
00454 *iptr0++ = clipRange(d - a);
00455 *iptr0++ = clipRange(c - a);
00456 *iptr1++ = clipRange(b - a);
00457 *iptr1++ = clipRange(a);
00458 }
00459 yLLPtr += skip;
00460 yLHPtr += skip;
00461 yHLPtr += skip;
00462 yHHPtr += skip;
00463 iptr0 = iptr1;
00464 iptr1 += 2*w;
00465 }
00466 }
00467
00468
00469
00470
00471
00472
00473