Utah Raster Toolkit  9999-git
URT Development version (post-3.1b)
getcx3d.c
Go to the documentation of this file.
1 /*
2  * This software is copyrighted as noted below. It may be freely copied,
3  * modified, and redistributed, provided that the copyright notice is
4  * preserved on all copies.
5  *
6  * There is no warranty or other guarantee of fitness for this software,
7  * it is provided solely "as is". Bug reports or fixes may be sent
8  * to the author, who may or may not act on them as he desires.
9  *
10  * You may not include this software in a program or other software product
11  * without supplying the source, or without informing the end-user that the
12  * source is available for no extra charge.
13  *
14  * If you modify this software, you should include a notice giving the
15  * name of the person performing the modification, the date of modification,
16  * and the reason for such modification.
17  */
18 /* getcx3d.c, 6/24/86, T. McCollough, UU */
19 
20 #include "rle.h"
21 
22 #include <stdio.h>
23 
24 #include <cx3d_types.h>
25 #include <cx3d_solid.h>
26 
27 #include "gamma.h"
28 #include "sig.h"
29 
30 #define GAMMA 2.5 /* gamma for the display we have attached to the CX */
31 
32 #define DIRECTCOLG( r, g, b, gv ) (DIRECTCOL( gamma( r, gv ),
33  gamma( g, gv ),
34  gamma( b, gv ) ))
35 /* For reading RLE images. */
36 rle_hdr hdr;
37 
38 static void go ( pc )
39 DLMADDR pc;
40 {
41  cx_idle( );
42  cx_flush( );
43  cx_go( pc, DISP_BM1, IMAGE_VIS, NO, NO );
44  cx_flush( );
45  cx_glomflush( );
46  cx_setpc( pc );
47 }
48 
49 static void run ( r, g, b, start, stop, y, magnification, originx, originy,
50  gamma_value )
51 rle_pixel r, g, b;
52 int start, stop, y, magnification, originx, originy;
53 float gamma_value;
54 {
55  /* overlay or clear to background?? */
56  if ((hdr.background==1 || hdr.background==2) &&
57  hdr.bg_color[RLE_RED] == r &&
58  hdr.bg_color[RLE_GREEN] == g &&
59  hdr.bg_color[RLE_BLUE] == b) /* screen already good! */ ;
60  else /* no overlay, so send the run */
61  if (magnification)
62  cx_clr_dc( DIRECTCOLG( r, g, b, gamma_value ),
63 originx+((start-hdr.xmin)*magnification)+hdr.xmin,
64 originx+((stop-hdr.xmin)*magnification)+hdr.xmin+magnification-1,
65 originy+((y-hdr.ymin)*magnification)+hdr.ymin,
66 originy+((y-hdr.ymin)*magnification)+hdr.ymin+magnification-1 );
67  else cx_clr_dc( DIRECTCOLG( r, g, b, gamma_value ),
68  originx+start, originx+stop,
69  originy+y, originy+y );
70 }
71 
72 static void scanline ( scan, y, magnification, originx, originy, gamma_value )
73 rle_pixel *scan[];
74 int y, magnification, originx, originy;
75 float gamma_value;
76 {
77  register rle_pixel *r = scan[RLE_RED], *g = scan[RLE_GREEN],
78  *b = scan[RLE_BLUE];
79  register int start = hdr.xmin;
80  DLMADDR pc = cx_getpc( );
81  int runcount = 0;
82 
83  /* find and display all runs */
84  while (r - scan[0] < hdr.xmax) {
85  register rle_pixel _r = *r, _g = *g, _b = *b;
86 
87  /* find the run */
88  r++, g++, b++;
89  while (*r == _r && *g == _g && *b == _b) {
90  if (r - scan[0] == hdr.xmax) break;
91  r++, g++, b++;
92  }
93  /* send the run */
94  run( _r, _g, _b, start, r - scan[0] - 1, y, magnification,
95  originx, originy, gamma_value );
96  /* flush the display list before it gets to big. this number
97  is arbitrary */
98  if (runcount++ > 128) {
99  go( pc );
100  runcount = 0;
101  }
102 
103  /* the start of the next scanline */
104  start = r - scan[0];
105  }
106 
107  /* do the last pixel on the scanline */
108  run( *r, *g, *b, start, start, y, magnification, originx, originy,
109  gamma_value);
110 
111  go( pc );
112 }
113 
114 /* set the background, if necessary */
115 
116 static void background ( magnification, originx, originy, gamma_value )
117 int magnification, originx, originy;
118 float gamma_value;
119 {
120  if (hdr.background == 2) {
121  DLMADDR pc = cx_getpc( );
122  rle_pixel r, g, b;
123 
124  switch (hdr.ncolors) {
125  case 1: r = g = b = hdr.bg_color[0];
126  break;
127  case 3: r = hdr.bg_color[RLE_RED],
128  g = hdr.bg_color[RLE_GREEN],
129  b = hdr.bg_color[RLE_BLUE]; break;
130  default: fprintf( stderr, "getcx3d: internal error 1\n" );
131  }
132  if (magnification)
133  cx_clr_dc( DIRECTCOLG( r, g, b, gamma_value ),
134 originx+hdr.xmin,
135 originx+((hdr.xmax-hdr.xmin)*magnification)+hdr.xmin+magnification-1,
136 originy+hdr.ymin,
137 originy+((hdr.ymax-hdr.ymin)*magnification)+hdr.ymin+magnification-1 );
138  else cx_clr_dc( DIRECTCOLG( r, g, b, gamma_value ),
139  originx+hdr.xmin, originx+hdr.xmax,
140  originy+hdr.ymin, originy+hdr.ymax );
141  go( pc );
142  }
143 }
144 
145 /* load the colormap, if necessary */
146 
147 static void colormap ( ) {
148  int i;
149  DLMADDR pc = cx_getpc( );
150 
151  if (hdr.ncmap == 3) {
152 #ifndef CX3D_COLORMAP
153  fprintf( stderr, "getcx3d: (3) colormap not loaded\n" );
154  return;
155 #else
156  for (i = 0 ; i < (1 << hdr.cmaplen) ; i++) {
157  cx_s_disp_clu( DISP_BM1,
158  DIRECTCOL( i, i, i ),
159  (hdr.cmap[i]>>8)/255.0,
160  (hdr.cmap[i+(1<<hdr.cmaplen)]>>8)/255.0,
161  (hdr.cmap[i+(2<<hdr.cmaplen)]>>8)/255.0 );
162  go( pc );
163  }
164 #endif
165  } else if (hdr.ncmap == 1) {
166 #ifndef CX3D_COLORMAP
167  fprintf( stderr, "getcx3d: (1) colormap not loaded\n" );
168  return;
169 #else
170  for (i = 0 ; i < (1 << hdr.cmaplen) ; i++) {
171  cx_s_disp_clu( DISP_BM1, DIRECTCOL( i, i, i ),
172  (hdr.cmap[i]>>8)/255.0,
173  (hdr.cmap[i]>>8)/255.0,
174  (hdr.cmap[i]>>8)/255.0 );
175  go( pc );
176  }
177 #endif
178  }
179 }
180 
181 static void clear_scan ( scan )
182 rle_pixel *scan[];
183 {
184  static junk = 1;
185  static rle_pixel *r, *g, *b;
186  int i;
187 
188  if (junk) {
189  r = (rle_pixel *) malloc( (unsigned) hdr.xmax+1 );
190  g = (rle_pixel *) malloc( (unsigned) hdr.xmax+1 );
191  b = (rle_pixel *) malloc( (unsigned) hdr.xmax+1 );
192  for (i = 0 ; i <= hdr.xmax ; i++)
193  r[i] = hdr.bg_color[RLE_RED],
194  g[i] = hdr.bg_color[RLE_GREEN],
195  b[i] = hdr.bg_color[RLE_BLUE];
196  junk = 0;
197  }
198  bcopy( (char *) r, (char *) scan[RLE_RED], hdr.xmax+1 );
199  bcopy( (char *) g, (char *) scan[RLE_GREEN], hdr.xmax+1 );
200  bcopy( (char *) b, (char *) scan[RLE_BLUE], hdr.xmax+1 );
201 }
202 
203 /* display an rle file using cx3d */
204 
205 getcx3d ( f, force_background, magnification, originx, originy, gamma_value )
206 char *f;
207 int force_background, magnification, originx, originy;
208 float gamma_value;
209 {
210  FILE *F = rle_open_f_noexit( hdr.cmd, f, "r" );
211  rle_pixel *scan[3];
212  int y, i;
213 
214  if (F == NULL) {
215  perror( f );
216  return;
217  }
218  (void)rle_hdr_init( &hdr );
219  rle_names( &hdr, hdr.cmd, f, 0 );
220  hdr.rle_file = F;
221  if (rle_get_setup( & hdr ) < 0) {
222  fprintf( stderr,
223  "getcx3d: error reading setup information from %s\n",
224  f ? f : "stdin");
225  return;
226  }
227  if (force_background != -1)
228  hdr.background = force_background;
229 
230  /* we're only interested in r, g, & b */
232  for (i = 3 ; i < hdr.ncolors ; i++) RLE_CLR_BIT( hdr, i );
233 
234  for (i = 0 ; i < 3 ; i++)
235  scan[i] = (rle_pixel *) malloc( (unsigned) hdr.xmax+1 );
236 
237  sig_block( );
238  background( magnification, originx, originy, gamma_value );
239  sig_unblock( );
240 
241  sig_block( );
242  colormap( );
243  sig_unblock( );
244 
245  clear_scan( scan );
246  while ((y = rle_getrow( & hdr, scan )) <= hdr.ymax) {
247  /* deal with b&w images */
248  for (i = 2; i >= hdr.ncolors; i--)
249  bcopy( (char *) scan[0], (char *) scan[i],
250  hdr.xmax+1);
251  /* dump the scanline */
252  sig_block( );
253  scanline( scan, y, magnification,
254  originx, originy, gamma_value );
255  sig_unblock( );
256  /* clear it out */
257  clear_scan( scan );
258  }
259  for (i = 0 ; i < 3 ; i++) free( (char *) scan[i] );
260 }
261 
262 static void usage ( ) {
263  fprintf( stderr,
264 "usage: getcx3d [-O] [-B] [-d] [-t] [-p x y] [-l] file ...\n" );
265  fprintf( stderr, "getcx3d: list as many files as you wish\n" );
266  fprintf( stderr, "getcx3d: use - for stdin\n" );
267  fprintf( stderr, "getcx3d: see the man page for details\n" );
268 }
269 
270 done ( ) {
271  /* finish up with the cx */
272  sig_block( );
273  cx_flush( );
274  cx_close( );
275  exit( 0 );
276 }
277 
279 int argc;
280 char *argv[];
281 {
282  int force_background = -1; /* don't force background */
283  int doneone = 0; /* we've not yet displayed an image */
284  int magnification = 1; /* we don't want any mag. by default */
285  int originx = 0, originy = 0; /* we want origin to be 0 by default */
286  float gamma_value = GAMMA; /* gamma for the CX display */
287 
288  /* Initialize header. */
289  hdr = *rle_hdr_init( (rle_hdr *)NULL );
290  rle_names( &hdr, cmd_name( argv ), NULL, 0 );
291 
292  /* set up signal stuff */
293  sig_setup( );
294 
295  /* set up cx */
296  sig_block( );
297  cx_ack( FALSE );
298  if (!cx_open( "/dev/dr0" )) {
299  fprintf( stderr, "getcx3d: wait your turn\n" );
300  exit( 1 );
301  }
302  cx_init( );
303  cx_init_disp( DISP_BM1 );
304  sig_unblock( );
305 
306  /* parse command line */
307  while (*++argv) if (*argv[0] == '-') switch (argv[0][1]) {
308  case 'O': force_background = 1; break;
309  case 'B': force_background = 2; break;
310  case 'd': magnification = 2; break;
311  case 't': magnification = 3; break;
312  case 'p': originx = atoi( *++argv ); originy = atoi( *++argv ); break;
313  case 'l': gamma_value = 1.0; break;
314  case '\0': getcx3d( (char *) 0, force_background, magnification,
315  originx, originy, gamma_value );
316  doneone = 1;
317  /* reset options */
318  force_background = -1;
319  magnification = 1;
320  originx = originy = 0;
321  gamma_value = GAMMA;
322  break;
323  default: usage( ); goto out;
324  } else {
325  getcx3d( argv[0], force_background, magnification,
326  originx, originy, gamma_value );
327  doneone = 1; /* we've done one, so forget about stdin */
328  /* reset options */
329  force_background = -1;
330  magnification = 1;
331  originx = originy = 0;
332  gamma_value = GAMMA;
333  }
334 
335  if (!doneone) getcx3d( (char *) 0, force_background, magnification,
336  originx, originy, gamma_value );
337 
338  out:
339  done( );
340 }
rle_hdr hdr
Definition: getx10.c:84
int xmin
Definition: rle.h:100
void rle_names(rle_hdr *the_hdr, const char *pgmname, const char *fname, int img_num)
Definition: rle_hdr.c:48
char * cmd_name(char **argv)
Definition: cmd_name.c:31
#define DIRECTCOLG(r, g, b, gv)
Definition: getcx3d.c:32
void main(int argc, char **argv)
Definition: aliastorle.c:121
int rle_get_setup(rle_hdr *the_hdr)
Definition: rle_getrow.c:74
#define RLE_GREEN
Definition: rle.h:63
int rle_getrow(rle_hdr *the_hdr, scanline)
Definition: rle_getrow.c:333
int * bg_color
Definition: rle.h:100
int ymin
Definition: rle.h:100
#define RLE_BLUE
Definition: rle.h:64
const char * cmd
Definition: rle.h:133
#define RLE_RED
Definition: rle.h:62
int xmax
Definition: rle.h:100
FILE * rle_open_f_noexit(char *prog_name, char *file_name, char *mode)
Definition: rle_open_f.c:57
int background
Definition: rle.h:100
#define RLE_CLR_BIT(glob, bit)
Definition: rle.h:124
int ncmap
Definition: rle.h:100
int ymax
Definition: rle.h:100
unsigned char rle_pixel
Definition: rle.h:56
#define RLE_ALPHA
Definition: rle.h:65
rle_hdr * rle_hdr_init(rle_hdr *the_hdr)
Definition: rle_hdr.c:267
FILE * rle_file
Definition: rle.h:114
int ncolors
Definition: rle.h:100
#define GAMMA
Definition: getcx3d.c:30