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
00021
00022
00023 cinfo.err = jpeg_std_error(&jerr);
00024 jpeg_create_compress(&cinfo);
00025
00026
00027 if(fbg!=NULL) {
00028 numLayers=numChannels=0;
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
00044
00045
00046 cinfo.err = jpeg_std_error(&jerr);
00047 jpeg_create_compress(&cinfo);
00048
00049
00050 if(fbg!=NULL) {
00051 numLayers=numChannels=0;
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
00064
00065
00066
00067 void
00068 JPEGGenerator::doEvent() {
00069 if(event->getGeneratorID()==getListenGeneratorID() && event->getSourceID()==getListenSourceID()) {
00070 if(getSourceMode()==SRC_AUTO) {
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 ) 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
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
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
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
00235
00236
00237
00238