Tekkotsu Homepage
Demos
Overview
Downloads
Dev. Resources
Reference
Credits

PNGGenerator.cc

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

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