00001 #ifndef PLATFORM_APERIOS
00002
00003 #include "BufferedImageGenerator.h"
00004 #include "Events/DataEvent.h"
00005 #include "Events/FilterBankEvent.h"
00006 #include "Wireless/Socket.h"
00007 #include "Events/EventRouter.h"
00008 #include "Shared/debuget.h"
00009 #include "Shared/ProjectInterface.h"
00010
00011 using namespace std;
00012
00013 void BufferedImageGenerator::processEvent(const EventBase & event) {
00014 EventGeneratorBase::processEvent(event);
00015 if(event.getGeneratorID()!=getListenGeneratorID() || event.getSourceID()!=getListenSourceID())
00016 return;
00017 if(event.getTypeID()==EventBase::activateETID) {
00018 const DataEvent<ImageSource>* data=dynamic_cast<const DataEvent<ImageSource>*>(&event);
00019 if(data==NULL) {
00020 serr->printf("Error: %s(%s) received event of the wrong type",getClassName().c_str(),getName().c_str());
00021 return;
00022 }
00023 if(imgsrc.layer!=data->getData().layer || imgsrc.channels!=data->getData().channels) {
00024
00025
00026 unsigned int i;
00027 for(i=0; i<data->getData().layer; i++) {
00028 increments[i] = 1;
00029 strides[i]=data->getData().width>>(data->getData().layer-i);
00030 skips[i]=0;
00031 }
00032 increments[i] = data->getData().channels;
00033 strides[i]=data->getData().width*data->getData().channels;
00034 skips[i]=0;
00035 for(++i; i<numLayers; i++) {
00036 increments[i] = 1;
00037 strides[i]=data->getData().width<<(i-data->getData().layer);
00038 skips[i]=0;
00039 }
00040 }
00041 imgsrc=data->getData();
00042 sysFrameNumber=frameNumber=imgsrc.frameIndex;
00043 invalidateCaches();
00044 if(numLayers>0) {
00045
00046 if(imgsrc.width!=getWidth(imgsrc.layer) || imgsrc.height!=getHeight(imgsrc.layer)) {
00047 freeCaches();
00048 setDimensions();
00049 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]);
00050 } else if(strides[numLayers-1]==0) {
00051
00052 setDimensions();
00053 }
00054 }
00055
00056 unsigned int i=imgsrc.layer;
00057 for(unsigned int j=0; j<imgsrc.channels; j++) {
00058 if(isAllocated[i][j]) {
00059 delete [] images[i][j];
00060 images[i][j]=NULL;
00061 isAllocated[i][j]=false;
00062 }
00063 imageValids[i][j]=true;
00064 }
00065 images[i][RawCameraGenerator::CHAN_Y]=imgsrc.img+0;
00066 images[i][RawCameraGenerator::CHAN_U]=imgsrc.img+1;
00067 images[i][RawCameraGenerator::CHAN_V]=imgsrc.img+2;
00068 framesProcessed++;
00069 }
00070 erouter->postEvent(FilterBankEvent(this,getGeneratorID(),getSourceID(),event.getTypeID()));
00071 }
00072
00073 unsigned int
00074 BufferedImageGenerator::getBinSize() const {
00075 unsigned int used=FilterBankGenerator::getBinSize();
00076 used+=getSerializedSize("RawImage");
00077 used+=widths[selectedSaveLayer]*heights[selectedSaveLayer];
00078 return used;
00079 }
00080
00081 unsigned int
00082 BufferedImageGenerator::loadBuffer(const char buf[], unsigned int len) {
00083 unsigned int origlen=len;
00084 if(!checkInc(FilterBankGenerator::loadBuffer(buf,len),buf,len)) return 0;
00085 std::string tmp;
00086 if(decode(tmp,buf,len)) return 0;
00087 if(tmp!="RawImage") {
00088 serr->printf("Unhandled image type for BufferedImageGenerator: %s",tmp.c_str());
00089 return 0;
00090 } else if(selectedSaveLayer!=numLayers-1) {
00091 serr->printf("Can't load into BufferedImageGenerator layer %d!=%d",selectedSaveLayer,numLayers-1);
00092 return 0;
00093 } else {
00094 if(images[selectedSaveLayer][selectedSaveChannel]==NULL)
00095 images[selectedSaveLayer][selectedSaveChannel]=createImageCache(selectedSaveLayer,selectedSaveChannel);
00096 unsigned char* img=images[selectedSaveLayer][selectedSaveChannel];
00097 unsigned int used=widths[selectedSaveLayer]*heights[selectedSaveLayer];
00098 ASSERTRETVAL(used<=len,"buffer too small",0);
00099 memcpy(img,buf,used);
00100 len-=used; buf+=used;
00101 imageValids[selectedSaveLayer][selectedSaveChannel]=true;
00102 return origlen-len;
00103 }
00104 }
00105
00106 unsigned int
00107 BufferedImageGenerator::saveBuffer(char buf[], unsigned int len) const {
00108 unsigned int origlen=len;
00109 if(!checkInc(FilterBankGenerator::saveBuffer(buf,len),buf,len)) return 0;
00110 if(!encodeInc("RawImage",buf,len)) return 0;
00111
00112 if(images[selectedSaveLayer][selectedSaveChannel]==NULL) {
00113 serr->printf("BufferedImageGenerator::saveBuffer() failed because selected image is NULL -- call selectSaveImage first to make sure it's up to date\n");
00114 return 0;
00115 }
00116 if(!imageValids[selectedSaveLayer][selectedSaveChannel]) {
00117 serr->printf("BufferedImageGenerator::saveBuffer() failed because selected image is invalid -- call selectSaveImage first to make sure it's up to date\n");
00118 return 0;
00119 }
00120 unsigned char* img=images[selectedSaveLayer][selectedSaveChannel];
00121 unsigned int used=widths[selectedSaveLayer]*heights[selectedSaveLayer];
00122 ASSERTRETVAL(used<=len,"buffer too small",0);
00123 unsigned int inc=getIncrement(selectedSaveLayer);
00124 if(inc==1) {
00125
00126 for(unsigned int y=0; y<heights[selectedSaveLayer]; y++) {
00127 memcpy(buf,img,widths[selectedSaveLayer]);
00128 buf+=widths[selectedSaveLayer];
00129 img+=getStride(selectedSaveLayer);
00130 }
00131 } else {
00132
00133 for(unsigned int y=0; y<heights[selectedSaveLayer]; y++) {
00134 unsigned char* const rowend=img+widths[selectedSaveLayer]*inc;
00135 while(img!=rowend) {
00136 *buf++=*img;
00137 img+=inc;
00138 }
00139 img+=getSkip(selectedSaveLayer);
00140 }
00141 }
00142 len-=used;
00143
00144 return origlen-len;
00145 }
00146
00147 unsigned int
00148 BufferedImageGenerator::saveFileStream(FILE * f) const {
00149 unsigned int totalused=0;
00150 unsigned int used;
00151 {
00152 unsigned int sz=FilterBankGenerator::getBinSize();
00153 char * buf = new char[sz];
00154 memset(buf,0xF0,sz);
00155 if(buf==NULL) {
00156 std::cout << "*** WARNING could not allocate " << sz << " bytes for loadFile";
00157 return 0;
00158 }
00159 unsigned int resp=FilterBankGenerator::saveBuffer(buf,sz);
00160 if(resp==0) {
00161 std::cout << "*** WARNING saveBuffer didn't write any data (possibly due to overflow or other error)" << std::endl;
00162 fwrite(buf,1,sz,f);
00163 } else {
00164 unsigned int wrote=fwrite(buf,1,resp,f);
00165 if(wrote!=resp)
00166 std::cout << "*** WARNING short write (wrote " << wrote << ", expected " << resp << ")" << std::endl;
00167 }
00168 delete [] buf;
00169 used=resp;
00170 }
00171 if(0==used) return 0;
00172 totalused+=used;
00173 if(0==(used=encode("RawImage",f))) return 0;
00174 totalused+=used;
00175
00176 if(images[selectedSaveLayer][selectedSaveChannel]==NULL) {
00177 serr->printf("BufferedImageGenerator::saveBuffer() failed because selected image is NULL -- call selectSaveImage first to make sure it's up to date\n");
00178 return 0;
00179 }
00180 if(!imageValids[selectedSaveLayer][selectedSaveChannel]) {
00181 serr->printf("BufferedImageGenerator::saveBuffer() failed because selected image is invalid -- call selectSaveImage first to make sure it's up to date\n");
00182 return 0;
00183 }
00184 unsigned char* img=images[selectedSaveLayer][selectedSaveChannel];
00185 used=widths[selectedSaveLayer]*heights[selectedSaveLayer];
00186 unsigned int inc=getIncrement(selectedSaveLayer);
00187 if(inc==1) {
00188
00189 sout->printf("Saving %d by %d\n",widths[selectedSaveLayer],heights[selectedSaveLayer]);
00190 for(unsigned int y=0; y<heights[selectedSaveLayer]; y++) {
00191 if(fwrite(img,widths[selectedSaveLayer],1,f)==0) {
00192 serr->printf("short write on image data - ran out of space?\n");
00193 return 0;
00194 }
00195 img+=getStride(selectedSaveLayer);
00196 }
00197 } else {
00198
00199 for(unsigned int y=0; y<heights[selectedSaveLayer]; y++) {
00200 unsigned char* const rowend=img+widths[selectedSaveLayer]*inc;
00201 while(img!=rowend) {
00202 if(fputc(*img,f)==EOF) {
00203 serr->printf("short write on image data - ran out of space?\n");
00204 return 0;
00205 }
00206 img+=inc;
00207 }
00208 img+=getSkip(selectedSaveLayer);
00209 }
00210 }
00211 totalused+=used;
00212
00213 return totalused;
00214 }
00215
00216 void BufferedImageGenerator::freeCaches() {
00217 FilterBankGenerator::freeCaches();
00218 for(unsigned int i=0; i<numLayers; i++)
00219 for(unsigned int j=0; j<numChannels; j++)
00220 isAllocated[i][j]=false;
00221 }
00222
00223 void BufferedImageGenerator::invalidateCaches() {
00224 for(unsigned int i=0; i<numLayers; i++)
00225 for(unsigned int j=0; j<numChannels; j++) {
00226 if(!isAllocated[i][j])
00227 images[i][j]=NULL;
00228 imageValids[i][j]=false;
00229 }
00230 }
00231
00232 unsigned char * BufferedImageGenerator::createImageCache(unsigned int layer, unsigned int channel) const {
00233 if(layer!=imgsrc.layer || imgsrc.channels==1) {
00234 isAllocated[layer][channel]=true;
00235 return new unsigned char[widths[layer]*heights[layer]];
00236 } else {
00237 ASSERT(channel>=imgsrc.channels,"createImageCache for image that should come from src")
00238
00239 unsigned int base=(channel/imgsrc.channels)*imgsrc.channels;
00240 if(images[layer][base]==NULL)
00241 images[layer][base]=new unsigned char[widths[layer]*heights[layer]*imgsrc.channels];
00242 for(unsigned int i=base+1; i<base+imgsrc.channels; ++i) {
00243 ASSERT(!isAllocated[layer][i],"createImageCache for image already allocated!");
00244 ASSERT(images[layer][i]==NULL,"createImageCache for image already assigned!");
00245 images[layer][i]=images[layer][i-1]+1;
00246 }
00247 isAllocated[layer][base]=true;
00248 return images[layer][channel];
00249 }
00250 }
00251 void BufferedImageGenerator::calcImage(unsigned int layer, unsigned int channel) {
00252
00253 ASSERTRET(layer!=imgsrc.layer || channel>=imgsrc.channels, "calcImage on src channel?");
00254 switch(channel) {
00255 case RawCameraGenerator::CHAN_Y:
00256 if(layer>imgsrc.layer) upsampleImage(imgsrc.layer,channel,layer);
00257 else downsampleImage(layer,channel);
00258 break;
00259 case RawCameraGenerator::CHAN_U:
00260 case RawCameraGenerator::CHAN_V:
00261 if(imgsrc.channels>1) {
00262 if(layer>imgsrc.layer) upsampleImage(imgsrc.layer,channel,layer);
00263 else downsampleImage(layer,channel);
00264 } else
00265 memset(images[layer][channel],128,widths[layer]*heights[layer]);
00266 break;
00267 case RawCameraGenerator::CHAN_Y_DX:
00268 calcDx(layer);
00269 break;
00270 case RawCameraGenerator::CHAN_Y_DY:
00271 calcDy(layer);
00272 break;
00273 case RawCameraGenerator::CHAN_Y_DXDY:
00274 calcDxDy(layer);
00275 break;
00276 default:
00277 cerr << "Bad layer selection!" << endl;
00278 }
00279 }
00280 void BufferedImageGenerator::setDimensions() {
00281 if(imgsrc.img==NULL)
00282 return;
00283
00284 for(unsigned int i=0; i<=imgsrc.layer; i++) {
00285
00286 unsigned int s=(1<<(imgsrc.layer-i));
00287
00288 widths[i]=imgsrc.width/s;
00289 heights[i]=imgsrc.height/s;
00290
00291 strides[i]=imgsrc.width*imgsrc.channels*s;
00292 skips[i]=strides[i]-imgsrc.width*imgsrc.channels;
00293
00294 }
00295
00296 for(unsigned int i=imgsrc.layer+1; i<numLayers; i++) {
00297
00298 unsigned int s=(1<<(i-imgsrc.layer));
00299
00300 widths[i]=strides[i]=imgsrc.width*s;
00301 heights[i]=imgsrc.height*s;
00302
00303 skips[i]=0;
00304 }
00305 }
00306 void BufferedImageGenerator::destruct() {
00307 FilterBankGenerator::destruct();
00308 for(unsigned int i=0; i<numLayers; i++)
00309 delete [] isAllocated[i];
00310 delete [] isAllocated;
00311 isAllocated=NULL;
00312 }
00313 void BufferedImageGenerator::setNumImages(unsigned int nLayers, unsigned int nChannels) {
00314 if(nLayers==numLayers && nChannels==numChannels)
00315 return;
00316 FilterBankGenerator::setNumImages(nLayers,nChannels);
00317 isAllocated=new bool*[numLayers];
00318 for(unsigned int i=0; i<numLayers; i++) {
00319 isAllocated[i]=new bool[numChannels];
00320 for(unsigned int j=0; j<numChannels; j++)
00321 isAllocated[i][j]=false;
00322 }
00323 setDimensions();
00324 }
00325
00326 void BufferedImageGenerator::upsampleImage(unsigned int srcLayer, unsigned int chan, unsigned int destLayer) {
00327 ASSERTRET(destLayer!=imgsrc.layer,"upsample into source layer")
00328 unsigned char * cur=images[destLayer][chan];
00329 ASSERTRET(cur!=NULL,"destination layer is NULL");
00330 unsigned char * orig=getImage(srcLayer,chan);
00331 ASSERTRET(orig!=NULL,"source layer is NULL");
00332 unsigned int width=widths[destLayer];
00333 unsigned int height=heights[destLayer];
00334 unsigned int inc=getIncrement(srcLayer);
00335 int power=destLayer-srcLayer;
00336 ASSERTRET(power>0,"upsampleImage attempting to downsample")
00337
00338 unsigned char * const imgend=cur+width*height;
00339 while(cur!=imgend) {
00340 unsigned char * const row=cur;
00341 unsigned char * const rowend=cur+width;
00342
00343 while(cur<rowend) {
00344 for(int p=1<<power; p>0; p--)
00345 *cur++=*orig;
00346 orig+=inc;
00347 }
00348
00349 for(int p=0; p<power; p++) {
00350 unsigned int avail=width*(1<<p);
00351 memcpy(cur,row,avail);
00352 cur+=avail;
00353 }
00354 orig+=getSkip(srcLayer);
00355 }
00356 imageValids[destLayer][chan]=true;
00357 }
00358
00359 void BufferedImageGenerator::downsampleImage(unsigned int destLayer, unsigned int chan) {
00360 ASSERTRET(destLayer!=imgsrc.layer,"downsample into source layer")
00361
00362 unsigned int layer=destLayer;
00363 while(layer<numLayers && !imageValids[layer][chan])
00364 layer++;
00365 ASSERTRET(layer<numLayers,"valid layer to downsample from could not be found!");
00366
00367
00368 for(unsigned int srcL=layer--; layer>=destLayer; srcL=layer--) {
00369 unsigned int srcInc=getIncrement(srcL);
00370 unsigned char * s=getImage(srcL,chan);
00371 if(images[layer][chan]==NULL)
00372 images[layer][chan]=createImageCache(layer,chan);
00373 unsigned char * dst=images[layer][chan];
00374 unsigned char * const dstEnd=dst+widths[layer]*heights[layer];
00375 while(dst!=dstEnd) {
00376 unsigned char * const rowEnd=dst+widths[layer];
00377 while(dst!=rowEnd) {
00378 unsigned short x=*s;
00379 x+=*(s+strides[srcL]);
00380 s+=srcInc;
00381 x+=*s;
00382 x+=*(s+strides[srcL]);
00383 s+=srcInc;
00384 *dst++ = x/4;
00385 }
00386 s+=strides[srcL];
00387 }
00388 imageValids[layer][chan]=true;
00389 }
00390 }
00391
00392 void BufferedImageGenerator::calcDx(unsigned int layer, unsigned int srcChan, unsigned int dstChan) {
00393 unsigned char * s=getImage(layer,srcChan);
00394 unsigned char * dst=images[layer][dstChan];
00395 unsigned int inc=getIncrement(layer);
00396 unsigned int skip=getSkip(layer)+inc;
00397 unsigned char * const dstEnd=dst+getStride(layer)*heights[layer];
00398 unsigned int sc=2;
00399 while(dst!=dstEnd) {
00400 unsigned char * const rowEnd=dst+widths[layer]*inc-inc;
00401 unsigned char left,right;
00402 while(dst!=rowEnd) {
00403 left=(*s)>>sc;
00404 s+=inc;
00405 right=(*s)>>sc;
00406 *dst=right+128-left;
00407 dst+=inc;
00408 }
00409 *dst=128;
00410 dst+=skip;
00411 s+=skip;
00412 }
00413 imageValids[layer][dstChan]=true;
00414 }
00415 void BufferedImageGenerator::calcDy(unsigned int layer, unsigned int srcChan, unsigned int dstChan) {
00416 unsigned char * s=getImage(layer,srcChan);
00417 unsigned char * dst=images[layer][dstChan];
00418 unsigned int inc=getIncrement(layer);
00419 unsigned int stride=getStride(layer);
00420 unsigned char * const dstEnd=dst+widths[layer]*inc;
00421 unsigned int sc=2;
00422 while(dst!=dstEnd) {
00423 unsigned char * const colEnd=dst+heights[layer]*stride-stride;
00424 unsigned char top,bottom;
00425 while(dst!=colEnd) {
00426 top=(*s)>>sc;
00427 s+=stride;
00428 bottom=(*s)>>sc;
00429 *dst=bottom+128-top;
00430 dst+=stride;
00431 }
00432 *dst=128;
00433 dst-=heights[layer]*stride-stride;
00434 s-=heights[layer]*stride-stride;
00435 dst+=inc;
00436 s+=inc;
00437 }
00438 imageValids[layer][dstChan]=true;
00439 }
00440 void BufferedImageGenerator::calcDxDy(unsigned int layer) {
00441
00442 if(imageValids[layer][RawCameraGenerator::CHAN_Y_DX]) {
00443 calcDy(layer,RawCameraGenerator::CHAN_Y_DX,RawCameraGenerator::CHAN_Y_DXDY);
00444 imageValids[layer][RawCameraGenerator::CHAN_Y_DXDY]=true;
00445 } else if(imageValids[layer][RawCameraGenerator::CHAN_Y_DY]) {
00446 calcDx(layer,RawCameraGenerator::CHAN_Y_DY,RawCameraGenerator::CHAN_Y_DXDY);
00447 imageValids[layer][RawCameraGenerator::CHAN_Y_DXDY]=true;
00448 } else {
00449
00450 getImage(layer,RawCameraGenerator::CHAN_Y_DX);
00451 calcDy(layer,RawCameraGenerator::CHAN_Y_DX,RawCameraGenerator::CHAN_Y_DXDY);
00452 }
00453 }
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467 #endif