Tekkotsu Homepage
Demos
Overview
Downloads
Dev. Resources
Reference
Credits

JPEGGenerator.cc

Go to the documentation of this file.
00001 #include "JPEGGenerator.h"
00002 #include "InterleavedYUVGenerator.h"
00003 #include "Events/DataEvent.h"
00004 #include "Events/EventRouter.h"
00005 #include "Events/FilterBankEvent.h"
00006 #include "Wireless/Wireless.h"
00007 #include "Shared/Config.h"
00008 #include "Shared/Profiler.h"
00009 #include "Shared/ImageUtil.h"
00010 #include "Shared/debuget.h"
00011 
00012 JPEGGenerator::JPEGGenerator(unsigned int mysid, FilterBankGenerator* fbg, EventBase::EventTypeID_t tid)
00013   : FilterBankGenerator("JPEGGenerator",EventBase::visJPEGEGID,mysid,fbg,tid), srcMode(SRC_AUTO), curMode(SRC_AUTO), bytesUsed(NULL), cinfo(), jerr(), quality(-1U)
00014 {
00015   if(dynamic_cast<const InterleavedYUVGenerator*>(src)!=NULL)
00016     curMode=SRC_COLOR;
00017   else
00018     curMode=SRC_GRAYSCALE;
00019 
00020   // We set the err object before we create the compress...  the idea
00021   // is if the creation fails, we can still get the error as to why it
00022   // failed.
00023   cinfo.err = jpeg_std_error(&jerr);
00024   jpeg_create_compress(&cinfo);
00025 
00026   //this part is only necessary if you override setNumImages yourself
00027   if(fbg!=NULL) {
00028     numLayers=numChannels=0; //this is to force setNumImages to override settings provided by FilterBankGenerator
00029     setNumImages(fbg->getNumLayers(),fbg->getNumChannels());
00030   }
00031 }
00032 
00033 JPEGGenerator::JPEGGenerator(unsigned int mysid, src_mode_t mode, FilterBankGenerator* fbg, EventBase::EventTypeID_t tid)
00034   : FilterBankGenerator("JPEGGenerator",EventBase::visJPEGEGID,mysid,fbg,tid), srcMode(mode), curMode(mode), bytesUsed(NULL), cinfo(), jerr(), quality(-1U)
00035 {
00036   if(srcMode==SRC_AUTO) {
00037     if(dynamic_cast<const InterleavedYUVGenerator*>(src)!=NULL)
00038       curMode=SRC_COLOR;
00039     else
00040       curMode=SRC_GRAYSCALE;
00041   }
00042   
00043   // We set the err object before we create the compress...  the idea
00044   // is if the creation fails, we can still get the error as to why it
00045   // failed.
00046   cinfo.err = jpeg_std_error(&jerr);
00047   jpeg_create_compress(&cinfo);
00048 
00049   //this part is only necessary if you override setNumImages yourself
00050   if(fbg!=NULL) {
00051     numLayers=numChannels=0; //this is to force setNumImages to override settings provided by FilterBankGenerator
00052     setNumImages(fbg->getNumLayers(),fbg->getNumChannels());
00053   }
00054 }
00055 
00056 JPEGGenerator::~JPEGGenerator() {
00057   freeCaches();
00058   destruct();
00059   jpeg_destroy_compress(&cinfo);
00060 }
00061 
00062 
00063 /*! The const casts in this function are regretable but necessary
00064  *  since the corresponding OPEN-R functions require mutable
00065  *  arguments, even though they shouldn't be modifying the data
00066  */
00067 void
00068 JPEGGenerator::doEvent() {
00069   if(event->getGeneratorID()==getListenGeneratorID() && event->getSourceID()==getListenSourceID()) {
00070     if(getSourceMode()==SRC_AUTO) { //if not auto, curMode was already set when srcMode was set
00071       if(dynamic_cast<const InterleavedYUVGenerator*>(src)!=NULL)
00072         curMode=SRC_COLOR;
00073       else
00074         curMode=SRC_GRAYSCALE;
00075     }
00076     FilterBankEvent fbkev(this,getGeneratorID(),getSourceID(),EventBase::activateETID);
00077     erouter->postEvent(fbkev);
00078     fbkev.setTypeID(EventBase::statusETID);
00079     erouter->postEvent(fbkev);
00080     fbkev.setTypeID(EventBase::deactivateETID);
00081     erouter->postEvent(fbkev);
00082   }
00083 }
00084 
00085 unsigned int
00086 JPEGGenerator::getBinSize() const {
00087   unsigned int used=FilterBankGenerator::getBinSize();
00088   const char * type;
00089   if(getCurrentSourceFormat()==SRC_COLOR)
00090     type="JPEGColor";
00091   else if(getCurrentSourceFormat()==SRC_GRAYSCALE)
00092     type="JPEGGrayscale";
00093   else {
00094     serr->printf("getBinSize failed - unsuitable or unknown mode/generator pair");
00095     return 0;
00096   }
00097   used+=strlen(type)+LoadSave::stringpad;
00098   if(bytesUsed[selectedSaveLayer][selectedSaveChannel]!=0)
00099     used+=bytesUsed[selectedSaveLayer][selectedSaveChannel];
00100   else
00101     used+=widths[selectedSaveLayer]*heights[selectedSaveLayer]*3+JPEG_HEADER_PAD;
00102   return used;
00103 }
00104 
00105 unsigned int
00106 JPEGGenerator::loadBuffer(const char buf[], unsigned int len, const char* filename) {
00107   unsigned int origlen=len;
00108   if(!checkInc(FilterBankGenerator::loadBuffer(buf,len,filename),buf,len)) return 0;
00109   std::string tmp;
00110   if(!decodeInc(tmp,buf,len)) return 0;
00111   if(tmp!="JPEGColor" && tmp!="JPEGGrayscale") {
00112     serr->printf("Unhandled image type for JPEGGenerator: %s",tmp.c_str());
00113     return 0;
00114   } else {
00115     if(tmp=="JPEGColor" && getCurrentSourceFormat()==SRC_GRAYSCALE)
00116       serr->printf("Warning: loading grayscale into color image");
00117     if(tmp=="JPEGGrayscale" && getCurrentSourceFormat()==SRC_COLOR)
00118       serr->printf("Warning: loading color into grayscale image");
00119     unsigned int tmpL;
00120     if(!decodeInc(tmpL,buf,len)) return 0;
00121     if(tmpL>len)
00122       return 0;
00123     if(images[selectedSaveLayer][selectedSaveChannel]!=NULL)
00124       delete [] images[selectedSaveLayer][selectedSaveChannel];
00125     images[selectedSaveLayer][selectedSaveChannel]=createImageCache(selectedSaveLayer,selectedSaveChannel);
00126     unsigned int used=bytesUsed[selectedSaveLayer][selectedSaveChannel]=tmpL;
00127     unsigned char* img=getImage(selectedSaveLayer,selectedSaveChannel);
00128     if(img==NULL)
00129       return 0;
00130     memcpy(img,buf,used);
00131     len-=used; buf+=used;
00132     imageValids[selectedSaveLayer][selectedSaveChannel]=true;
00133     return origlen-len; 
00134   }
00135 }
00136 
00137 unsigned int
00138 JPEGGenerator::saveBuffer(char buf[], unsigned int len) const {
00139   unsigned int origlen=len;
00140   if(!checkInc(FilterBankGenerator::saveBuffer(buf,len),buf,len)) return 0;
00141 
00142   const char * type;
00143   if(getCurrentSourceFormat()==SRC_COLOR)
00144     type="JPEGColor";
00145   else if(getCurrentSourceFormat()==SRC_GRAYSCALE)
00146     type="JPEGGrayscale";
00147   else {
00148     serr->printf("saveBuffer failed - unsuitable or unknown mode/generator pair");
00149     return 0;
00150   }
00151   if(!encodeInc(type,buf,len)) return 0;
00152   
00153   if(images[selectedSaveLayer][selectedSaveChannel]==NULL) {
00154     serr->printf("JPEGGenerator::saveBuffer() failed because selected image is NULL -- call selectSaveImage first to make sure it's up to date\n");
00155     return 0;
00156   }
00157   if(!imageValids[selectedSaveLayer][selectedSaveChannel]) {
00158     serr->printf("JPEGGenerator::saveBuffer() failed because selected image is invalid -- call selectSaveImage first to make sure it's up to date\n");
00159     return 0;
00160   }
00161   unsigned char* img=images[selectedSaveLayer][selectedSaveChannel];
00162   if(img==NULL)
00163     return 0;
00164   if(!encodeInc(bytesUsed[selectedSaveLayer][selectedSaveChannel],buf,len)) return 0;
00165   unsigned int used=bytesUsed[selectedSaveLayer][selectedSaveChannel];
00166   if(used>len)
00167     return 0;
00168   memcpy(buf,img,used);
00169   len-=used;
00170   return origlen-len;
00171 }
00172 
00173 void
00174 JPEGGenerator::setNumImages(unsigned int nLayers, unsigned int nChannels) {
00175   if(nLayers==numLayers && nChannels==numChannels)
00176     return;
00177   FilterBankGenerator::setNumImages(nLayers,nChannels);
00178   for(unsigned int i=0; i<numLayers; i++)
00179     strides[i]=skips[i]=0;
00180   bytesUsed=new unsigned int*[numLayers];
00181   for(unsigned int res=0; res<numLayers; res++) {
00182     increments[res]=3;
00183     bytesUsed[res]=new unsigned int[numChannels];
00184     for(unsigned int i=0; i<numChannels; i++)
00185       bytesUsed[res][i]=0;
00186   }
00187 }
00188 
00189 unsigned char *
00190 JPEGGenerator::createImageCache(unsigned int layer, unsigned int /*chan*/) const {
00191   return new unsigned char[widths[layer]*heights[layer]*3+JPEG_HEADER_PAD];
00192 }
00193 
00194 void
00195 JPEGGenerator::calcImage(unsigned int layer, unsigned int chan) {
00196   PROFSECTION("JPEGGenerator::calcImage(...)",*mainProfiler);
00197   
00198   // input configuration
00199   char* inbuf = reinterpret_cast<char*>(src->getImage(layer,chan));
00200   size_t inbufSize = src->getWidth(layer)*src->getIncrement(layer)*src->getHeight(layer);
00201   size_t srcChans = src->getIncrement(layer);
00202   
00203   // output configuration
00204   ASSERT(images[layer][chan]!=NULL,"image was not allocated");
00205   char*& outbuf = reinterpret_cast<char*&>(images[layer][chan]);
00206   size_t outbufSize = widths[layer]*heights[layer]*3+JPEG_HEADER_PAD;
00207   size_t dstChans;
00208   if(getCurrentSourceFormat()==SRC_COLOR ) {
00209     dstChans=3;
00210   } else if(getCurrentSourceFormat()==SRC_GRAYSCALE) {
00211     dstChans=1;
00212   } else {
00213     serr->printf("%s %s Compression failed - unsuitable or unknown mode/generator pair",getClassName().c_str(),getName().c_str());
00214     return;
00215   }
00216   unsigned int qual = (quality==-1U?*config->vision.rawcam.compress_quality:quality);
00217   unsigned int yskip = config->vision.rawcam.y_skip;
00218   unsigned int uvskip = config->vision.rawcam.uv_skip;
00219   
00220   // do it!
00221   bytesUsed[layer][chan] = image_util::encodeJPEG(inbuf,inbufSize,widths[layer],heights[layer],srcChans,outbuf,outbufSize,dstChans,qual,yskip,uvskip,cinfo);
00222   imageValids[layer][chan] = (bytesUsed[layer][chan]!=0);
00223 }
00224 
00225 void
00226 JPEGGenerator::destruct() {
00227   FilterBankGenerator::destruct();
00228   for(unsigned int res=0; res<numLayers; res++)
00229     delete [] bytesUsed[res];
00230   delete [] bytesUsed;
00231   bytesUsed=NULL;
00232 }
00233 
00234 /*! @file
00235  * @brief Implements JPEGGenerator, which generates FilterBankEvents containing JPEG compressed images
00236  * @author ejt (Creator)
00237  */
00238 

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