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 
00011 JPEGGenerator::JPEGGenerator(unsigned int mysid, FilterBankGenerator* fbg, EventBase::EventTypeID_t tid)
00012   : FilterBankGenerator("JPEGGenerator","JPEGGenerator",EventBase::visJPEGEGID,mysid,fbg,tid), srcMode(SRC_AUTO), curMode(SRC_AUTO), bytesUsed(NULL), cinfo(), jerr(), quality(-1U)
00013 {
00014   if(dynamic_cast<const InterleavedYUVGenerator*>(src)!=NULL)
00015     curMode=SRC_COLOR;
00016   else
00017     curMode=SRC_GRAYSCALE;
00018 
00019   // We set the err object before we create the compress...  the idea
00020   // is if the creation fails, we can still get the error as to why it
00021   // failed.
00022   cinfo.err = jpeg_std_error(&jerr);
00023   jpeg_create_compress(&cinfo);
00024 
00025   //this part is only necessary if you override setNumImages yourself
00026   if(fbg!=NULL) {
00027     numLayers=numChannels=0; //this is to force setNumImages to override settings provided by FilterBankGenerator
00028     setNumImages(fbg->getNumLayers(),fbg->getNumChannels());
00029   }
00030 }
00031 
00032 JPEGGenerator::JPEGGenerator(unsigned int mysid, src_mode_t mode, FilterBankGenerator* fbg, EventBase::EventTypeID_t tid)
00033   : FilterBankGenerator("JPEGGenerator","JPEGGenerator",EventBase::visJPEGEGID,mysid,fbg,tid), srcMode(mode), curMode(mode), bytesUsed(NULL), cinfo(), jerr(), quality(-1U)
00034 {
00035   if(srcMode==SRC_AUTO) {
00036     if(dynamic_cast<const InterleavedYUVGenerator*>(src)!=NULL)
00037       curMode=SRC_COLOR;
00038     else
00039       curMode=SRC_GRAYSCALE;
00040   }
00041   
00042   // We set the err object before we create the compress...  the idea
00043   // is if the creation fails, we can still get the error as to why it
00044   // failed.
00045   cinfo.err = jpeg_std_error(&jerr);
00046   jpeg_create_compress(&cinfo);
00047 
00048   //this part is only necessary if you override setNumImages yourself
00049   if(fbg!=NULL) {
00050     numLayers=numChannels=0; //this is to force setNumImages to override settings provided by FilterBankGenerator
00051     setNumImages(fbg->getNumLayers(),fbg->getNumChannels());
00052   }
00053 }
00054 
00055 JPEGGenerator::~JPEGGenerator() {
00056   freeCaches();
00057   destruct();
00058   jpeg_destroy_compress(&cinfo);
00059 }
00060 
00061 
00062 /*! The const casts in this function are regretable but necessary
00063  *  since the corresponding OPEN-R functions require mutable
00064  *  arguments, even though they shouldn't be modifying the data
00065  */
00066 void
00067 JPEGGenerator::processEvent(const EventBase& event) {
00068   FilterBankGenerator::processEvent(event);
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   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) {
00107   unsigned int origlen=len;
00108   if(!checkInc(FilterBankGenerator::loadBuffer(buf,len),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   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  * $Author: ejt $
00239  * $Name: tekkotsu-4_0 $
00240  * $Revision: 1.22 $
00241  * $State: Exp $
00242  * $Date: 2007/06/22 18:33:52 $
00243  */
00244 

Tekkotsu v4.0
Generated Thu Nov 22 00:54:53 2007 by Doxygen 1.5.4