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
00022 if(fbg!=NULL) {
00023 numLayers=numChannels=0;
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
00039 if(fbg!=NULL) {
00040 numLayers=numChannels=0;
00041 setNumImages(fbg->getNumLayers(),fbg->getNumChannels());
00042 }
00043 }
00044
00045 PNGGenerator::~PNGGenerator() {
00046 freeCaches();
00047 destruct();
00048 }
00049
00050
00051
00052
00053
00054
00055 void
00056 PNGGenerator::doEvent() {
00057 if(event->getGeneratorID()==getListenGeneratorID() && event->getSourceID()==getListenSourceID()) {
00058 if(getSourceMode()==SRC_AUTO) {
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 ) 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
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
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
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
00220
00221
00222