vrpn  07.33
Virtual Reality Peripheral Network
vrpn_Imager.h
Go to the documentation of this file.
1 // ImagerControl (should be built into Imager, because it will always
2 // be the same device). The app doesn't have to use all of the
3 // functions if they don't want to.
4 // XXX Client can sent request for only subregion of image to be sent
5 // Server may ignore this message.
6 // XXX Server sets region back to total region when last connection closed.
7 // XXX Client can request a frame rate from the server. This is passed on
8 // to the server code as a handled message. Server should reset to the
9 // default when the last connection is closed.
10 // XXX Binning
11 // XXX integration times
12 // XXX Which data sets to send (nano)
13 
14 // ImagerPose (may be a separate physical device from the imager)
15 // XXX Lets client request new pose for imager
16 
17 // XXX When transcoding to a lower-bitcount resolution, should we
18 // adjust the scale and offset to make best use of the bits? Perhaps
19 // a local and a global scale and offset?
20 
21 #ifndef VRPN_IMAGER_H
22 #define VRPN_IMAGER_H
23 #include <stdio.h> // for fprintf, stderr
24 #include <string.h> // for NULL, memcpy
25 
26 #include "vrpn_BaseClass.h" // for vrpn_Callback_List, etc
27 #include "vrpn_Configure.h" // for VRPN_CALLBACK, VRPN_API
28 #include "vrpn_Connection.h"
29 #include "vrpn_Shared.h" // for vrpn_buffer, vrpn_unbuffer, etc
30 #include "vrpn_Types.h" // for vrpn_uint16, vrpn_int32, etc
31 
32 const unsigned vrpn_IMAGER_MAX_CHANNELS = 100;
33 
37 const unsigned vrpn_IMAGER_MAX_REGIONu8 =
38  (vrpn_CONNECTION_TCP_BUFLEN - 8 * sizeof(vrpn_int16) -
39  6 * sizeof(vrpn_int32)) /
40  sizeof(vrpn_uint8);
41 const unsigned vrpn_IMAGER_MAX_REGIONu16 =
42  (vrpn_CONNECTION_TCP_BUFLEN - 8 * sizeof(vrpn_int16) -
43  6 * sizeof(vrpn_int32)) /
44  sizeof(vrpn_uint16);
46 const unsigned vrpn_IMAGER_MAX_REGIONf32 =
47  (vrpn_CONNECTION_TCP_BUFLEN - 8 * sizeof(vrpn_int16) -
48  6 * sizeof(vrpn_int32)) /
49  sizeof(vrpn_float32);
50 
54  friend class vrpn_Imager_Remote; // provides access to compression status
55  friend class vrpn_Imager_Server; // provides access to compression status
56  friend class vrpn_Imager_Stream_Buffer; // provides access to
57  // buffer/unbuffer
58 public:
60  {
61  name[0] = '\0';
62  units[0] = '\0';
63  minVal = maxVal = 0.0;
64  scale = 1;
65  offset = 0;
66  d_compression = NONE;
67  };
68 
69  cName name; //< Name of the data set stored in this channel
70  cName units; //< Units for the data set stored in this channel
71  vrpn_float32 minVal,
72  maxVal; //< Range of possible values for pixels in this channel
73  vrpn_float32 offset,
74  scale; //< Values in units are (raw_values * scale) + offset
75 
76 protected:
77  // The following methods are here for the derived classes and are not
78  // relevant
79  // to user code.
80  inline bool buffer(char **insertPt, vrpn_int32 *buflen) const
81  {
82  if (vrpn_buffer(insertPt, buflen, minVal) ||
83  vrpn_buffer(insertPt, buflen, maxVal) ||
84  vrpn_buffer(insertPt, buflen, offset) ||
85  vrpn_buffer(insertPt, buflen, scale) ||
86  vrpn_buffer(insertPt, buflen, (vrpn_uint32)d_compression) ||
87  vrpn_buffer(insertPt, buflen, name, sizeof(name)) ||
88  vrpn_buffer(insertPt, buflen, units, sizeof(units))) {
89  return false;
90  }
91  else {
92  return true;
93  }
94  }
95 
96  inline bool unbuffer(const char **buffer)
97  {
98  vrpn_uint32 compression;
99  if (vrpn_unbuffer(buffer, &minVal) || vrpn_unbuffer(buffer, &maxVal) ||
100  vrpn_unbuffer(buffer, &offset) || vrpn_unbuffer(buffer, &scale) ||
101  vrpn_unbuffer(buffer, &compression) ||
102  vrpn_unbuffer(buffer, name, sizeof(name)) ||
103  vrpn_unbuffer(buffer, units, sizeof(units))) {
104  return false;
105  }
106  else {
107  d_compression = (ChannelCompression)compression;
108  return true;
109  }
110  }
111 
112  typedef enum { NONE = 0 } ChannelCompression;
114 };
115 
118 public:
119  vrpn_Imager(const char *name, vrpn_Connection *c = NULL);
120 
121  // Data member accessors.
122  vrpn_int32 nRows(void) const { return d_nRows; };
123  vrpn_int32 nCols(void) const { return d_nCols; };
124  vrpn_int32 nDepth(void) const { return d_nDepth; };
125  vrpn_int32 nChannels(void) const { return d_nChannels; };
126 
127 protected:
128  vrpn_int32 d_nRows; //< Number of rows in the image
129  vrpn_int32 d_nCols; //< Number of columns in the image
130  vrpn_int32 d_nDepth; //< Number of depth stacks in the image
131  vrpn_int32 d_nChannels; //< Number of image data channels
133 
134  virtual int register_types(void);
135  vrpn_int32 d_description_m_id; //< ID of the message type describing the
136  // range and channels
137  vrpn_int32 d_begin_frame_m_id; //< ID of the message type describing the
138  // start of a region
139  vrpn_int32 d_end_frame_m_id; //< ID of the message type describing the start
140  // of a region
141  vrpn_int32 d_discarded_frames_m_id; //< ID of the message type describing
142  // the discarding of one or more regions
143  vrpn_int32 d_throttle_frames_m_id; //< ID of the message type requesting
144  // throttling of sending.
145  vrpn_int32 d_regionu8_m_id; //< ID of the message type describing a region
146  // with 8-bit unsigned entries
147  vrpn_int32 d_regionu12in16_m_id; //< ID of the message type describing a
148  // region with 12-bit unsigned entries
149  // packed in 16 bits
150  vrpn_int32 d_regionu16_m_id; //< ID of the message type describing a region
151  // with 16-bit unsigned entries
152  vrpn_int32 d_regionf32_m_id; //< ID of the message type describing a region
153  // with 32-bit float entries
154 };
155 
157 public:
158  vrpn_Imager_Server(const char *name, vrpn_Connection *c, vrpn_int32 nCols,
159  vrpn_int32 nRows, vrpn_int32 nDepth = 1);
160 
163  int add_channel(const char *name, const char *units = "unsigned8bit",
164  vrpn_float32 minVal = 0, vrpn_float32 maxVal = 255,
165  vrpn_float32 scale = 1, vrpn_float32 offset = 0);
166 
169  // to provide hints to the client about when to refresh displays and such.
170  // If they can determine when frames are missed, they should also send a
171  // description of missed frames, telling how many are skipped (default of
172  // zero means "some but don't know how many").
173  bool send_begin_frame(const vrpn_uint16 cMin, const vrpn_uint16 cMax,
174  const vrpn_uint16 rMin, const vrpn_uint16 rMax,
175  const vrpn_uint16 dMin = 0,
176  const vrpn_uint16 dMax = 0,
177  const struct timeval *time = NULL);
178  bool send_end_frame(const vrpn_uint16 cMin, const vrpn_uint16 cMax,
179  const vrpn_uint16 rMin, const vrpn_uint16 rMax,
180  const vrpn_uint16 dMin = 0, const vrpn_uint16 dMax = 0,
181  const struct timeval *time = NULL);
182  bool send_discarded_frames(const vrpn_uint16 count = 0,
183  const struct timeval *time = NULL);
184 
187  // These functions each take a pointer to the base of the image to be sent:
188  // its [0,0] element.
189  // If rows are being inverted, then we need to know how many rows there are
190  // in the total image.
191  bool send_region_using_base_pointer(
192  vrpn_int16 chanIndex, vrpn_uint16 cMin, vrpn_uint16 cMax,
193  vrpn_uint16 rMin, vrpn_uint16 rMax, const vrpn_uint8 *data,
194  vrpn_uint32 colStride, vrpn_uint32 rowStride, vrpn_uint16 nRows = 0,
195  bool invert_rows = false, vrpn_uint32 depthStride = 0,
196  vrpn_uint16 dMin = 0, vrpn_uint16 dMax = 0,
197  const struct timeval *time = NULL);
198  bool send_region_using_base_pointer(
199  vrpn_int16 chanIndex, vrpn_uint16 cMin, vrpn_uint16 cMax,
200  vrpn_uint16 rMin, vrpn_uint16 rMax, const vrpn_uint16 *data,
201  vrpn_uint32 colStride, vrpn_uint32 rowStride, vrpn_uint16 nRows = 0,
202  bool invert_rows = false, vrpn_uint32 depthStride = 0,
203  vrpn_uint16 dMin = 0, vrpn_uint16 dMax = 0,
204  const struct timeval *time = NULL);
205  bool send_region_using_base_pointer(
206  vrpn_int16 chanIndex, vrpn_uint16 cMin, vrpn_uint16 cMax,
207  vrpn_uint16 rMin, vrpn_uint16 rMax, const vrpn_float32 *data,
208  vrpn_uint32 colStride, vrpn_uint32 rowStride, vrpn_uint16 nRows = 0,
209  bool invert_rows = false, vrpn_uint32 depthStride = 0,
210  vrpn_uint16 dMin = 0, vrpn_uint16 dMax = 0,
211  const struct timeval *time = NULL);
212 
215  // These functions each take a pointer to the first of the data values to be
216  // sent. This is a
217  // pointer to the [cMin, rMin] element of the image to be sent. Note that
218  // if the Y value is inverted,
219  // this will NOT be a pointer to the beginning of the data block, but rather
220  // the the beginning of
221  // the last line in the data block. Note that rowStride will be less than
222  // the number of rows in the
223  // whole image if the data is tightly packed into a block and the region
224  // does not cover all columns.
225  bool send_region_using_first_pointer(
226  vrpn_int16 chanIndex, vrpn_uint16 cMin, vrpn_uint16 cMax,
227  vrpn_uint16 rMin, vrpn_uint16 rMax, const vrpn_uint8 *data,
228  vrpn_uint32 colStride, vrpn_uint32 rowStride, vrpn_uint16 nRows = 0,
229  bool invert_rows = false, vrpn_uint32 depthStride = 0,
230  vrpn_uint16 dMin = 0, vrpn_uint16 dMax = 0,
231  const struct timeval *time = NULL);
232  bool send_region_using_first_pointer(
233  vrpn_int16 chanIndex, vrpn_uint16 cMin, vrpn_uint16 cMax,
234  vrpn_uint16 rMin, vrpn_uint16 rMax, const vrpn_uint16 *data,
235  vrpn_uint32 colStride, vrpn_uint32 rowStride, vrpn_uint16 nRows = 0,
236  bool invert_rows = false, vrpn_uint32 depthStride = 0,
237  vrpn_uint16 dMin = 0, vrpn_uint16 dMax = 0,
238  const struct timeval *time = NULL);
239  bool send_region_using_first_pointer(
240  vrpn_int16 chanIndex, vrpn_uint16 cMin, vrpn_uint16 cMax,
241  vrpn_uint16 rMin, vrpn_uint16 rMax, const vrpn_float32 *data,
242  vrpn_uint32 colStride, vrpn_uint32 rowStride, vrpn_uint16 nRows = 0,
243  bool invert_rows = false, vrpn_uint32 depthStride = 0,
244  vrpn_uint16 dMin = 0, vrpn_uint16 dMax = 0,
245  const struct timeval *time = NULL);
246 
249  bool set_resolution(vrpn_int32 nCols, vrpn_int32 nRows,
250  vrpn_int32 nDepth = 1);
251 
254  bool send_description(void);
255 
257  virtual void mainloop(void);
258 
259 protected:
260  bool d_description_sent; //< Has the description message been sent?
261  vrpn_int32 d_frames_to_send; //< Set to -1 if continuous, zero or positive
262  // tells how many to send and then start
263  // dropping
264  vrpn_uint16 d_dropped_due_to_throttle; //< Number of frames dropped due to
265  // the throttle request
266 
267  // This method makes sure we send a description whenever we get a ping from
268  // a client object.
269  static int VRPN_CALLBACK
270  handle_ping_message(void *userdata, vrpn_HANDLERPARAM p);
271 
272  // This method handles requests to throttle the number of frames.
273  static int VRPN_CALLBACK
274  handle_throttle_message(void *userdata, vrpn_HANDLERPARAM p);
275  static int VRPN_CALLBACK
276  handle_last_drop_message(void *userdata, vrpn_HANDLERPARAM p);
277 };
278 
280 public:
281  vrpn_ImagerPose(const char *name, vrpn_Connection *c = NULL);
282 
284  // the location of the corner of the (0,0,0) pixel. Note that
285  // the pixel coordinate is centered in that pixel, but that the
286  // pixel extends a half-pixel into the "negative" coordinates.
287  void get_origin(vrpn_float64 *origin) const
288  {
289  memcpy(origin, d_origin, sizeof(d_origin));
290  }
291 
293  // it is how far and in what direction to go from the origin
294  // of the image to one pixel past the pixel at the end of
295  // the column that (0,0,0) is in: this is the total image
296  // width.
297  void get_dCol(vrpn_float64 *dCol) const
298  {
299  memcpy(dCol, d_dCol, sizeof(d_dCol));
300  }
301 
303  // it is how far and in what direction to go from the origin
304  // of the image to one pixel past the pixel at the end of
305  // the row that (0,0,0) is in: this is the total image height.
306  void get_dRow(vrpn_float64 *dRow) const
307  {
308  memcpy(dRow, d_dRow, sizeof(d_dRow));
309  }
310 
312  // it is how far and in what direction to go from the origin
313  // of the image to one pixel past the pixel at the end of
314  // the depth pixel that (0,0,0) is in: this is the total
315  // image depth.
316  void get_dDepth(vrpn_float64 *dDepth) const
317  {
318  memcpy(dDepth, d_dDepth, sizeof(d_dDepth));
319  }
320 
322  // pixel within the image, assuming that the image covers the
323  // space described by this imagerpose. Note that none of the pixel
324  // centers will be at the end of the space, except where the image
325  // has no dimension (Z for a 2D image). Returns false if there is
326  // a problem (coordinates out of bounds).
327  bool compute_pixel_center(vrpn_float64 *center, const vrpn_Imager &image,
328  vrpn_uint16 col, vrpn_uint16 row,
329  vrpn_uint16 depth = 0);
330 
331 protected:
332  vrpn_float64 d_origin[3]; //< Origin, pixel (0,0,0) in meters
333  vrpn_float64
334  d_dCol[3]; //< End of first columne in coordinate system in meters
335  vrpn_float64 d_dRow[3]; //< End of first row in coordinate system in meters
336  vrpn_float64 d_dDepth[3]; //< End of depth in coordinate system in meters
337 
338  virtual int register_types(void);
339  vrpn_int32 d_description_m_id; //< ID of the message type describing the
340  // range and channels
341 };
342 
344 public:
345  vrpn_ImagerPose_Server(const char *name, const vrpn_float64 origin[3],
346  const vrpn_float64 dCol[3],
347  const vrpn_float64 dRow[3],
348  const vrpn_float64 *dDepth = NULL,
349  vrpn_Connection *c = NULL);
350 
352  bool set_range(const vrpn_float64 origin[3], const vrpn_float64 dCol[3],
353  const vrpn_float64 dRow[3],
354  const vrpn_float64 *dDepth = NULL);
355 
358  bool send_description(void);
359 
361  virtual void mainloop(void);
362 
363 protected:
364  // This method makes sure we send a description whenever we get a ping from
365  // a client object.
366  static int VRPN_CALLBACK
367  handle_ping_message(void *userdata, vrpn_HANDLERPARAM p);
368 };
369 
370 //------------------------------------------------------------------------------
371 // Users deal with things below this line.
372 
373 //------------------------------------------------------------------------------
374 // Imager_Remote is used for passing image values (pixels), converting them
375 // to physical units, and saying when regions are started and finished.
376 
377 const vrpn_uint16 vrpn_IMAGER_VALTYPE_UNKNOWN = 0;
378 const vrpn_uint16 vrpn_IMAGER_VALTYPE_UINT8 = 1;
379 // XXX Bad idea -- do not do this! const vrpn_uint16
380 // vrpn_IMAGER_VALTYPE_UINT8RGB = 2; // Placeholder
381 // XXX Bad idea -- do not do this! const vrpn_uint16
382 // vrpn_IMAGER_VALTYPE_UINT8BGR = 3; // Placeholder
383 const vrpn_uint16 vrpn_IMAGER_VALTYPE_UINT16 = 4;
384 const vrpn_uint16 vrpn_IMAGER_VALTYPE_UINT12IN16 = 5;
385 const vrpn_uint16 vrpn_IMAGER_VALTYPE_FLOAT32 = 6;
386 
388 
389 typedef struct _vrpn_IMAGERREGIONCB {
390  struct timeval msg_time; //< Timestamp of the region data's change
391  const vrpn_Imager_Region *region; //< New region of the image
393 
395  void *userdata, const vrpn_IMAGERREGIONCB info);
396 // There is no data in the description callback other than the time; the
397 // data members for the class will have been filled in, so the client should
398 // call nRows() and other functions to read the new values.
400  void *userdata, const struct timeval msg_time);
401 
402 typedef struct _vrpn_IMAGERBEGINFRAMECB {
403  struct timeval msg_time; //< Timestamp of the begin-frame message
404  vrpn_uint16 rMin; //< Minimum row in the frame
405  vrpn_uint16 rMax; //< Maximum row in the frame
406  vrpn_uint16 cMin; //< Minimum column in the frame
407  vrpn_uint16 cMax; //< Maximum column in the frame
408  vrpn_uint16 dMin; //< Minimum depth in the frame
409  vrpn_uint16 dMax; //< Maximum depth in the frame
411 
412 typedef struct _vrpn_IMAGERENDFRAMECB {
413  struct timeval msg_time; //< Timestamp of the end-frame message
414  vrpn_uint16 rMin; //< Minimum row in the frame
415  vrpn_uint16 rMax; //< Maximum row in the frame
416  vrpn_uint16 cMin; //< Minimum column in the frame
417  vrpn_uint16 cMax; //< Maximum column in the frame
418  vrpn_uint16 dMin; //< Minimum depth in the frame
419  vrpn_uint16 dMax; //< Maximum depth in the frame
421 
422 typedef struct _vrpn_IMAGERDISCARDEDFRAMESCB {
423  struct timeval msg_time; //< Timestamp of the begin-frame message
424  vrpn_uint16 count; //< Number of discarded frames (0 means "1 or more")
426 
428  void *userdata, const vrpn_IMAGERBEGINFRAMECB info);
430  void *userdata, const vrpn_IMAGERENDFRAMECB info);
432  void *userdata, const vrpn_IMAGERDISCARDEDFRAMESCB info);
433 
435 // the image. This is passed to the user callback handler and aids in
436 // getting values out of the buffer. The region is only valid during
437 // the actual callback handler, so users should not store pointers to
438 // it for later use.
441  friend void VRPN_CALLBACK
442  java_vrpn_handle_region_change(void *userdata,
443  const vrpn_IMAGERREGIONCB info);
444 
445 public:
447  {
448  d_chanIndex = -1;
449  d_rMin = d_rMax = d_cMin = d_cMax = 0;
450  d_valBuf = NULL;
451  d_valType = vrpn_IMAGER_VALTYPE_UNKNOWN;
452  d_valid = false;
453  }
454 
456  inline vrpn_uint32 getNumVals() const
457  {
458  if (!d_valid) {
459  return 0;
460  }
461  else {
462  return (d_rMax - d_rMin + 1) * (d_cMax - d_cMin + 1);
463  }
464  }
465 
470  inline bool read_unscaled_pixel(vrpn_uint16 c, vrpn_uint16 r,
471  vrpn_uint8 &val, vrpn_uint16 d = 0) const
472  {
473  if (!d_valid || (c < d_cMin) || (c > d_cMax) || (r < d_rMin) ||
474  (r > d_rMax)) {
475  fprintf(stderr, "vrpn_Imager_Region::read_unscaled_pixel(): "
476  "Invalid region or out of range\n");
477  return false;
478  }
479  else {
480  if (d_valType != vrpn_IMAGER_VALTYPE_UINT8) {
481  fprintf(stderr, "XXX "
482  "vrpn_Imager_Region::read_unscaled_pixel(): "
483  "Transcoding not implemented yet\n");
484  return false;
485  }
486  else {
487  // The data is packed in with column varying fastest, row
488  // varying next, and depth
489  // varying slowest. Depth steps are therefore the largest
490  // steps.
491  val =
492  ((vrpn_uint8 *)
493  d_valBuf)[(c - d_cMin) +
494  (d_cMax - d_cMin + 1) *
495  ((r - d_rMin) +
496  (d - d_dMin) * (d_rMax - d_rMin + 1))];
497  }
498  }
499  return true;
500  }
501 
504  // the most efficient way to read the pixels out -- use the block read
505  // routines.
506  inline bool read_unscaled_pixel(vrpn_uint16 c, vrpn_uint16 r,
507  vrpn_uint16 &val, vrpn_uint16 d = 0) const
508  {
509  if (!d_valid || (d < d_dMin) || (d > d_dMax) || (c < d_cMin) ||
510  (c > d_cMax) || (r < d_rMin) || (r > d_rMax)) {
511  fprintf(stderr, "vrpn_Imager_Region::read_unscaled_pixel(): "
512  "Invalid region or out of range\n");
513  return false;
514  }
515  else {
516  if ((d_valType != vrpn_IMAGER_VALTYPE_UINT16) &&
517  (d_valType != vrpn_IMAGER_VALTYPE_UINT12IN16)) {
518  fprintf(stderr, "XXX "
519  "vrpn_Imager_Region::read_unscaled_pixel(): "
520  "Transcoding not implemented yet\n");
521  return false;
522  }
523  else if (vrpn_big_endian) {
524  fprintf(stderr, "XXX "
525  "vrpn_Imager_Region::read_unscaled_pixel(): "
526  "Not implemented on big-endian yet\n");
527  return false;
528  }
529  else {
530  // The data is packed in with column varying fastest, row
531  // varying next, and depth
532  // varying slowest. Depth steps are therefore the largest
533  // steps.
534  val =
535  ((vrpn_uint16 *)
536  d_valBuf)[(c - d_cMin) +
537  (d_cMax - d_cMin + 1) *
538  ((r - d_rMin) +
539  (d - d_dMin) * (d_rMax - d_rMin + 1))];
540  }
541  }
542  return true;
543  }
544 
547  // the most efficient way to read the pixels out -- use the block read
548  // routines.
549  inline bool read_unscaled_pixel(vrpn_uint16 c, vrpn_uint16 r,
550  vrpn_float32 &val, vrpn_uint16 d = 0) const
551  {
552  if (!d_valid || (d < d_dMin) || (d > d_dMax) || (c < d_cMin) ||
553  (c > d_cMax) || (r < d_rMin) || (r > d_rMax)) {
554  fprintf(stderr, "vrpn_Imager_Region::read_unscaled_pixel(): "
555  "Invalid region or out of range\n");
556  return false;
557  }
558  else {
559  if (d_valType != vrpn_IMAGER_VALTYPE_FLOAT32) {
560  fprintf(stderr, "XXX "
561  "vrpn_Imager_Region::read_unscaled_pixel(): "
562  "Transcoding not implemented yet\n");
563  return false;
564  }
565  else if (vrpn_big_endian) {
566  fprintf(stderr, "XXX "
567  "vrpn_Imager_Region::read_unscaled_pixel(): "
568  "Not implemented on big-endian yet\n");
569  return false;
570  }
571  else {
572  // The data is packed in with column varying fastest, row
573  // varying next, and depth
574  // varying slowest. Depth steps are therefore the largest
575  // steps.
576  val =
577  ((vrpn_float32 *)
578  d_valBuf)[(c - d_cMin) +
579  (d_cMax - d_cMin + 1) *
580  ((r - d_rMin) +
581  (d - d_dMin) * (d_rMax - d_rMin + 1))];
582  }
583  }
584  return true;
585  }
586 
587  // Bulk read routines to copy the whole region right into user structures as
588  // efficiently as possible.
589  bool decode_unscaled_region_using_base_pointer(
590  vrpn_uint8 *data, vrpn_uint32 colStride, vrpn_uint32 rowStride,
591  vrpn_uint32 depthStride = 0, vrpn_uint16 nRows = 0,
592  bool invert_rows = false, unsigned repeat = 1) const;
593  // This routine also reads 12-bits-in-16-bit values.
594  bool decode_unscaled_region_using_base_pointer(
595  vrpn_uint16 *data, vrpn_uint32 colStride, vrpn_uint32 rowStride,
596  vrpn_uint32 depthStride = 0, vrpn_uint16 nRows = 0,
597  bool invert_rows = false, unsigned repeat = 1) const;
598  bool decode_unscaled_region_using_base_pointer(
599  vrpn_float32 *data, vrpn_uint32 colStride, vrpn_uint32 rowStride,
600  vrpn_uint32 depthStride = 0, vrpn_uint16 nRows = 0,
601  bool invert_rows = false, unsigned repeat = 1) const;
602 
603  // XXX Add routines to read scaled pixels. Clamp values.
604 
605  // Report the type of the values stored in the region. The above routines
606  // use this to decode automatically, but user code may want to do different
607  // things with different types of data.
608  vrpn_uint16 get_val_type(void) const { return d_valType; }
609 
610  vrpn_int16 d_chanIndex; //< Which channel this region holds data for
611  vrpn_uint16 d_rMin, d_rMax; //< Range of indices for the rows
612  vrpn_uint16 d_cMin, d_cMax; //< Range of indices for the columns
613  vrpn_uint16 d_dMin, d_dMax; //< Range of indices for the depth
614 
615 protected:
616  const void *d_valBuf; //< Pointer to the buffer of values
617  vrpn_uint16 d_valType; //< Type of the values in the buffer
618  bool d_valid; //< Tells whether the helper can be used.
619 };
620 
624 public:
625  vrpn_Imager_Remote(const char *name, vrpn_Connection *c = NULL);
626 
629  virtual int register_region_handler(void *userdata,
630  vrpn_IMAGERREGIONHANDLER handler)
631  {
632  return d_region_list.register_handler(userdata, handler);
633  };
634  virtual int unregister_region_handler(void *userdata,
635  vrpn_IMAGERREGIONHANDLER handler)
636  {
637  return d_region_list.unregister_handler(userdata, handler);
638  }
639 
642  virtual int
645  {
646  return d_description_list.register_handler(userdata, handler);
647  };
648  virtual int
651  {
652  return d_description_list.unregister_handler(userdata, handler);
653  }
654 
656  virtual int
659  {
660  return d_begin_frame_list.register_handler(userdata, handler);
661  };
662  virtual int
665  {
666  return d_begin_frame_list.unregister_handler(userdata, handler);
667  }
668 
670  virtual int register_end_frame_handler(void *userdata,
672  {
673  return d_end_frame_list.register_handler(userdata, handler);
674  };
675  virtual int unregister_end_frame_handler(void *userdata,
677  {
678  return d_end_frame_list.unregister_handler(userdata, handler);
679  }
680 
683  virtual int
686  {
687  return d_discarded_frames_list.register_handler(userdata, handler);
688  };
690  void *userdata, vrpn_IMAGERDISCARDEDFRAMESHANDLER handler)
691  {
692  return d_discarded_frames_list.unregister_handler(userdata, handler);
693  }
694 
697  // This is used to throttle senders that are incurring lots of latency by
698  // filling
699  // the network with packets and blocking. The next request for "N" will add
700  // onto
701  // the request. Sending "-1" means to send continuously as fast as
702  // possible,
703  // which is the default.
704  virtual bool throttle_sender(vrpn_int32 N);
705 
707  // region size changed (which would be called only if the description had
708  // a different region size than the last time, and also the first time it
709  // is called) and channel changes (which would require keeping a copy of
710  // the old and diffing when a new description came in). Also, the interace
711  // could hook different callbacks for different channels IDs to let the
712  // Imager do the work of sorting out any mapping changes and keeping track
713  // of which channel is handled by which callback -- like the Tracker and its
714  // sensors. This should happen by name, rather than by index. It might be
715  // nice to provide a delete callback when a channel is removed and an add
716  // callback when a channel is added as well, and a change callback if the
717  // name, units, scale or offset change.
718 
720  virtual void mainloop(void);
721 
724  const vrpn_Imager_Channel *channel(unsigned chanNum) const;
725 
727  bool is_description_valid() { return d_got_description; }
728 
729 protected:
730  bool d_got_description; //< Have we gotten a description yet?
731  // Lists to keep track of registered user handlers.
737 
739  static int VRPN_CALLBACK
740  handle_region_message(void *userdata, vrpn_HANDLERPARAM p);
741 
743  static int VRPN_CALLBACK
744  handle_description_message(void *userdata, vrpn_HANDLERPARAM p);
745 
747  static int VRPN_CALLBACK
748  handle_connection_dropped_message(void *userdata, vrpn_HANDLERPARAM p);
749 
751  static int VRPN_CALLBACK
752  handle_begin_frame_message(void *userdata, vrpn_HANDLERPARAM p);
753 
755  static int VRPN_CALLBACK
756  handle_end_frame_message(void *userdata, vrpn_HANDLERPARAM p);
757 
759  static int VRPN_CALLBACK
760  handle_discarded_frames_message(void *userdata, vrpn_HANDLERPARAM p);
761 };
762 
763 //------------------------------------------------------------------------------
764 // ImagerPose_Remote deals with the physical size and location the pixels in
765 // an image.
766 
768  void *userdata, const struct timeval msg_time);
769 
771 public:
772  vrpn_ImagerPose_Remote(const char *name, vrpn_Connection *c = NULL);
773 
776  virtual int
779  {
780  return d_description_list.register_handler(userdata, handler);
781  };
782  virtual int
785  {
786  return d_description_list.unregister_handler(userdata, handler);
787  }
788 
790  virtual void mainloop(void);
791 
792 protected:
793  // Lists to keep track of registered user handlers.
795 
797  static int VRPN_CALLBACK
798  handle_description_message(void *userdata, vrpn_HANDLERPARAM p);
799 };
800 
801 #endif
const unsigned vrpn_IMAGER_MAX_REGIONu12in16
Definition: vrpn_Imager.h:45
Helper function to convert data for a sub-region of one channel of.
Definition: vrpn_Imager.h:439
virtual int unregister_end_frame_handler(void *userdata, vrpn_IMAGERENDFRAMEHANDLER handler)
Definition: vrpn_Imager.h:675
vrpn_Callback_List< vrpn_IMAGERDISCARDEDFRAMESCB > d_discarded_frames_list
Definition: vrpn_Imager.h:736
vrpn_int32 d_frames_to_send
Definition: vrpn_Imager.h:261
VRPN_API int vrpn_unbuffer(const char **buffer, timeval *t)
Utility routine for taking a struct timeval from a buffer that was sent as a message.
Definition: vrpn_Shared.C:312
bool read_unscaled_pixel(vrpn_uint16 c, vrpn_uint16 r, vrpn_float32 &val, vrpn_uint16 d=0) const
Reads pixel from the region with no scale and offset applied to the value. Not.
Definition: vrpn_Imager.h:549
const vrpn_uint16 vrpn_IMAGER_VALTYPE_UINT12IN16
Definition: vrpn_Imager.h:384
vrpn_int32 nCols(void) const
Definition: vrpn_Imager.h:123
vrpn_int32 d_regionf32_m_id
Definition: vrpn_Imager.h:152
vrpn_int32 d_begin_frame_m_id
Definition: vrpn_Imager.h:137
void get_dCol(vrpn_float64 *dCol) const
This is the total span of the image in columns;.
Definition: vrpn_Imager.h:297
void(VRPN_CALLBACK * vrpn_IMAGERBEGINFRAMEHANDLER)(void *userdata, const vrpn_IMAGERBEGINFRAMECB info)
Definition: vrpn_Imager.h:427
vrpn_int32 nChannels(void) const
Definition: vrpn_Imager.h:125
vrpn_int32 nRows(void) const
Definition: vrpn_Imager.h:122
vrpn_int32 d_throttle_frames_m_id
Definition: vrpn_Imager.h:143
ChannelCompression d_compression
Definition: vrpn_Imager.h:113
void(VRPN_CALLBACK * vrpn_IMAGERREGIONHANDLER)(void *userdata, const vrpn_IMAGERREGIONCB info)
Definition: vrpn_Imager.h:394
vrpn_int32 d_end_frame_m_id
Definition: vrpn_Imager.h:139
vrpn_int32 nDepth(void) const
Definition: vrpn_Imager.h:124
virtual int unregister_begin_frame_handler(void *userdata, vrpn_IMAGERBEGINFRAMEHANDLER handler)
Definition: vrpn_Imager.h:663
const void * d_valBuf
Definition: vrpn_Imager.h:616
vrpn_uint16 d_rMin
Definition: vrpn_Imager.h:611
const vrpn_uint16 vrpn_IMAGER_VALTYPE_UINT8
Definition: vrpn_Imager.h:378
bool buffer(char **insertPt, vrpn_int32 *buflen) const
Definition: vrpn_Imager.h:80
const vrpn_uint16 vrpn_IMAGER_VALTYPE_UNKNOWN
Definition: vrpn_Imager.h:377
vrpn_int32 d_description_m_id
Definition: vrpn_Imager.h:135
vrpn_uint16 d_dropped_due_to_throttle
Definition: vrpn_Imager.h:264
vrpn_int16 d_chanIndex
Definition: vrpn_Imager.h:610
vrpn_float32 minVal
Definition: vrpn_Imager.h:71
Holds the description needed to convert from raw data to values for a channel.
Definition: vrpn_Imager.h:53
void get_dDepth(vrpn_float64 *dDepth) const
This is the total span of the image in depth;.
Definition: vrpn_Imager.h:316
This is the class users deal with: it tells the format and the region data when it arrives...
Definition: vrpn_Imager.h:623
vrpn_int32 d_regionu8_m_id
Definition: vrpn_Imager.h:145
bool read_unscaled_pixel(vrpn_uint16 c, vrpn_uint16 r, vrpn_uint16 &val, vrpn_uint16 d=0) const
Reads pixel from the region with no scale and offset applied to the value. Not.
Definition: vrpn_Imager.h:506
Generic connection class not specific to the transport mechanism.
virtual int register_types(void)=0
Register the types of messages this device sends/receives. Return 0 on success, -1 on fail...
vrpn_uint16 d_dMin
Definition: vrpn_Imager.h:613
virtual int register_description_handler(void *userdata, vrpn_IMAGERDESCRIPTIONHANDLER handler)
Register a handler for when the object&#39;s description changes (if desired).
Definition: vrpn_Imager.h:643
virtual int unregister_region_handler(void *userdata, vrpn_IMAGERREGIONHANDLER handler)
Definition: vrpn_Imager.h:634
vrpn_int32 d_nDepth
Definition: vrpn_Imager.h:130
vrpn_Callback_List< struct timeval > d_description_list
Definition: vrpn_Imager.h:794
#define VRPN_CALLBACK
void(VRPN_CALLBACK * vrpn_IMAGERENDFRAMEHANDLER)(void *userdata, const vrpn_IMAGERENDFRAMECB info)
Definition: vrpn_Imager.h:429
const vrpn_Imager_Region * region
Definition: vrpn_Imager.h:391
vrpn_int32 d_nChannels
Definition: vrpn_Imager.h:131
#define VRPN_API
vrpn_int32 d_nCols
Definition: vrpn_Imager.h:129
All types of client/server/peer objects in VRPN should be derived from the vrpn_BaseClass type descri...
const unsigned vrpn_IMAGER_MAX_CHANNELS
Definition: vrpn_Imager.h:32
virtual void mainloop()=0
Called once through each main loop iteration to handle updates. Remote object mainloop() should call ...
vrpn_Callback_List< vrpn_IMAGERBEGINFRAMECB > d_begin_frame_list
Definition: vrpn_Imager.h:734
vrpn_uint16 get_val_type(void) const
Definition: vrpn_Imager.h:608
vrpn_uint16 d_cMin
Definition: vrpn_Imager.h:612
char cName[100]
Length of names within VRPN.
This structure is what is passed to a vrpn_Connection message callback.
void(VRPN_CALLBACK * vrpn_IMAGERDISCARDEDFRAMESHANDLER)(void *userdata, const vrpn_IMAGERDISCARDEDFRAMESCB info)
Definition: vrpn_Imager.h:431
virtual int register_region_handler(void *userdata, vrpn_IMAGERREGIONHANDLER handler)
Register a handler for when new data arrives (can look up info in object when this happens) ...
Definition: vrpn_Imager.h:629
virtual int unregister_description_handler(void *userdata, vrpn_IMAGERDESCRIPTIONHANDLER handler)
Definition: vrpn_Imager.h:783
vrpn_int32 d_regionu12in16_m_id
Definition: vrpn_Imager.h:147
const unsigned vrpn_IMAGER_MAX_REGIONu8
Set of constants to tell how many points you can put into a region depending on the type you are putt...
Definition: vrpn_Imager.h:37
vrpn_uint16 d_valType
Definition: vrpn_Imager.h:617
const unsigned vrpn_IMAGER_MAX_REGIONu16
Definition: vrpn_Imager.h:41
virtual int register_begin_frame_handler(void *userdata, vrpn_IMAGERBEGINFRAMEHANDLER handler)
Register a handler for frame beginning (if the application cares)
Definition: vrpn_Imager.h:657
void(VRPN_CALLBACK * vrpn_IMAGERDESCRIPTIONHANDLER)(void *userdata, const struct timeval msg_time)
Definition: vrpn_Imager.h:399
virtual int register_description_handler(void *userdata, vrpn_IMAGERDESCRIPTIONHANDLER handler)
Register a handler for when the object&#39;s description changes (if desired)
Definition: vrpn_Imager.h:777
Base class for Imager class.
Definition: vrpn_Imager.h:117
vrpn_Callback_List< struct timeval > d_description_list
Definition: vrpn_Imager.h:732
vrpn_int32 d_regionu16_m_id
Definition: vrpn_Imager.h:150
VRPN_API int vrpn_buffer(char **insertPt, vrpn_int32 *buflen, const timeval t)
Utility routine for placing a timeval struct into a buffer that is to be sent as a message...
Definition: vrpn_Shared.C:241
void(VRPN_CALLBACK * vrpn_IMAGERPOSEDESCRIPTIONHANDLER)(void *userdata, const struct timeval msg_time)
Definition: vrpn_Imager.h:767
Class from which all user-level (and other) classes that communicate with vrpn_Connections should der...
const int vrpn_CONNECTION_TCP_BUFLEN
const vrpn_uint16 vrpn_IMAGER_VALTYPE_UINT16
Definition: vrpn_Imager.h:383
vrpn_uint32 getNumVals() const
Returns the number of values in the region.
Definition: vrpn_Imager.h:456
const vrpn_uint16 vrpn_IMAGER_VALTYPE_FLOAT32
Definition: vrpn_Imager.h:385
bool read_unscaled_pixel(vrpn_uint16 c, vrpn_uint16 r, vrpn_uint8 &val, vrpn_uint16 d=0) const
Reads pixel from the region with no scale and offset applied to the value. Not the most efficient way...
Definition: vrpn_Imager.h:470
void get_origin(vrpn_float64 *origin) const
Returns the origin of the coordinate system,.
Definition: vrpn_Imager.h:287
vrpn_Callback_List< vrpn_IMAGERENDFRAMECB > d_end_frame_list
Definition: vrpn_Imager.h:735
bool is_description_valid()
have we gotten a description message yet?
Definition: vrpn_Imager.h:727
void get_dRow(vrpn_float64 *dRow) const
This is the total span of the image in rows;.
Definition: vrpn_Imager.h:306
vrpn_Callback_List< vrpn_IMAGERREGIONCB > d_region_list
Definition: vrpn_Imager.h:733
virtual int register_discarded_frames_handler(void *userdata, vrpn_IMAGERDISCARDEDFRAMESHANDLER handler)
Register a handler for discarded frame notifications (if the application cares)
Definition: vrpn_Imager.h:684
virtual int register_end_frame_handler(void *userdata, vrpn_IMAGERENDFRAMEHANDLER handler)
Register a handler for frame end (if the application cares)
Definition: vrpn_Imager.h:670
bool unbuffer(const char **buffer)
Definition: vrpn_Imager.h:96
vrpn_int32 d_description_m_id
Definition: vrpn_Imager.h:339
virtual int unregister_description_handler(void *userdata, vrpn_IMAGERDESCRIPTIONHANDLER handler)
Definition: vrpn_Imager.h:649
virtual int unregister_discarded_frames_handler(void *userdata, vrpn_IMAGERDISCARDEDFRAMESHANDLER handler)
Definition: vrpn_Imager.h:689
const unsigned vrpn_IMAGER_MAX_REGIONf32
Definition: vrpn_Imager.h:46
vrpn_int32 d_discarded_frames_m_id
Definition: vrpn_Imager.h:141