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
00010 #include "Shared/jpeg-6b/jpeg_mem_dest.h"
00011
00012 #include "Shared/debuget.h"
00013
00014 JPEGGenerator::JPEGGenerator(unsigned int mysid, FilterBankGenerator* fbg, EventBase::EventTypeID_t tid)
00015 : FilterBankGenerator("JPEGGenerator","JPEGGenerator",EventBase::visJPEGEGID,mysid,fbg,tid), srcMode(SRC_AUTO), curMode(SRC_AUTO), bytesUsed(NULL), cinfo(), jerr(), quality(-1U)
00016 {
00017 if(dynamic_cast<const InterleavedYUVGenerator*>(src)!=NULL)
00018 curMode=SRC_COLOR;
00019 else
00020 curMode=SRC_GRAYSCALE;
00021
00022
00023
00024
00025 cinfo.err = jpeg_std_error(&jerr);
00026 jpeg_create_compress(&cinfo);
00027
00028
00029 if(fbg!=NULL) {
00030 numLayers=numChannels=0;
00031 setNumImages(fbg->getNumLayers(),fbg->getNumChannels());
00032 }
00033 }
00034
00035 JPEGGenerator::JPEGGenerator(unsigned int mysid, src_mode_t mode, FilterBankGenerator* fbg, EventBase::EventTypeID_t tid)
00036 : FilterBankGenerator("JPEGGenerator","JPEGGenerator",EventBase::visJPEGEGID,mysid,fbg,tid), srcMode(mode), curMode(mode), bytesUsed(NULL), cinfo(), jerr(), quality(-1U)
00037 {
00038 if(srcMode==SRC_AUTO) {
00039 if(dynamic_cast<const InterleavedYUVGenerator*>(src)!=NULL)
00040 curMode=SRC_COLOR;
00041 else
00042 curMode=SRC_GRAYSCALE;
00043 }
00044
00045
00046
00047
00048 cinfo.err = jpeg_std_error(&jerr);
00049 jpeg_create_compress(&cinfo);
00050
00051
00052 if(fbg!=NULL) {
00053 numLayers=numChannels=0;
00054 setNumImages(fbg->getNumLayers(),fbg->getNumChannels());
00055 }
00056 }
00057
00058 JPEGGenerator::~JPEGGenerator() {
00059 freeCaches();
00060 destruct();
00061 jpeg_destroy_compress(&cinfo);
00062 }
00063
00064
00065
00066
00067
00068
00069 void
00070 JPEGGenerator::processEvent(const EventBase& event) {
00071 FilterBankGenerator::processEvent(event);
00072 if(event.getGeneratorID()==getListenGeneratorID() && event.getSourceID()==getListenSourceID()) {
00073 if(getSourceMode()==SRC_AUTO) {
00074 if(dynamic_cast<const InterleavedYUVGenerator*>(src)!=NULL)
00075 curMode=SRC_COLOR;
00076 else
00077 curMode=SRC_GRAYSCALE;
00078 }
00079 FilterBankEvent fbkev(this,getGeneratorID(),getSourceID(),EventBase::activateETID);
00080 erouter->postEvent(fbkev);
00081 fbkev.setTypeID(EventBase::statusETID);
00082 erouter->postEvent(fbkev);
00083 fbkev.setTypeID(EventBase::deactivateETID);
00084 erouter->postEvent(fbkev);
00085 }
00086 }
00087
00088 unsigned int
00089 JPEGGenerator::getBinSize() const {
00090 unsigned int used=FilterBankGenerator::getBinSize();
00091 char * type;
00092 if(getCurrentSourceFormat()==SRC_COLOR)
00093 type="JPEGColor";
00094 else if(getCurrentSourceFormat()==SRC_GRAYSCALE)
00095 type="JPEGGrayscale";
00096 else {
00097 serr->printf("getBinSize failed - unsuitable or unknown mode/generator pair");
00098 return 0;
00099 }
00100 used+=strlen(type)+LoadSave::stringpad;
00101 if(bytesUsed[selectedSaveLayer][selectedSaveChannel]!=0)
00102 used+=bytesUsed[selectedSaveLayer][selectedSaveChannel];
00103 else
00104 used+=widths[selectedSaveLayer]*heights[selectedSaveLayer]*3+JPEG_HEADER_PAD;
00105 return used;
00106 }
00107
00108 unsigned int
00109 JPEGGenerator::loadBuffer(const char buf[], unsigned int len) {
00110 unsigned int origlen=len;
00111 if(!checkInc(FilterBankGenerator::loadBuffer(buf,len),buf,len)) return 0;
00112 std::string tmp;
00113 if(!decodeInc(tmp,buf,len)) return 0;
00114 if(tmp!="JPEGColor" && tmp!="JPEGGrayscale") {
00115 serr->printf("Unhandled image type for JPEGGenerator: %s",tmp.c_str());
00116 return 0;
00117 } else {
00118 if(tmp=="JPEGColor" && getCurrentSourceFormat()==SRC_GRAYSCALE)
00119 serr->printf("Warning: loading grayscale into color image");
00120 if(tmp=="JPEGGrayscale" && getCurrentSourceFormat()==SRC_COLOR)
00121 serr->printf("Warning: loading color into grayscale image");
00122 unsigned int tmpL;
00123 if(!decodeInc(tmpL,buf,len)) return 0;
00124 if(tmpL>len)
00125 return 0;
00126 if(images[selectedSaveLayer][selectedSaveChannel]!=NULL)
00127 delete [] images[selectedSaveLayer][selectedSaveChannel];
00128 images[selectedSaveLayer][selectedSaveChannel]=createImageCache(selectedSaveLayer,selectedSaveChannel);
00129 unsigned int used=bytesUsed[selectedSaveLayer][selectedSaveChannel]=tmpL;
00130 unsigned char* img=getImage(selectedSaveLayer,selectedSaveChannel);
00131 if(img==NULL)
00132 return 0;
00133 memcpy(img,buf,used);
00134 len-=used; buf+=used;
00135 imageValids[selectedSaveLayer][selectedSaveChannel]=true;
00136 return origlen-len;
00137 }
00138 }
00139
00140 unsigned int
00141 JPEGGenerator::saveBuffer(char buf[], unsigned int len) const {
00142 unsigned int origlen=len;
00143 if(!checkInc(FilterBankGenerator::saveBuffer(buf,len),buf,len)) return 0;
00144
00145 char * type;
00146 if(getCurrentSourceFormat()==SRC_COLOR)
00147 type="JPEGColor";
00148 else if(getCurrentSourceFormat()==SRC_GRAYSCALE)
00149 type="JPEGGrayscale";
00150 else {
00151 serr->printf("saveBuffer failed - unsuitable or unknown mode/generator pair");
00152 return 0;
00153 }
00154 if(!encodeInc(type,buf,len)) return 0;
00155
00156 if(images[selectedSaveLayer][selectedSaveChannel]==NULL) {
00157 serr->printf("JPEGGenerator::saveBuffer() failed because selected image is NULL -- call selectSaveImage first to make sure it's up to date\n");
00158 return 0;
00159 }
00160 if(!imageValids[selectedSaveLayer][selectedSaveChannel]) {
00161 serr->printf("JPEGGenerator::saveBuffer() failed because selected image is invalid -- call selectSaveImage first to make sure it's up to date\n");
00162 return 0;
00163 }
00164 unsigned char* img=images[selectedSaveLayer][selectedSaveChannel];
00165 if(img==NULL)
00166 return 0;
00167 if(!encodeInc(bytesUsed[selectedSaveLayer][selectedSaveChannel],buf,len)) return 0;
00168 unsigned int used=bytesUsed[selectedSaveLayer][selectedSaveChannel];
00169 if(used>len)
00170 return 0;
00171 memcpy(buf,img,used);
00172 len-=used;
00173 return origlen-len;
00174 }
00175
00176 void
00177 JPEGGenerator::setNumImages(unsigned int nLayers, unsigned int nChannels) {
00178 if(nLayers==numLayers && nChannels==numChannels)
00179 return;
00180 FilterBankGenerator::setNumImages(nLayers,nChannels);
00181 for(unsigned int i=0; i<numLayers; i++)
00182 strides[i]=skips[i]=0;
00183 bytesUsed=new unsigned int*[numLayers];
00184 for(unsigned int res=0; res<numLayers; res++) {
00185 increments[res]=3;
00186 bytesUsed[res]=new unsigned int[numChannels];
00187 for(unsigned int i=0; i<numChannels; i++)
00188 bytesUsed[res][i]=0;
00189 }
00190 }
00191
00192 unsigned char *
00193 JPEGGenerator::createImageCache(unsigned int layer, unsigned int ) const {
00194 return new unsigned char[widths[layer]*heights[layer]*3+JPEG_HEADER_PAD];
00195 }
00196
00197
00198
00199
00200
00201
00202
00203 void
00204 JPEGGenerator::calcImage(unsigned int layer, unsigned int chan) {
00205 PROFSECTION("JPEGGenerator::calcImage(...)",*mainProfiler);
00206 try {
00207
00208 jpeg_mem_dest(&cinfo, images[layer][chan], widths[layer]*heights[layer]*3+JPEG_HEADER_PAD);
00209
00210
00211 cinfo.image_width = widths[layer];
00212 cinfo.image_height = heights[layer];
00213 if(getCurrentSourceFormat()==SRC_COLOR ) {
00214 cinfo.input_components = 3;
00215 cinfo.in_color_space = JCS_YCbCr;
00216 } else if(getCurrentSourceFormat()==SRC_GRAYSCALE) {
00217 cinfo.input_components = 1;
00218 cinfo.in_color_space = JCS_GRAYSCALE;
00219 } else {
00220 serr->printf("%s %s Compression failed - unsuitable or unknown mode/generator pair",getClassName().c_str(),getName().c_str());
00221 jpeg_destroy_compress(&cinfo);
00222 return;
00223 }
00224
00225
00226 jpeg_set_defaults(&cinfo);
00227 unsigned int qual=(quality==-1U?config->vision.rawcam_compress_quality:quality);
00228 jpeg_set_quality(&cinfo, qual, false);
00229 cinfo.dct_method=config->vision.jpeg_dct_method;
00230 if(cinfo.in_color_space==JCS_GRAYSCALE && src->getIncrement(layer)!=1) {
00231
00232 jpeg_start_compress(&cinfo, TRUE);
00233 unsigned int row_stride = src->getStride(layer);
00234 JSAMPROW row_pointer[1] = { new JSAMPLE[src->getWidth(layer)] };
00235 unsigned char * curpos=src->getImage(layer,chan);
00236 const unsigned int inc=src->getIncrement(layer);
00237 while (cinfo.next_scanline < cinfo.image_height) {
00238 for(unsigned int x=0; x<src->getWidth(layer); x++)
00239 row_pointer[0][x] = curpos[x*inc];
00240 jpeg_write_scanlines(&cinfo, row_pointer, 1);
00241 curpos+=row_stride;
00242 }
00243 jpeg_finish_compress(&cinfo);
00244
00245 } else {
00246 if(cinfo.in_color_space==JCS_YCbCr) {
00247 unsigned int ysamp=1;
00248 unsigned int uvsamp=1;
00249 const unsigned int maxsamp=2;
00250 if(config->vision.rawcam_y_skip>config->vision.rawcam_uv_skip) {
00251 uvsamp=config->vision.rawcam_y_skip-config->vision.rawcam_uv_skip+1;
00252 if(uvsamp>maxsamp)
00253 uvsamp=maxsamp;
00254 } else {
00255 ysamp=config->vision.rawcam_uv_skip-config->vision.rawcam_y_skip+1;
00256 if(ysamp>maxsamp)
00257 ysamp=maxsamp;
00258 }
00259 cinfo.comp_info[0].h_samp_factor=ysamp;
00260 cinfo.comp_info[0].v_samp_factor=ysamp;
00261 cinfo.comp_info[1].h_samp_factor=uvsamp;
00262 cinfo.comp_info[1].v_samp_factor=uvsamp;
00263 cinfo.comp_info[2].h_samp_factor=uvsamp;
00264 cinfo.comp_info[2].v_samp_factor=uvsamp;
00265 }
00266
00267
00268 jpeg_start_compress(&cinfo, TRUE);
00269 unsigned int row_stride = src->getStride(layer);
00270 JSAMPROW row_pointer[1] = { const_cast<JSAMPROW>(src->getImage(layer,chan)) };
00271 while (cinfo.next_scanline < cinfo.image_height) {
00272 jpeg_write_scanlines(&cinfo, row_pointer, 1);
00273 row_pointer[0]+=row_stride;
00274 }
00275 jpeg_finish_compress(&cinfo);
00276 }
00277
00278
00279 bytesUsed[layer][chan]=jpeg_mem_size(&cinfo);
00280 imageValids[layer][chan]=true;
00281 } catch(const std::exception& ex) {
00282 std::cerr << "Exception while compressing JPEG: " << ex.what() << std::endl;
00283 std::cerr << "layer==" << layer << " channel==" << chan << " image==" << (void*)images[layer][chan] << std::endl;
00284 std::cerr << "width==" << widths[layer] << " height==" << heights[layer] << std::endl;
00285 std::cerr << "row_stride==" << src->getStride(layer) << " next_scanline==" << reinterpret_cast<void*>(cinfo.next_scanline) << " image_height==" << cinfo.image_height << std::endl;
00286 jpeg_destroy_compress(&cinfo);
00287 }
00288 }
00289
00290 void
00291 JPEGGenerator::destruct() {
00292 FilterBankGenerator::destruct();
00293 for(unsigned int res=0; res<numLayers; res++)
00294 delete [] bytesUsed[res];
00295 delete [] bytesUsed;
00296 bytesUsed=NULL;
00297 }
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309