00001
00002
00003
00004
00005
00006 #include <string>
00007 #include <stdio.h>
00008 #include "charm++.h"
00009 #include "conv-ccs.h"
00010 #include <sys/types.h>
00011 #include "liveViz0.h"
00012 #include "pup_toNetwork.h"
00013
00014
00015
00016
00017 static liveVizConfig config;
00018
00019
00020 void liveVizConfig::init(pixel_t pix,bool push)
00021 {
00022 pixels=pix;
00023 switch(pixels) {
00024 case pix_greyscale: bytesPerPixel=1; break;
00025 case pix_color: bytesPerPixel=3; break;
00026 case pix_float: bytesPerPixel=4; break;
00027 default: CmiAbort("Unrecognized liveViz pixel code!\n");
00028 };
00029 serverPush=push;
00030 is3d=false;
00031
00032 verbose=0;
00033 }
00034
00035
00036 void liveVizConfig::pupNetwork(PUP::er &p) {
00037 int version=1;
00038 p|version;
00039 bool isColor=(pixels!=pix_greyscale);
00040 p|isColor;
00041 if(isColor)
00042 {
00043 pixels = pix_color;
00044 bytesPerPixel=3;
00045 }
00046 p|serverPush;
00047 p|is3d;
00048 if (is3d) {
00049 p|box.min;
00050 p|box.max;
00051 }
00052 }
00053
00054
00055 void liveVizRequest::pupNetwork(PUP::er &p) {
00056 int version=2;
00057 p|version;
00058 p|code;
00059 p|wid;
00060 p|ht;
00061 if (version>=2) {
00062 p|compressionType;
00063 p|compressionQuality;
00064 } else {
00065 compressionType=compressionNone;
00066 compressionQuality=0;
00067 }
00068 }
00069
00070 void liveVizRequest3d::pup(PUP::er &p) {
00071 p|x; p|y; p|z; p|o;
00072 p|minZ; p|maxZ;
00073 }
00074
00075
00076
00077
00078
00079 extern "C" void getImageConfigHandler(char * msg)
00080 {
00081 PUP_toNetwork_sizer sp;
00082 config.pupNetwork(sp);
00083 int len=sp.size();
00084 char *buf=new char[len];
00085 PUP_toNetwork_pack pp(buf);
00086 config.pupNetwork(pp);
00087 if (len!=pp.size()) CkAbort("liveVizConfig get pup mismatch");
00088 if (config.getVerbose(1))
00089 CmiPrintf("CCS getImageConfig> Sending a new client my configuration\n");
00090 CcsSendReply(len,buf);
00091 delete[] buf;
00092 CmiFree(msg);
00093 }
00094
00095
00096
00097
00098
00099
00100 extern "C" void getImageHandler(char * msg)
00101 {
00102 int msgLen=CmiSize(msg);
00103 char *buf=(char *)(msg+CmiMsgHeaderSizeBytes); msgLen-=CmiMsgHeaderSizeBytes;
00104 liveVizRequest o;
00105 PUP_toNetwork_unpack up(buf);
00106 o.pupNetwork(up);
00107 buf+=up.size(); msgLen-=up.size();
00108 int wid=o.wid,ht=o.ht;
00109
00110 if (config.getVerbose(2))
00111 CmiPrintf("CCS getImage> Request for (%d x %d) or (0x%x x 0x%x) pixel image.\n",
00112 wid,ht,wid,ht);
00113 if (msgLen<0) {
00114 CmiError("liveViz0 getImageHandler Rejecting too-short image request\n");
00115 return;
00116 }
00117
00118 o.replyToken = CcsDelayReply();
00119 liveViz0Get(o,buf,msgLen);
00120 CmiFree(msg);
00121 }
00122
00123
00124 #if CMK_USE_LIBJPEG
00125 #include <string>
00126 #include "jpeglib.h"
00127
00128
00129
00130 typedef struct {
00131 struct jpeg_destination_mgr pub;
00132
00133 std::string *stl_dest;
00134 JOCTET * buffer;
00135 } stl_destination_mgr;
00136
00137 typedef stl_destination_mgr * stl_dest_ptr;
00138
00139 #define OUTPUT_BUF_SIZE 4096
00140
00141 extern "C" void liveViz0_jpeg_stl_dest_init_destination (j_compress_ptr cinfo)
00142 {
00143 stl_dest_ptr dest = (stl_dest_ptr) cinfo->dest;
00144 dest->buffer = (JOCTET *)
00145 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
00146 OUTPUT_BUF_SIZE * sizeof(JOCTET));
00147 dest->pub.next_output_byte = dest->buffer;
00148 dest->pub.free_in_buffer = OUTPUT_BUF_SIZE;
00149 }
00150 extern "C" boolean liveViz0_jpeg_stl_dest_empty_output_buffer (j_compress_ptr cinfo)
00151 {
00152 stl_dest_ptr dest = (stl_dest_ptr) cinfo->dest;
00153
00154 dest->stl_dest->append((char *)dest->buffer,OUTPUT_BUF_SIZE);
00155
00156 dest->pub.next_output_byte = dest->buffer;
00157 dest->pub.free_in_buffer = OUTPUT_BUF_SIZE;
00158
00159 return TRUE;
00160 }
00161 extern "C" void liveViz0_jpeg_stl_dest_term_destination (j_compress_ptr cinfo)
00162 {
00163 stl_dest_ptr dest = (stl_dest_ptr) cinfo->dest;
00164 size_t datacount = OUTPUT_BUF_SIZE - dest->pub.free_in_buffer;
00165 dest->stl_dest->append((char *)dest->buffer,datacount);
00166 }
00167
00168 void jpeg_stl_dest(j_compress_ptr cinfo, std::string *stl_dest)
00169 {
00170 stl_dest_ptr dest;
00171
00172
00173
00174
00175
00176
00177
00178 if (cinfo->dest == NULL) {
00179 cinfo->dest = (struct jpeg_destination_mgr *)
00180 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
00181 sizeof(stl_destination_mgr));
00182 }
00183
00184 dest = (stl_dest_ptr) cinfo->dest;
00185 dest->pub.init_destination = liveViz0_jpeg_stl_dest_init_destination;
00186 dest->pub.empty_output_buffer = liveViz0_jpeg_stl_dest_empty_output_buffer;
00187 dest->pub.term_destination = liveViz0_jpeg_stl_dest_term_destination;
00188 dest->stl_dest = stl_dest;
00189 }
00190
00203 std::string JPEGcompressImage(int wid,int ht,int bpp, const byte *image_data, int quality) {
00204 struct jpeg_compress_struct cinfo;
00205 JSAMPROW row_pointer[1];
00206 int row_stride;
00207
00208 struct jpeg_error_mgr jerr;
00209 cinfo.err = jpeg_std_error(&jerr);
00210
00211 jpeg_create_compress(&cinfo);
00212
00213 std::string ret;
00214 jpeg_stl_dest(&cinfo,&ret);
00215
00216 cinfo.image_width = wid;
00217 cinfo.image_height = ht;
00218
00219 while (cinfo.image_height>65000) {
00220
00221
00222
00223
00224
00225
00226
00227 if (cinfo.image_height&1) {
00228 CkError("liveViz0 JPEGlib WARNING: cannot shrink odd image height %d\n",cinfo.image_height);
00229 }
00230 cinfo.image_height/=2;
00231 cinfo.image_width*=2;
00232 }
00233
00234
00235 switch (bpp) {
00236 case 1:
00237 cinfo.input_components = 1;
00238 cinfo.in_color_space = JCS_GRAYSCALE;
00239 break;
00240 case 3:
00241 cinfo.input_components = 3;
00242 cinfo.in_color_space = JCS_RGB;
00243 break;
00244 default:
00245 CkError("liveViz0's JPEGcompressImage: JPEGlib can only handle 1 or 3 bytes per pixel, not %d bpp\n",bpp);
00246 CkAbort("liveViz0's JPEGcompressImage: JPEGlib can only handle 1 or 3 bytes per pixel");
00247 break;
00248 }
00249
00250 jpeg_set_defaults(&cinfo);
00251 jpeg_set_quality(&cinfo, quality, TRUE );
00252 jpeg_start_compress(&cinfo, TRUE);
00253 row_stride = cinfo.image_width * bpp;
00254 while (cinfo.next_scanline < cinfo.image_height) {
00255 row_pointer[0] = (JSAMPLE *)(& image_data[cinfo.next_scanline * row_stride]);
00256 (void) jpeg_write_scanlines(&cinfo, row_pointer, 1);
00257 }
00258 jpeg_finish_compress(&cinfo);
00259 jpeg_destroy_compress(&cinfo);
00260 return ret;
00261 }
00262
00263 #endif
00264
00265 void liveViz0Deposit(const liveVizRequest &req,byte * imageData)
00266 {
00267 int len=req.wid*req.ht*config.getNetworkBytesPerPixel();
00268 if (config.getVerbose(2))
00269 CmiPrintf("CCS getImage> Reply for (%d x %d) pixel or %d byte image.\n",
00270 req.wid,req.ht,len);
00271 switch (req.compressionType) {
00272 case liveVizRequest::compressionNone:
00273 CcsSendDelayedReply(req.replyToken, len, imageData);
00274 break;
00275 #if CMK_USE_LIBJPEG
00276 case liveVizRequest::compressionJPEG: {
00277 std::string data=JPEGcompressImage(req.wid,req.ht,
00278 config.getNetworkBytesPerPixel(),imageData,
00279 req.compressionQuality);
00280 CcsSendDelayedReply(req.replyToken, data.size(), &data[0]);
00281 break;
00282 }
00283 #endif
00284 case liveVizRequest::compressionRunLength:
00285 {
00286 std::string data;
00287 for(int i=0; i<req.ht*req.wid;)
00288 {
00289 int j=i;
00290 while(imageData[j]==imageData[i]&&i-j<255&&i<req.ht*req.wid)
00291 i++;
00292 data.push_back((char)((i-j)&0xff));
00293 data.push_back(imageData[j]);
00294 }
00295 CcsSendDelayedReply(req.replyToken, data.size(), &data[0]);
00296 }
00297 break;
00298 default:
00299 CkError("liveViz0.C WARNING: Ignoring liveViz client's unrecognized compressionType %d\n",req.compressionType);
00300 CcsSendDelayedReply(req.replyToken, 0, 0);
00301 };
00302 }
00303
00304
00305
00306
00307 void liveViz0Init(const liveVizConfig &cfg) {
00308 config=cfg;
00309 CcsRegisterHandler("lvConfig",(CmiHandler)getImageConfigHandler);
00310 CcsRegisterHandler("lvImage", (CmiHandler)getImageHandler);
00311 if (config.getVerbose(1))
00312 CmiPrintf("CCS getImage handlers registered. Waiting for clients...\n");
00313 }
00314
00315 void liveViz0PollInit() {
00316 CcsRegisterHandler("lvImage", (CmiHandler)getImageHandler);
00317 if (config.getVerbose(1))
00318 CmiPrintf("CCS getImage handler registered. Waiting for clients...\n");
00319 }