HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
tiledevice.C
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2018
3  * Side Effects Software Inc. All rights reserved.
4  *
5  * Redistribution and use of Houdini Development Kit samples in source and
6  * binary forms, with or without modification, are permitted provided that the
7  * following conditions are met:
8  * 1. Redistributions of source code must retain the above copyright notice,
9  * this list of conditions and the following disclaimer.
10  * 2. The name of Side Effects Software may not be used to endorse or
11  * promote products derived from this software without specific prior
12  * written permission.
13  *
14  * THIS SOFTWARE IS PROVIDED BY SIDE EFFECTS SOFTWARE `AS IS' AND ANY EXPRESS
15  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
17  * NO EVENT SHALL SIDE EFFECTS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
18  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
19  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
20  * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
21  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
22  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
23  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  *
25  *----------------------------------------------------------------------------
26  * Sample application showing how to use IMG_TileDevice by writing constant
27  * image planes (like $HH/public/deepmplay.C). IMG_TileDevice is the
28  * interface used by imdisplay and by mantra to write tiles to mplay and
29  * the IPR, so it is faster to use IMG_TileDevice directly rather than
30  * using imdisplay.
31  *
32  * To send images to the IPR, you can specify the port number using the -s
33  * option. This can be retrieved in soho by evaluating the
34  * vm_image_mplay_socketport property.
35  */
36 
37 
38 #include <UT/UT_Args.h>
39 #include <UT/UT_WorkBuffer.h>
40 #include <IMG/IMG_TileDevice.h>
41 #include <IMG/IMG_TileOptions.h>
42 #include <TIL/TIL_TileMPlay.h>
43 
44 #define XRES 320 // Image X resolution
45 #define YRES 240 // Image Y resolution
46 #define TXRES 16 // Tile X resolution
47 #define TYRES 16 // Tile Y resolution
48 
49 struct PlaneDef {
50  const char *myName;
53 };
54 
56  { "C", IMG_UCHAR, IMG_RGBA }, // C plane is unsigned char, RGBA
57  { "s", IMG_FLOAT, IMG_1CHAN }, // s plane is float, single channel
58  { "Normal", IMG_FLOAT, IMG_RGB }, // N plane is float, RGB data
59 };
60 
61 #define NPLANES (sizeof(thePlanes)/sizeof(PlaneDef))
62 
63 static void *
64 buildTiles()
65 {
66  int pixels = TXRES * TYRES;
67  size_t bytes = 0;
68  for (int i = 0; i < NPLANES; i++)
69  {
70  int words = pixels * IMGvectorSize(thePlanes[i].myColorModel);
71  bytes += words * IMGbyteSize(thePlanes[i].myFormat);
72  }
73 
74  void *tdata = ::malloc(bytes);
75  char *ptr = (char *)tdata;
76  for (int i = 0; i < NPLANES; i++)
77  {
78  unsigned short *sdata;
79  unsigned char *cdata;
80  unsigned int *idata;
81  float *fdata;
82 
83  int words = pixels * IMGvectorSize(thePlanes[i].myColorModel);
84 
85  cdata = (unsigned char *)ptr;
86  sdata = (unsigned short *)ptr;
87  idata = (unsigned int *)ptr;
88  fdata = (float *)ptr;
89 
90  // Just fill in with some constant values.
91  for (int c = 0; c < words; c++)
92  {
93  switch (thePlanes[i].myFormat)
94  {
95  case IMG_UCHAR: *cdata++ = 0x85; break;
96  case IMG_USHORT: *sdata++ = 0x8512; break;
97  case IMG_UINT: *idata++ = 0x84123456; break;
98  default: *fdata++ = 0.763;
99  }
100  }
101 
102  ptr += words*IMGbyteSize(thePlanes[i].myFormat);
103  }
104 
105  return tdata;
106 }
107 
108 static void
109 splitHostPort(UT_String &host, UT_String &port, const char *hostname)
110 {
111  const char *colon = strchr(hostname, ':');
112  if (colon)
113  {
114  int len = colon - hostname;
115  host.harden(colon, len);
116  colon++; // Move past the colon
117  }
118  else
119  {
120  colon = hostname;
121  }
122  port.harden(colon);
123 }
124 
125 static void
126 sendPlaneDefinitions(IMG_TileDevice *dev,
127  const UT_String &host,
128  const UT_String &port)
129 {
130  IMG_TileOptionList flist;
131 
132  for (int i = 0; i < NPLANES; i++)
133  {
134  IMG_TileOptions *finfo = new IMG_TileOptions();
135 
136  finfo->setPlaneInfo("ip", thePlanes[i].myName,
137  0, thePlanes[i].myFormat, thePlanes[i].myColorModel);
138 
139  // These format options allow sending tiles to an existing tile
140  // device (such as the IPR) rather than opening a new one. They
141  // only need to be set for plane 0 but it's harmless to send them
142  // for all planes.
143 
144  if (host) finfo->setFormatOption("sockethost", host);
145  if (port) finfo->setFormatOption("socketport", port);
146 
147  flist.append(finfo);
148  }
149 
150  if (!dev->openMulti(flist, XRES, YRES, TXRES, TYRES, 1.0))
151  {
152  ::fprintf(stderr, "Error opening tile device\n");
153  ::exit(1);
154  }
155 }
156 
157 static void
158 writeTile(IMG_TileDevice *dev, void *tdata, int tx0, int tx1, int ty0, int ty1)
159 {
160  if (!dev->writeTile(tdata, tx0, tx1, ty0, ty1))
161  {
162  ::fprintf(stderr, "Error writing data: %d %d %d %d\n",
163  tx0, tx1, ty0, ty1);
164  ::exit(1);
165  }
166  dev->flush();
167 }
168 
169 int
170 main(int argc, char *argv[])
171 {
172  UT_Args args;
173  UT_String host, port;
174 
175 #ifdef _WIN32
176  struct local {
177  static IMG_TileDevice *
178  creator(int middle)
179  {
180  return new TIL_TileMPlay(middle, 0);
181  }
182  };
183  IMG_TileDevice::setMPlayDevCreator(local::creator);
184 #endif
185 
186  args.initialize(argc, argv);
187  args.stripOptions("s:");
188 
189  if (args.found('s'))
190  splitHostPort(host, port, args.argp('s'));
191 
193 
194  sendPlaneDefinitions(dev, host, port);
195 
196  void *tdata = buildTiles();
197  for (int ty = 0; ty < YRES; ty += TYRES)
198  for (int tx = 0; tx < XRES; tx += TXRES)
199  ::writeTile(dev, tdata,
200  tx, SYSmin(tx+TXRES, XRES)-1,
201  ty, SYSmin(ty+TYRES, YRES)-1);
202 
203  free(tdata);
204 }
void append(IMG_TileOptions *opt)
#define TXRES
Definition: tiledevice.C:46
static IMG_TileDevice * newDevice(const char *filename, const UT_Options *options=NULL)
png_voidp ptr
Definition: png.h:2145
virtual int openMulti(IMG_TileOptionList &flist, int xres, int yres, int tile_width, int tile_height, fpreal aspect)
void stripOptions(const char *options)
int found(int opt) const
Definition: UT_Args.h:56
GLint GLint GLsizei GLint GLenum GLenum const void * pixels
Definition: glcorearb.h:107
#define XRES
Definition: tiledevice.C:44
static void setMPlayDevCreator(IMG_TileDevice *(*creator)(int))
png_uint_32 i
Definition: png.h:2877
void setPlaneInfo(const UT_StringHolder &filename, const UT_StringHolder &channel, const UT_StringHolder &format, IMG_DataType dtype=IMG_DT_ANY, IMG_ColorModel cmodel=IMG_CM_ANY, IMG_TypeInfo tinfo=IMG_TI_COLOR)
IMG_DataType
Definition: IMG_FileTypes.h:17
PlaneDef thePlanes[]
Definition: tiledevice.C:55
void harden()
Take shallow copy and make it deep.
Definition: UT_String.h:213
#define YRES
Definition: tiledevice.C:45
virtual int writeTile(const void *data, unsigned x0, unsigned x1, unsigned y0, unsigned y1)=0
IMG_ColorModel
Definition: IMG_FileTypes.h:53
IMG_DataType myFormat
Definition: tiledevice.C:51
const char * myName
Definition: tiledevice.C:50
const char * argp(int opt, int which=0) const
Definition: UT_Args.h:61
virtual void flush()
#define TYRES
Definition: tiledevice.C:47
void initialize(int argc, const char *const argv[])
int main(int argc, char *argv[])
Definition: tiledevice.C:170
IMG_ColorModel myColorModel
Definition: tiledevice.C:52
#define SYSmin(a, b)
Definition: SYS_Math.h:1368
void setFormatOption(const char *token, const char *value)
#define NPLANES
Definition: tiledevice.C:61