LightWrap++
AC++wrapperfortheLightWave3DSDK
imageio_handler.h
Go to the documentation of this file.
1 #ifndef LWPP_IMAGEIO_HANDLER
2 #define LWPP_IMAGEIO_HANDLER
3 
4 #include <lwimageio.h>
5 #include <lwtypes.h>
6 #include <lwpp/lw_server.h>
7 #include <lwpp/monitor.h>
8 #include <lwpp/message.h>
9 #include <sstream>
10 
11 namespace lwpp
12 {
15  {
16  LWImageProtocolID prot;
17  int rc;
18  public:
19  ImageLoaderProtocol(LWImageProtocolID _prot)
20  : prot(_prot), rc(IPSTAT_OK)
21  {}
23  {
24 
25  }
26  LWImageProtocolID getID() const {return prot;}
27  bool isValid()
28  {
29  return prot != 0;
30  }
31  void Done()
32  {
33  if (prot) prot->done(prot->priv_data, rc);
34  }
36 
41  void SetSize (int w, int h)
42  {
43  if (prot) prot->setSize(prot->priv_data, w, h);
44  }
45 
46  int SetParam (LWImageParam param, const char *data)
47  {
48  if (prot) return prot->setParam(prot->priv_data, param, data);
49  return 0;
50  }
51 
52  int SetParam (LWImageParam param, const std::string data)
53  {
54  return SetParam(param, data.c_str());
55  }
56 
58 
67  int SendLine (int line, const LWPixelID pix)
68  {
69  if (prot)
70  return prot->sendLine(prot->priv_data, line, pix);
71  else
72  return IPSTAT_FAILED;
73  }
74 
75  void SetMap (int idx, const unsigned char col[3])
76  {
77  if (prot) return prot->setMap(prot->priv_data, idx, col);
78  }
79  };
80 
82  int type;
83  void *priv_data;
84  int (*done) (void *, int);
85  void (*setSize) (void *, int w, int h);
86  void (*setParam) (void *, LWImageParam, int, float);
87  int (*sendLine) (void *, int, const LWPixelID);
88  void (*setMap) (void *, int, const unsigned char[3]);
89  };
90 
92  int type;
93  void *priv_data;
94  int (*done) (void *, int);
95  void (*setSize) (void *, int w, int h);
96  int (*setParam) (void *, LWImageParam, const char*);
97  int (*sendLine) (void *, int, const LWPixelID);
98  void (*setMap) (void *, int, const unsigned char[3]);
99  };
100 
103  {
104  protected:
105  union
106  {
107  LWImageProtocol_V2 *protocol;
108  LWImageProtocol_V3 *protocol3;
109  };
110  //LWImageProtocol *protocol;
111  LWImageLoaderLocal *local;
113  int version;
114  void SetRC(int res) {local->result = res;}
115 
116  bool Begin (LWImageType type)
117  {
118  if (version == 2) protocol = (LWImageProtocol_V2 *)local->begin(local->priv_data, type);
119  else if (version == 3) protocol3 = (LWImageProtocol_V3 *)local->begin(local->priv_data, type);
120  return (protocol != 0);
121  }
122  int Done (int rc = IPSTAT_OK)
123  {
124  int ret = 0;
125  if (protocol) ret = protocol->done ((LWImageProtocolID)protocol->priv_data, rc);
126  if (protocol) local->done(local->priv_data, (LWImageProtocolID)protocol);
127  protocol = 0;
128  return ret;
129  }
130  void SetSize (int w, int h)
131  {
132  if (protocol) protocol->setSize(protocol->priv_data,w, h);
133  }
134  void SetParam (LWImageParam p, int i, float f)
135  {
136  if ((version == 2) && (protocol))
137  {
138  protocol->setParam(protocol->priv_data,p,i,f);
139  }
140  }
141  int SendLine (int y, const LWPixelID buffer)
142  {
143  if (protocol) return protocol->sendLine(protocol->priv_data,y,buffer);
144  return 0;
145  }
146  void SetMap (int index, const unsigned char colour[3] )
147  {
148  if (protocol) protocol->setMap(protocol->priv_data,index,colour);
149  }
150  public:
151  int SetParam (LWImageParam p, const char *c)
152  {
153  if ((version == 3) && (protocol3))
154  {
155  return protocol3->setParam(protocol->priv_data,p,c);
156  }
157  return 0;
158  }
159  int SetParam (LWImageParam p, const std::string str)
160  {
161  if ((version == 3) && (protocol3))
162  {
163  return protocol3->setParam(protocol->priv_data,p,str.c_str());
164  }
165  return 0;
166  }
167  int SetParam (LWImageParam p, int i)
168  {
169  if ((version == 3) && (protocol3))
170  {
171  std::ostringstream ss;
172  ss << i;
173  return SetParam(p, ss.str());
174  }
175  return 0;
176  }
177  int SetParam (LWImageParam p, double d)
178  {
179  if ((version == 3) && (protocol3))
180  {
181  std::ostringstream ss;
182  ss << d;
183  return SetParam(p, ss.str());
184  }
185  return 0;
186  }
187  ImageLoaderHandler() : protocol(0), local(0), monitor(0), version(0) {}
188  void InitHandler(LWImageLoaderLocal *l, int ver)
189  {
190  version = ver;
191  local = l;
192  monitor.setMonitor(local->monitor);
193  }
194  virtual ~ImageLoaderHandler() {Done();}
195 
196  virtual int LoadImage(const char *filename) = 0;
197  };
198 
200  template <class T>
202  {
203  public:
204  ImageLoaderAdaptor(const char *name, ServerTagInfo *tags)
205  {
206  LWServer::AddPlugin(LWIMAGELOADER_CLASS, name, Activate, tags);
207  }
209  static int Activate( int version, GlobalFunc *global, void *l, void *serverData )
210  {
211  if (version > LWPP_IMAGELOADER_VERSION) return AFUNC_BADVERSION;
212  try
213  {
214  lwpp::SetSuperGlobal(global);
215  LWImageLoaderLocal *local = static_cast<LWImageLoaderLocal *>(l);
216  T loader;
217  loader.InitHandler(local, version);
218  return loader.LoadImage(local->filename);
219  }
220  catch (std::exception &e)
221  {
222  lwpp::LWMessage::Error("An exception occured when attempting to load an image:", e.what());
223  return AFUNC_BADAPP_SILENT;
224  }
225  }
226  };
227 
228  /*
229  * Image Saver
230  */
231 
234  {
235  protected:
236  union
237  {
238  LWImageProtocol_V2 protocol;
239  LWImageProtocol_V3 protocol3;
240  };
241  int version;
242  LWImageSaverLocal *local;
244  int width, height;
245  const char *fileName;
246  void SetRC(int res) {local->result = res;}
247 
248  static int CBdone(LWInstance inst, int rc)
249  {
250  try
251  {
252  ImageSaverHandler *saver = static_cast<ImageSaverHandler *>(inst);
253  saver->monitor.Done();
254  return saver->Done(rc);
255  }
256  catch (std::exception &e)
257  {
258  lwpp::LWMessage::Error("An exception occured in ImageSaver::Done():", e.what());
259  return IPSTAT_FAILED;
260  }
261  }
262  static void CBsetSize(LWInstance inst, int w, int h)
263  {
264  try
265  {
266  ImageSaverHandler *saver = static_cast<ImageSaverHandler *>(inst);
267  saver->monitor.Init(h);
268  saver->SetSize(w, h);
269  }
270  catch (std::exception &e)
271  {
272  lwpp::LWMessage::Error("An exception occured in ImageSaver::SetSize():", e.what());
273  return;
274  }
275  }
276  static void CBsetParam(LWInstance inst, LWImageParam p, int i, float f)
277  {
278  try
279  {
280  ImageSaverHandler *saver = static_cast<ImageSaverHandler *>(inst);
281  saver->SetParam(p, i, f);
282  }
283  catch (std::exception &e)
284  {
285  lwpp::LWMessage::Error("An exception occured in ImageSaver::SetParam():", e.what());
286  return ;
287  }
288  }
289  static int CBsetParam3(LWInstance inst, LWImageParam p, const char *c)
290  {
291  try
292  {
293  ImageSaverHandler *saver = static_cast<ImageSaverHandler *>(inst);
294  return saver->SetParam(p, c);
295  }
296  catch (std::exception &e)
297  {
298  lwpp::LWMessage::Error("An exception occured in ImageSaver::SetParam():", e.what());
299  return 0;
300  }
301  }
302  static int CBsendLine(LWInstance inst, int y, const LWPixelID pixel)
303  {
304  try
305  {
306  ImageSaverHandler *saver = static_cast<ImageSaverHandler *>(inst);
307  saver->monitor.Step();
308  return saver->SendLine(y, pixel);
309  }
310  catch (std::exception &e)
311  {
312  lwpp::LWMessage::Error("An exception occured in ImageSaver::SendLine():", e.what());
313  return IPSTAT_FAILED;
314  }
315  }
316  static void CBsetMap(LWInstance inst, int index, const unsigned char rgb[3])
317  {
318  try
319  {
320  ImageSaverHandler *saver = static_cast<ImageSaverHandler *>(inst);
321  saver->SetMap(index, rgb);
322  }
323  catch (std::exception &e)
324  {
325  lwpp::LWMessage::Error("An exception occured in ImageSaver::SetMap():", e.what());
326  return;
327  }
328  }
329 
330  virtual int SendData (int flags = 0)
331  {
332  // init Protocol
333  if (version == 2)
334  {
335  protocol.type = local->type;
336  protocol.priv_data = this;
337  protocol.done = CBdone;
338  protocol.setSize = CBsetSize;
339  protocol.setParam = CBsetParam;
340  protocol.sendLine = CBsendLine;
341  protocol.setMap = CBsetMap;
342  return local->sendData (local->priv_data, reinterpret_cast<LWImageProtocolID>(&protocol), flags);
343  }
344  else if (version == 3)
345  {
346  protocol3.type = local->type;
347  protocol3.priv_data = this;
348  protocol3.done = CBdone;
349  protocol3.setSize = CBsetSize;
350  protocol3.setParam = CBsetParam3;
351  protocol3.sendLine = CBsendLine;
352  protocol3.setMap = CBsetMap;
353  return local->sendData (local->priv_data, reinterpret_cast<LWImageProtocolID>(&protocol3), flags);
354  }
355  else return IPSTAT_FAILED;
356  }
357  public:
358  ImageSaverHandler(int v, LWImageSaverLocal *l)
359  : version (v), local(0), monitor(0), width(0), height(0), fileName(0)
360  {
361  local = l;
362  monitor.setMonitor(local->monitor);
363  }
364  virtual ~ImageSaverHandler() {}
365  virtual int SaveImage(const char *filename)
366  {
367  try
368  {
369  fileName = filename;
370  SetRC(IPSTAT_OK);
371  int rc = SendData(0);
372  SetRC(rc);
373  //if (rc == IPSTAT_OK)
374  return AFUNC_OK;
375  //else return
376  }
377  catch (std::exception &e)
378  {
379  SetRC(IPSTAT_FAILED);
380  throw;
381  }
382  }
383 
384  virtual void SetSize (int w, int h)
385  {
386  width = w;
387  height = h;
388  }
389  virtual int Done(int rc)
390  {
391  return rc;
392  }
393  virtual void SetParam (LWImageParam p, int i, float f) {}
394  virtual int SetParam (LWImageParam p, const char *c) {return 0;}
395 
396  virtual int SendLine (int y, const LWPixelRGB24 *buffer){return IPSTAT_OK;}
397  virtual int SendLine (int y, const LWPixelRGBFP *buffer) {return IPSTAT_OK;}
398  virtual int SendLine (int y, const LWPixelRGBA32 *buffer) {return IPSTAT_OK;}
399  virtual int SendLine (int y, const LWPixelRGBAFP *buffer) {return IPSTAT_OK;}
400  virtual int SendLine (int y, const float *buffer) {return IPSTAT_OK;}
401  virtual int SendLine (int y, const unsigned char *buffer) {return IPSTAT_OK;}
402  virtual int PreSendLine (int y) {return IPSTAT_OK;}
403  virtual int PostSendLine (int y) {return IPSTAT_OK;}
404  virtual int SendLine (int y, const LWPixelID buffer)
405  {
406  int rc = PreSendLine(y);
407  if (rc != IPSTAT_OK) return rc;
408  switch (protocol.type)
409  {
410  case LWIMTYP_GREY8:
411  case LWIMTYP_INDEX8:
412  rc = SendLine(y, static_cast<const unsigned char*>(buffer));
413  break;
414 
415  case LWIMTYP_RGB24:
416  rc = SendLine(y, static_cast<const LWPixelRGB24 *>(buffer));
417  break;
418 
419  case LWIMTYP_RGBA32:
420  rc = SendLine(y, static_cast<const LWPixelRGBA32 *>(buffer));
421  break;
422 
423  case LWIMTYP_GREYFP:
424  rc = SendLine(y, static_cast<const float *>(buffer));
425  break;
426 
427  case LWIMTYP_RGBFP:
428  rc = SendLine(y, static_cast<const LWPixelRGBFP *>(buffer));
429  break;
430 
431  case LWIMTYP_RGBAFP:
432  rc = SendLine(y, static_cast<const LWPixelRGBAFP *>(buffer));
433  break;
434 
435  default:
436  return IPSTAT_FAILED;
437  break;
438  }
439  if (rc != IPSTAT_OK) return rc;
440  return PostSendLine(y);
441  }
442  virtual void SetMap (int index, const unsigned char colour[3] ) {}
443 
444  };
445 
447  template <class T>
449  {
450  public:
451  ImageSaverAdaptor(const char *name, ServerTagInfo *tags)
452  {
453  LWServer::AddPlugin(LWIMAGESAVER_CLASS, name, Activate, tags);
454  }
456  static int Activate( int version, GlobalFunc *global, void *l, void *serverData )
457  {
458  if ((version < LWPP_IMAGESAVER_VERSION) || (version > 3)) return AFUNC_BADVERSION;
459  try
460  {
461  lwpp::SetSuperGlobal(global);
462  LWImageSaverLocal *local = static_cast<LWImageSaverLocal *>(l);
463  T saver(version, local);
464  return saver.SaveImage(local->filename);
465  }
466  catch (std::exception &e)
467  {
468  lwpp::LWMessage::Error("An exception occured when attempting to save an image:", e.what());
469  return AFUNC_BADAPP_SILENT;
470  }
471  }
472  };
473 
474 }
475 
476 #endif // LWPP_IMAGEIO_HANDLER