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