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