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 <write_jpeg.h>
00008 #include "Shared/Config.h"
00009 #include "Shared/WorldState.h"
00010
00011 #include <jpeg_mem_dest.h>
00012
00013
00014 #include "Shared/debuget.h"
00015
00016 JPEGGenerator::JPEGGenerator(EventBase::EventGeneratorID_t gid, unsigned int sid, unsigned int mysid)
00017 : FilterBankGenerator("JPEGGenerator",0,0,gid,sid,EventBase::visJPEGEGID,mysid), src(NULL), srcMode(SRC_AUTO), curMode(SRC_AUTO), bytesUsed(NULL), cinfo(), jerr(), quality(-1U)
00018 {
00019 setNumImages(numLayers,numChannels);
00020
00021
00022
00023
00024 cinfo.err = jpeg_std_error(&jerr);
00025 jpeg_create_compress(&cinfo);
00026 }
00027
00028 JPEGGenerator::JPEGGenerator(EventBase::EventGeneratorID_t gid, unsigned int sid, unsigned int mysid, src_mode_t mode)
00029 : FilterBankGenerator("JPEGGenerator",0,0,gid,sid,EventBase::visJPEGEGID,mysid), src(NULL), srcMode(mode), curMode(SRC_AUTO), bytesUsed(NULL), cinfo(), jerr(), quality(-1U)
00030 {
00031 setNumImages(numLayers,numChannels);
00032
00033
00034
00035
00036 cinfo.err = jpeg_std_error(&jerr);
00037 jpeg_create_compress(&cinfo);
00038 }
00039
00040 JPEGGenerator::~JPEGGenerator() {
00041 freeCaches();
00042 destruct();
00043 jpeg_destroy_compress(&cinfo);
00044 }
00045
00046
00047
00048
00049
00050
00051 void
00052 JPEGGenerator::processEvent(const EventBase& event) {
00053 const FilterBankEvent& fbkevent=dynamic_cast<const FilterBankEvent& >(event);
00054 src=fbkevent.getSource();
00055 frameNumber=src->getFrameNumber();
00056 if(getSourceMode()==SRC_AUTO) {
00057 if(dynamic_cast<const InterleavedYUVGenerator*>(src)!=NULL)
00058 curMode=SRC_COLOR;
00059 else
00060 curMode=SRC_GRAYSCALE;
00061 }
00062 if(src->getNumLayers()!=numLayers || src->getNumChannels()!=numChannels)
00063 setNumImages(src->getNumLayers(),src->getNumChannels());
00064 if(src->getWidth(numLayers-1)!=getWidth(numLayers-1)) {
00065 ASSERT(widths[numLayers-1]==0,"Strange, the image width changed after initial setting" << widths[numLayers-1]);
00066 setDimensions();
00067 }
00068
00069 invalidateCaches();
00070 framesProcessed++;
00071 erouter->postEvent(new FilterBankEvent(this,getGeneratorID(),getSourceID()));
00072 }
00073
00074 unsigned int
00075 JPEGGenerator::getBinSize() const {
00076 unsigned int used=FilterBankGenerator::getBinSize();
00077 used+=strlen("JPEGColor")+LoadSave::stringpad;
00078 if(bytesUsed[selectedSaveLayer][selectedSaveChannel]!=0)
00079 used+=bytesUsed[selectedSaveLayer][selectedSaveChannel];
00080 else
00081 used+=widths[selectedSaveLayer]*heights[selectedSaveLayer]*3+JPEG_HEADER_PAD;
00082 return used;
00083 }
00084
00085 unsigned int
00086 JPEGGenerator::LoadBuffer(const char buf[], unsigned int len) {
00087 unsigned int origlen=len;
00088 unsigned int used;
00089 std::string tmp;
00090 if(0==(used=FilterBankGenerator::LoadBuffer(buf,len))) return 0;
00091 len-=used; buf+=used;
00092 if(0==(used=decode(tmp,buf,len))) return 0;
00093 len-=used; buf+=used;
00094 if(tmp!="JPEGColor" && tmp!="JPEGGray") {
00095 serr->printf("Unhandled image type for JPEGGenerator: %s",tmp.c_str());
00096 return 0;
00097 } else {
00098 if(tmp=="JPEGColor" && getCurrentSourceFormat()==SRC_GRAYSCALE)
00099 serr->printf("Warning: loading grayscale into color image");
00100 if(tmp=="JPEGGrayscale" && getCurrentSourceFormat()==SRC_COLOR)
00101 serr->printf("Warning: loading color into grayscale image");
00102 unsigned int tmpL;
00103 if(0==(used=decode(tmpL,buf,len))) return 0;
00104 len-=used; buf+=used;
00105 if(tmpL>len)
00106 return 0;
00107 if(images[selectedSaveLayer][selectedSaveChannel]!=NULL)
00108 delete [] images[selectedSaveLayer][selectedSaveChannel];
00109 images[selectedSaveLayer][selectedSaveChannel]=createImageCache(selectedSaveLayer,selectedSaveChannel);
00110 used=bytesUsed[selectedSaveLayer][selectedSaveChannel]=tmpL;
00111 unsigned char* img=getImage(selectedSaveLayer,selectedSaveChannel);
00112 if(img==NULL)
00113 return 0;
00114 memcpy(img,buf,used);
00115 len-=used; buf+=used;
00116 imageValids[selectedSaveLayer][selectedSaveChannel]=true;
00117 return origlen-len;
00118 }
00119 }
00120
00121 unsigned int
00122 JPEGGenerator::SaveBuffer(char buf[], unsigned int len) const {
00123 unsigned int origlen=len;
00124 unsigned int used;
00125 if(0==(used=FilterBankGenerator::SaveBuffer(buf,len))) return 0;
00126 len-=used; buf+=used;
00127
00128 char * type;
00129 if(getCurrentSourceFormat()==SRC_COLOR)
00130 type="JPEGColor";
00131 else if(getCurrentSourceFormat()==SRC_GRAYSCALE)
00132 type="JPEGGrayscale";
00133 else {
00134 serr->printf("SaveBuffer failed - unsuitable or unknown mode/generator pair");
00135 return 0;
00136 }
00137 if(0==(used=encode(type,buf,len))) return 0;
00138 len-=used; buf+=used;
00139
00140 unsigned char* img=getImage(selectedSaveLayer,selectedSaveChannel);
00141 if(img==NULL)
00142 return 0;
00143 if(0==(used=encode(bytesUsed[selectedSaveLayer][selectedSaveChannel],buf,len))) return 0;
00144 len-=used; buf+=used;
00145 used=bytesUsed[selectedSaveLayer][selectedSaveChannel];
00146 if(used>len)
00147 return 0;
00148 memcpy(buf,img,used);
00149 len-=used;
00150 return origlen-len;
00151 }
00152
00153 void
00154 JPEGGenerator::setDimensions() {
00155 for(unsigned int i=0; i<numLayers; i++) {
00156 widths[i]=src->getWidth(i);
00157 heights[i]=src->getHeight(i);
00158 strides[i]=skips[i]=0;
00159 }
00160 }
00161
00162 void
00163 JPEGGenerator::setNumImages(unsigned int nLayers, unsigned int nChannels) {
00164 FilterBankGenerator::setNumImages(nLayers,nChannels);
00165 bytesUsed=new unsigned int*[numLayers];
00166 for(unsigned int res=0; res<numLayers; res++) {
00167 increments[res]=3;
00168 bytesUsed[res]=new unsigned int[numChannels];
00169 for(unsigned int i=0; i<numChannels; i++)
00170 bytesUsed[res][i]=0;
00171 }
00172 }
00173
00174 unsigned char *
00175 JPEGGenerator::createImageCache(unsigned int layer, unsigned int ) const {
00176 return new unsigned char[widths[layer]*heights[layer]*3+JPEG_HEADER_PAD];
00177 }
00178
00179
00180
00181
00182
00183
00184
00185 void
00186 JPEGGenerator::calcImage(unsigned int layer, unsigned int chan) const {
00187 PROFSECTION("JPEGGenerator::calcImage(...)",state->mainProfile);
00188
00189
00190 jpeg_mem_dest(&cinfo, images[layer][chan], widths[layer]*heights[layer]*3+JPEG_HEADER_PAD);
00191
00192
00193 cinfo.image_width = widths[layer];
00194 cinfo.image_height = heights[layer];
00195 if(getCurrentSourceFormat()==SRC_COLOR ) {
00196 cinfo.input_components = 3;
00197 cinfo.in_color_space = JCS_YCbCr;
00198 } else if(getCurrentSourceFormat()==SRC_GRAYSCALE) {
00199 cinfo.input_components = 1;
00200 cinfo.in_color_space = JCS_GRAYSCALE;
00201 } else {
00202 serr->printf("Compression failed - unsuitable or unknown mode/generator pair");
00203 jpeg_destroy_compress(&cinfo);
00204 return;
00205 }
00206
00207
00208 jpeg_set_defaults(&cinfo);
00209 unsigned int qual=(quality==-1U?config->vision.rawcam_compress_quality:quality);
00210 jpeg_set_quality(&cinfo, qual, false);
00211 cinfo.dct_method=config->vision.jpeg_dct_method;
00212 if(cinfo.in_color_space==JCS_YCbCr) {
00213 unsigned int ysamp=1;
00214 unsigned int uvsamp=1;
00215 const unsigned int maxsamp=2;
00216 if(config->vision.rawcam_y_skip>config->vision.rawcam_uv_skip) {
00217 uvsamp=config->vision.rawcam_y_skip-config->vision.rawcam_uv_skip+1;
00218 if(uvsamp>maxsamp)
00219 uvsamp=maxsamp;
00220 } else {
00221 ysamp=config->vision.rawcam_uv_skip-config->vision.rawcam_y_skip+1;
00222 if(ysamp>maxsamp)
00223 ysamp=maxsamp;
00224 }
00225 cinfo.comp_info[0].h_samp_factor=ysamp;
00226 cinfo.comp_info[0].v_samp_factor=ysamp;
00227 cinfo.comp_info[1].h_samp_factor=uvsamp;
00228 cinfo.comp_info[1].v_samp_factor=uvsamp;
00229 cinfo.comp_info[2].h_samp_factor=uvsamp;
00230 cinfo.comp_info[2].v_samp_factor=uvsamp;
00231 }
00232
00233
00234 jpeg_start_compress(&cinfo, TRUE);
00235 unsigned int row_stride = src->getStride(layer);
00236 JSAMPROW row_pointer[1] = { const_cast<JSAMPROW>(src->getImage(layer,chan)) };
00237 while (cinfo.next_scanline < cinfo.image_height) {
00238 jpeg_write_scanlines(&cinfo, row_pointer, 1);
00239 row_pointer[0]+=row_stride;
00240 }
00241 jpeg_finish_compress(&cinfo);
00242
00243
00244 bytesUsed[layer][chan]=jpeg_mem_size(&cinfo);
00245 imageValids[layer][chan]=true;
00246 }
00247
00248 void
00249 JPEGGenerator::destruct() {
00250 FilterBankGenerator::destruct();
00251 for(unsigned int res=0; res<numLayers; res++)
00252 delete [] bytesUsed[res];
00253 delete [] bytesUsed;
00254 bytesUsed=NULL;
00255 }
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267