Homepage Demos Overview Downloads Tutorials Reference
Credits

RawCameraGenerator.cc

Go to the documentation of this file.
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/WorldState.h"
00008 
00009 #include <OPENR/ODataFormats.h>
00010 #include <OPENR/OFbkImage.h>
00011 
00012 #include "Shared/debuget.h"
00013 
00014 RawCameraGenerator::RawCameraGenerator(unsigned int numRawLayers, unsigned int numCalcLayers, EventBase::EventGeneratorID_t gid, unsigned int sid, unsigned int mysid)
00015   : FilterBankGenerator("RawCameraGenerator",numCalcLayers,NUM_CHANNELS,gid,sid,EventBase::visRawCameraEGID,mysid), numRealLayers(numRawLayers), layers(NULL), imageInfos(NULL)
00016 {
00017   setNumImages(numLayers,numChannels);
00018 }
00019 
00020 RawCameraGenerator::~RawCameraGenerator() {
00021   freeCaches();
00022   destruct();
00023 }
00024 
00025 /*! The const casts in this function are regretable but necessary
00026  *  since the OPEN-R OFbkImage constructor requires mutable
00027  *  arguments, even though it shouldn't be modifying the data
00028  */
00029 void
00030 RawCameraGenerator::processEvent(const EventBase& event) {
00031   typedef DataEvent<const OFbkImageVectorData*> OFbkEvent;
00032   const OFbkEvent& fbkevent=dynamic_cast<const OFbkEvent& >(event);
00033   OFbkImageVectorData& fbkdat=*const_cast<OFbkImageVectorData*>(fbkevent.getData());
00034   for(unsigned int res=0; res<numRealLayers; res++) {
00035     layers[numLayers-2-res] = fbkdat.GetData(res);
00036     imageInfos[numLayers-2-res] = fbkdat.GetInfo(res);
00037   }
00038   {
00039     const OFbkImage img(const_cast<OFbkImageInfo*>(imageInfos[numLayers-2]), const_cast<unsigned char*>(layers[numLayers-2]), ofbkimageBAND_Y);
00040     //I have to do this crazy thing because apparently img.FieldCounter() doesn't work
00041     frameNumber=*(int*)(img.Pointer()+(img.Height()-1)*(img.Skip()+img.Width()));
00042   }
00043   unsigned int numNotRealLayers=numLayers-1-numRealLayers;
00044   for(unsigned int res=numNotRealLayers; res<numLayers-1; res++) {
00045     widths[res] = imageInfos[res]->width;
00046     heights[res] = imageInfos[res]->height;
00047 
00048     const OFbkImage img(const_cast<OFbkImageInfo*>(imageInfos[res]), const_cast<unsigned char*>(layers[res]), ofbkimageBAND_Y);
00049     skips[res]=img.Skip();
00050     strides[res]=skips[res]+widths[res];
00051 
00052     ASSERT(static_cast<unsigned int>(img.Width())==getWidth(res),"Widths don't match");
00053     ASSERT(static_cast<unsigned int>(img.Height())==getHeight(res),"Heights don't match");
00054   }
00055   if(widths[numLayers-2]*2!=widths[numLayers-1] || heights[numLayers-2]*2!=heights[numLayers-1]) {
00056     //|| widths[numLayers-2-numRealLayers]*2!=widths[numNotRealLayers]
00057     //|| heights[numLayers-2-numRealLayers]*2!=heights[numNotRealLayers]) {
00058     //set the width and height of non-real layers (since they don't match what they should be)
00059     ASSERT(widths[numLayers-1]==0,"Strange, the image width changed after initial setting" << widths[numLayers-1]);
00060     setDimensions();
00061   }
00062 
00063   invalidateCaches(); 
00064   framesProcessed++;
00065   erouter->postEvent(new FilterBankEvent(this,getGeneratorID(),getSourceID()));
00066 }
00067 
00068 unsigned int
00069 RawCameraGenerator::getBinSize() const {
00070   unsigned int used=FilterBankGenerator::getBinSize();
00071   used+=strlen("RawImage")+LoadSave::stringpad;
00072   used+=widths[selectedSaveLayer]*heights[selectedSaveLayer];
00073   return used;
00074 }
00075 
00076 unsigned int
00077 RawCameraGenerator::LoadBuffer(const char buf[], unsigned int len) {
00078   unsigned int origlen=len;
00079   unsigned int used;
00080   std::string tmp;
00081   if(0==(used=FilterBankGenerator::LoadBuffer(buf,len))) return 0;
00082   len-=used; buf+=used;
00083   if(0==(used=decode(tmp,buf,len))) return 0;
00084   len-=used; buf+=used;
00085   if(tmp!="RawImage") {
00086     serr->printf("Unhandled image type for RawCameraGenerator: %s",tmp.c_str());
00087     return 0;
00088   } else if(selectedSaveLayer!=numLayers-1) {
00089     serr->printf("Can't load into RawCameraGenerator layer %d!=%d",selectedSaveLayer,numLayers-1);
00090     return 0;
00091   } else {
00092     if(images[selectedSaveLayer][selectedSaveChannel]==NULL)
00093       images[selectedSaveLayer][selectedSaveChannel]=createImageCache(selectedSaveLayer,selectedSaveChannel);
00094     unsigned char* img=images[selectedSaveLayer][selectedSaveChannel];
00095     used=widths[selectedSaveLayer]*heights[selectedSaveLayer];
00096     ASSERTRETVAL(used<=len,"buffer too small",0);
00097     memcpy(img,buf,used);
00098     len-=used; buf+=used;
00099     imageValids[selectedSaveLayer][selectedSaveChannel]=true;
00100     return origlen-len; 
00101   }
00102 }
00103 
00104 unsigned int
00105 RawCameraGenerator::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   if(0==(used=encode("RawImage",buf,len))) return 0;
00111   len-=used; buf+=used;
00112   
00113   unsigned char* img=getImage(selectedSaveLayer,selectedSaveChannel);
00114   used=widths[selectedSaveLayer]*heights[selectedSaveLayer];
00115   ASSERTRETVAL(used<=len,"buffer too small",0);
00116   unsigned int inc=getIncrement(selectedSaveLayer);
00117   if(inc==1) {
00118     //special case, straight copy
00119     for(unsigned int y=0; y<heights[selectedSaveLayer]; y++) {
00120       memcpy(buf,img,widths[selectedSaveLayer]);
00121       buf+=widths[selectedSaveLayer];
00122       img+=getStride(selectedSaveLayer);
00123     }
00124   } else {
00125     //otherwise, interleaved or subsampling
00126     for(unsigned int y=0; y<heights[selectedSaveLayer]; y++) {
00127       unsigned char* const rowend=img+widths[selectedSaveLayer]*inc;
00128       while(img!=rowend) {
00129         *buf++=*img;
00130         img+=inc;
00131       }
00132       img+=getSkip(selectedSaveLayer);
00133     }
00134   }
00135   len-=used;
00136   
00137   return origlen-len;
00138 }
00139 
00140 unsigned int
00141 RawCameraGenerator::SaveFileStream(FILE * f) const {
00142   unsigned int totalused=0;
00143   unsigned int used;
00144   { //sigh, inheritance has failed me (I wouldn't want FilterBankGenerator::SaveFileStream() to call the virtuals...)
00145     unsigned int sz=FilterBankGenerator::getBinSize();
00146     char * buf = new char[sz];
00147     memset(buf,0xF0,sz);
00148     if(buf==NULL) {
00149       std::cout << "*** WARNING could not allocate " << sz << " bytes for LoadFile";
00150       return 0;
00151     }
00152     unsigned int resp=FilterBankGenerator::SaveBuffer(buf,sz);
00153     if(resp==0) {
00154       std::cout << "*** WARNING SaveBuffer didn't write any data (possibly due to overflow or other error)" << std::endl;
00155       fwrite(buf,1,sz,f);
00156     } else {
00157       unsigned int wrote=fwrite(buf,1,resp,f);
00158       if(wrote!=resp)
00159         std::cout << "*** WARNING short write (wrote " << wrote << ", expected " << resp << ")" << std::endl;
00160     }
00161     delete [] buf;
00162     used=resp;
00163   }
00164   if(0==used) return 0;
00165   totalused+=used;
00166   if(0==(used=encode("RawImage",f))) return 0;
00167   totalused+=used;
00168   
00169   unsigned char* img=getImage(selectedSaveLayer,selectedSaveChannel);
00170   used=widths[selectedSaveLayer]*heights[selectedSaveLayer];
00171   unsigned int inc=getIncrement(selectedSaveLayer);
00172   if(inc==1) {
00173     //special case, straight copy
00174     sout->printf("Saving %d by %d\n",widths[selectedSaveLayer],heights[selectedSaveLayer]);
00175     for(unsigned int y=0; y<heights[selectedSaveLayer]; y++) {
00176       if(fwrite(img,widths[selectedSaveLayer],1,f)==0) {
00177         serr->printf("short write on image data - ran out of space?\n");
00178         return 0;
00179       }
00180       img+=getStride(selectedSaveLayer);
00181     }
00182   } else {
00183     //otherwise, interleaved or subsampling
00184     for(unsigned int y=0; y<heights[selectedSaveLayer]; y++) {
00185       unsigned char* const rowend=img+widths[selectedSaveLayer]*inc;
00186       while(img!=rowend) {
00187         if(fputc(*img,f)==EOF) {
00188           serr->printf("short write on image data - ran out of space?\n");
00189           return 0;
00190         }
00191         img+=inc;
00192       }
00193       img+=getSkip(selectedSaveLayer);
00194     }
00195   }
00196   totalused+=used;
00197   
00198   return totalused;
00199 }
00200 
00201 void
00202 RawCameraGenerator::setDimensions() {
00203   freeCaches();
00204   unsigned int numNotRealLayers=numLayers-1-numRealLayers;
00205   for(unsigned int res=0; res<numNotRealLayers; res++) {
00206     widths[res] = imageInfos[numNotRealLayers]->width>>(numNotRealLayers-res);
00207     heights[res] = imageInfos[numNotRealLayers]->height>>(numNotRealLayers-res);
00208     ASSERT(widths[res]*increments[res]==widths[numNotRealLayers],"widths*increments doesn't match total width");
00209     strides[res]=strides[numNotRealLayers]*increments[res];
00210     skips[res]=skips[numNotRealLayers]+strides[res]-strides[numNotRealLayers];
00211   }
00212   strides[numLayers-1]=widths[numLayers-1]=widths[numLayers-2]*2;
00213   heights[numLayers-1]=heights[numLayers-2]*2;
00214 }
00215 
00216 void 
00217 RawCameraGenerator::freeCaches() {
00218   for(unsigned int i=0; i<numLayers; i++) {
00219     for(unsigned int j=0; j<numChannels; j++) {
00220       images[i][j]=NULL;
00221       imageValids[i][j]=false;
00222     }
00223   }
00224   FilterBankGenerator::freeCaches();
00225 }
00226 
00227 void
00228 RawCameraGenerator::setNumImages(unsigned int nLayers, unsigned int nChannels) {
00229   FilterBankGenerator::setNumImages(nLayers,nChannels);
00230   layers=new unsigned char*[numLayers];
00231   imageInfos=new const OFbkImageInfo*[numLayers];
00232   unsigned int numNotRealLayers=numLayers-1-numRealLayers;
00233   for(unsigned int res=0; res<numLayers; res++) {
00234     layers[res]=NULL;
00235     imageInfos[res]=NULL;
00236     if(res<numNotRealLayers)
00237       increments[res]=1<<(numNotRealLayers-res);
00238   }
00239 }
00240 
00241 unsigned char *
00242 RawCameraGenerator::createImageCache(unsigned int layer, unsigned int chan) const {
00243   if(layer==numLayers-1) {
00244     return const_cast<unsigned char*>(&dblRes[chan][0][0]);
00245   } else
00246     return NULL; // calcImage will set the cache itself
00247 }
00248 
00249 void
00250 RawCameraGenerator::calcImage(unsigned int layer, unsigned int chan) const {
00251   PROFSECTION("RawCameraGenerator::calcImage(...)",state->mainProfile);
00252   unsigned int numNotRealLayers=numLayers-1-numRealLayers;
00253   if(layer==numLayers-1) {
00254     //This is the only layer for which we calculate and store any data of our own...
00255     if(chan==CHAN_Y)
00256       reconstructImage();
00257     else
00258       upsampleImage(static_cast<channel_id_t>(chan));
00259   } else {
00260     if(layer>=numNotRealLayers) {
00261       unsigned int fbkdatChan=mapChannelID(static_cast<channel_id_t>(chan));
00262       const OFbkImage img(const_cast<OFbkImageInfo*>(imageInfos[layer]), const_cast<unsigned char*>(layers[layer]), fbkdatChan);
00263       images[layer][chan]=img.Pointer();
00264 
00265       //this part restores pixels over written with the CDT table and
00266       //frame count.  Yes, we are modifying the original image passed
00267       //from the system here...
00268       if(config->vision.restore_image) {
00269         const unsigned int numPix=16;
00270         if(layer==numLayers-2) {
00271           unsigned char * s=images[layer][chan]+getStride(layer)*(getHeight(layer)-2);
00272           unsigned char * d=images[layer][chan]+getStride(layer)*(getHeight(layer)-1);
00273           for(unsigned int i=0; i<numPix; i++)
00274             *d++=*s++;
00275         } else {
00276           unsigned int inc=1<<(numLayers-2-layer);
00277           unsigned char * s;
00278           //unsigned char * s=getImage(numLayers-2,chan)+getStride(numLayers-2)*(getHeight(numLayers-2)-inc);
00279           //...or an attempt to possibly avoid a trivial amount of recomputation....
00280           if(!imageValids[numLayers-2][chan]) {
00281             const OFbkImage simg(const_cast<OFbkImageInfo*>(imageInfos[numLayers-2]), const_cast<unsigned char*>(layers[numLayers-2]), fbkdatChan);
00282             s=simg.Pointer();
00283           } else {
00284             s=images[numLayers-2][chan];
00285           }
00286           s+=getStride(numLayers-2)*(getHeight(numLayers-2)-inc);
00287           unsigned char * d=images[layer][chan]+getStride(layer)*(getHeight(layer)-1);
00288           for(unsigned int i=0; i<numPix; i++) {
00289             *d++=*s;
00290             s+=inc;
00291           }
00292         }
00293       }
00294     } else {
00295       //we don't need to do the restoration in the previous section
00296       //here because these layers skip the last row
00297       unsigned int fbkdatChan=mapChannelID(static_cast<channel_id_t>(chan));
00298       const OFbkImage img(const_cast<OFbkImageInfo*>(imageInfos[numNotRealLayers]), const_cast<unsigned char*>(layers[numNotRealLayers]), fbkdatChan);
00299       images[layer][chan]=img.Pointer();
00300     }
00301   }
00302   imageValids[layer][chan]=true;
00303 }
00304 
00305 void
00306 RawCameraGenerator::destruct() {
00307   FilterBankGenerator::destruct();
00308   delete [] layers;
00309   layers=NULL;
00310   delete [] imageInfos;
00311   imageInfos=NULL;
00312 }
00313 
00314 unsigned int
00315 RawCameraGenerator::mapChannelID(channel_id_t chan) {
00316   switch(chan) {
00317   case CHAN_Y:
00318     return ofbkimageBAND_Y;
00319   case CHAN_U:
00320     return ofbkimageBAND_Cr;
00321   case CHAN_V:
00322     return ofbkimageBAND_Cb;
00323   case CHAN_Y_DY:
00324     return ofbkimageBAND_Y_LH;
00325   case CHAN_Y_DX:
00326     return ofbkimageBAND_Y_HL;
00327   case CHAN_Y_DXDY:
00328     return ofbkimageBAND_Y_HH;
00329   default:
00330     std::cout << "RawCameraGenerator::mapChannelID bad channel" << std::endl;
00331     return ofbkimageBAND_Y;;
00332   }
00333 }
00334 
00335 void
00336 RawCameraGenerator::upsampleImage(channel_id_t chan) const {
00337   const unsigned int dblLayer=numLayers-1;
00338   const unsigned int srcLayer=dblLayer-1;
00339   const unsigned int width=widths[dblLayer];
00340   const unsigned int height=heights[dblLayer];
00341 
00342   unsigned char * cur=images[dblLayer][chan];
00343   ASSERTRET(cur!=NULL,"destination layer is NULL");
00344   unsigned char * src=getImage(srcLayer,chan);
00345   ASSERTRET(cur!=NULL,"source layer is NULL");
00346 
00347   unsigned char * const imgend=cur+width*height;
00348   while(cur!=imgend) {
00349     unsigned char * const row=cur;
00350     unsigned char * const rowend=cur+width;
00351     while(cur!=rowend) {
00352       *cur++=*src;
00353       *cur++=*src++;
00354     }
00355     memcpy(cur,row,width);
00356     cur+=width;
00357     src+=getSkip(srcLayer);
00358   }
00359 }
00360 
00361 
00362 
00363 /*! This function is lifted from Sony's ImageObserver sample code.
00364     Here's Sony's original license for the file (ImageObserver.cc) that contained this function:
00365     <pre>
00366     Copyright 2002,2003 Sony Corporation 
00367     
00368     Permission to use, copy, modify, and redistribute this software for
00369     non-commercial use is hereby granted.
00370     
00371     This software is provided "as is" without warranty of any kind,
00372     either expressed or implied, including but not limited to the
00373     implied warranties of fitness for a particular purpose.
00374     </pre>
00375 */
00376 void
00377 RawCameraGenerator::reconstructImage() const {
00378   byte* yLLPtr = getImage(numLayers-2,CHAN_Y);
00379   byte* yLHPtr = getImage(numLayers-2,CHAN_Y_DY);
00380   byte* yHLPtr = getImage(numLayers-2,CHAN_Y_DX);
00381   byte* yHHPtr = getImage(numLayers-2,CHAN_Y_DXDY);
00382   
00383   unsigned int w = getWidth(numLayers-2);
00384   unsigned int h = getWidth(numLayers-2);
00385   unsigned int skip = getSkip(numLayers-2);
00386   
00387   unsigned char* img = images[numLayers-1][CHAN_Y];
00388   ASSERTRET(img!=NULL,"image destination NULL");
00389 
00390   unsigned char* iptr0 = img;
00391   unsigned char* iptr1 = iptr0 + 2*w;
00392     
00393   for (unsigned int y = 0; y < h; y++) {
00394     for (unsigned int x = 0; x < w; x++) {
00395       //
00396       // yLH, yHL, yHH : offset binary [0, 255] -> signed int [-128, 127]
00397       //
00398       short yLL = (short)*yLLPtr++;
00399       short yLH = (short)*yLHPtr++ - 128;
00400       short yHL = (short)*yHLPtr++ - 128;
00401       short yHH = (short)*yHHPtr++ - 128;
00402 
00403       short a = yLL + yLH + yHL + yHH; // ypix11
00404       short b = 2 * (yLL + yLH);       // ypix11 + ypix01
00405       short c = 2 * (yLL + yHL);       // ypix11 + ypix10
00406       short d = 2 * (yLL + yHH);       // ypix11 + ypix00
00407             
00408       *iptr0++ = clipRange(d - a);
00409       *iptr0++ = clipRange(c - a);
00410       *iptr1++ = clipRange(b - a);
00411       *iptr1++ = clipRange(a);
00412     }
00413     yLLPtr += skip;
00414     yLHPtr += skip;
00415     yHLPtr += skip;
00416     yHHPtr += skip;
00417     iptr0  = iptr1;
00418     iptr1  += 2*w;
00419   }
00420 }
00421 
00422 
00423 /*! @file
00424  * @brief Implements RawCameraGenerator, which generates FilterBankEvents containing raw camera images
00425  * @author ejt (Creator)
00426  *
00427  * $Author: ejt $
00428  * $Name: tekkotsu-2_0_1+Doc $
00429  * $Revision: 1.14 $
00430  * $State: Exp $
00431  * $Date: 2004/02/06 00:06:31 $
00432  */
00433 

Tekkotsu v2.0.1+Doc
Generated Mon Feb 9 22:16:49 2004 by Doxygen 1.3.5