Utah Raster Toolkit  9999-git
URT Development version (post-3.1b)
getbob.c
Go to the documentation of this file.
1 /*
2  * getbob.c - Read RLE files onto hp bobcat screens.
3  *
4  * Author: Mark Bloomenthal
5  * Computer Science Dept.
6  * University of Utah
7  * Date: Fri Oct 17 1986
8  * Copyright (c) 1986, University of Utah
9  *
10  * Most code lifted from J W. Peterson.
11  *
12  * Flags are:
13  * -l Linear map
14  * -g gam Gammap map, use gamma of gam (floating point number)
15  * -d device Use the device specified.
16  * -x driver Use the driver specified.
17  * -p x y Position image lower left hand corner on the display. The
18  * x and y position is given in pixels with the origin taken as
19  * the lower left hand corner of the display. This flag is only
20  * useful with the -D, -d, and/or -x flags.
21  *
22  */
23 
24 #include "starbase.c.h"
25 #include <stdio.h>
26 #include <math.h>
27 #include <fcntl.h>
28 #include "rle.h"
29 
30 typedef char * string; /* Character Strings. */
31 typedef int boolean; /* Logical vars or values. */
32 #define TRUE 1 /* Logical constants. */
33 #define FALSE 0
34 typedef float single;
35 #define MAX(i,j) ( (i) > (j) ? (i) : (j) )
36 
37 
38 /* Some starbase type definitions. */
40 typedef unsigned char starbase_color_index_type;
41 
42 #define RASTERSIZE_LIM 1023
43 
44 /* Standard color map offset. */
45 #define COLMAP_OFFSET 8
46 
47 /* Color modes. */
48 #define MONOCHROME_MODE 1
49 #define EIGHT_BIT_COLOR_MODE 2
50 
51 /* Scanline storage & RLE row pointers */
52 unsigned char scanline[4][RASTERSIZE_LIM], *rows[4];
53 
54 /* Scanline to be written to device. */
56 
57 /* Dither matrix. */
58 int dm16[16][16];
59 
60 /* Tables for quantization. */
61 int errN[256], divN[256];
62 
63 /* The gamma map and default gamma. */
64 int gammamap[256];
65 float gam = 2.0;
66 
67 /* Input filename. */
68 string infname = NULL;
69 
70 /* Image header. */
71 rle_hdr hdr;
72 
73 /* Color map flags. */
76 
78 
79 /* The default device and device driver. */
80 string display_name = "/dev/crt";
81 string driver_name = "hp98705";
82 
83 /* For positioning the image on the display. */
85 int pic_x = 0;
86 int pic_y = 0;
87 
88 /* How many bits in the devices color map. */
90 
91 /* What mode to dither into. Either 8 bit color or monochrome. */
93 
94 /* Color map to be written to device. */
97 
98 /* The color to be used in case we do monochrome. */
99 float r_base_color = 1.0;
100 float g_base_color = 1.0;
101 float b_base_color = 1.0;
102 
103 /* Starbase file descriptor for device where the picture goes. */
105 
106 
108 int argc; char *argv[];
109 {
110  int i;
111  int row;
112  boolean bw_flag = FALSE;
113 
114  /* sbrk( 1000000 ); */
115 
116  /* Get command line arguments. */
117  if ( scanargs( argc, argv,
118  "getbob l%- g%-gamma!f p%-pos!d!d d%-display!s x%-driver!s file%s",
123  &infname ) == 0 )
124  exit( 1 );
125 
126  /* Open file for reading, if no filename was specified, we'll read
127  * from stdin.
128  */
129  hdr = *rle_hdr_init( (rle_hdr *)NULL );
132  /* Read header information from rle file. */
133  rle_get_setup_ok( &hdr, NULL, NULL );
134 
135  RLE_CLR_BIT( hdr, RLE_ALPHA ); /* No alpha channel */
136 
137  /* Set up gamma correction tables if need be. */
138  init_gamma_map();
139 
140  direct_setup();
141 
142  /* Set up rows to point to our copy of the scanline */
143  for ( i= 0; i < 4; i++ )
144  rows[i] = scanline[i];
145 
146  /* Get the scanlines. */
147  for (i = hdr.ymin; i < hdr.ymax; i++)
148  {
150  if ( put_mode == MONOCHROME_MODE )
151  put_line_mono( i );
152  else
153  put_line_8( i );
154  }
155 }
156 
157 
158 
159 /*****************************************************************
160  * TAG( init_gamma_map )
161  *
162  * Compute a gamma correction map.
163  */
164 
165 init_gamma_map()
166 {
167  int i;
168 
169  /* Compute a gamma correction map. */
170  for ( i = 0; i < 256; i++ )
171  {
172  if ( ! linear_flag )
173  {
174  gammamap[i] = (int)(0.5 + 255 * pow( i / 255.0, 1.0/gam ));
175  }
176  }
177 }
178 
179 
180 
181 /*****************************************************************
182  * TAG( init_8_bit_color_map )
183  *
184  * Initialize the 8 bit color map.
185  */
186 
187 init_8_bit_color_map()
188 {
189  int i;
190 
191  /*
192  * Set up the color map entries. We will use 216 colors.
193  */
194  n_colmap_colors = 216; /* Fill out the global. */
195 
196  for ( i = 0; i < n_colmap_colors; i++ )
197  {
198  colmap[i][0] = ((i%6) * 51) / 255.0;
199  colmap[i][1] = (((i/6)%6) * 51) / 255.0;
200  colmap[i][2] = (((i/36)%6) * 51) / 255.0;
201  }
202 
204 }
205 
206 
207 
208 /*****************************************************************
209  * TAG( init_monochrome_color_map )
210  *
211  * Initialize the monochrome color map. This is for devices with
212  * color maps too small to do good color dithering. The argument
213  * ncolors is the number of colors of the devices color map that
214  * may be used for dithering.
215  */
216 
217 init_monochrome_color_map( ncolors )
218 int ncolors;
219 {
220  int k;
221  int color_val;
222 
223  /* Set up the color map entries into a single grayscale ramp. */
224  n_colmap_colors = ncolors; /* Fill out the global. */
225 
226  for ( k = 0; k < ncolors; k++ )
227  {
228  color_val = (k * 255) / (ncolors - 1);
229  colmap[k][0] = (color_val * r_base_color) / 255.;
230  colmap[k][1] = (color_val * g_base_color) / 255.;
231  colmap[k][2] = (color_val * b_base_color) / 255.;
232  }
233 
234  /* Make dithering tables. */
235  make_square( (double)ncolors, divN, errN, dm16 );
236 }
237 
238 
239 
240 #define DMAP(v,x,y) (errN[v]>dm16[x][y] ? divN[v] + 1 : divN[v])
241 
242 /*****************************************************************
243  * TAG( put_line_8 )
244  *
245  * Map a 24 bit scanline to 8 bits through the dither matrix.
246  */
247 
248 put_line_8( y )
249 int y;
250 {
251  register unsigned char *r, *g, *b;
252  register int i, dither_col, dither_row;
253  register starbase_color_index_type *dest_pixel_ptr;
254  int xmax = hdr.xmax;
255  int g_offset, b_offset;
256 
257 
258  /* In case we have less than 3 color channels. */
259  for (i = 2; i >= hdr.ncolors; i--)
260  bcopy(rows[0], rows[i], hdr.xmax - hdr.xmin);
261 
262  dither_row = y % 16;
263  dither_col = 0;
264  r = rows[0];
265  g = rows[1];
266  b = rows[2];
267  dest_pixel_ptr = &dest_pixels[0];
268 
269  /* Linear map. */
270  if ( linear_flag )
271  for ( i = 0; i < xmax; i++, r++, g++, b++,
272  dither_col = ((dither_col + 1) & 15),
273  dest_pixel_ptr++ )
274  *dest_pixel_ptr =
275  DMAP( *r, dither_col, dither_row ) +
276  DMAP( *g, dither_col, dither_row ) * 6 +
277  DMAP( *b, dither_col, dither_row ) * 36 +
279 
280  /* RLE file with color map. */
281  else if ( hdr.ncmap )
282  {
283  /* Compute offsets to the green and blue sections of the color map. */
284  g_offset = 1 << hdr.cmaplen;
285  b_offset = 2 * g_offset;
286 
287  for ( i = 0; i < xmax; i++, r++, g++, b++,
288  dither_col = ((dither_col + 1) & 15),
289  dest_pixel_ptr++ )
290  *dest_pixel_ptr =
291  DMAP( hdr.cmap[*r], dither_col, dither_row ) +
292  DMAP( hdr.cmap[*g + g_offset],
293  dither_col, dither_row ) * 6 +
294  DMAP( hdr.cmap[*b + b_offset],
295  dither_col, dither_row ) * 36 +
297  }
298 
299  /* Gamma correction is the default. */
300  else
301  for ( i = 0; i < xmax; i++, r++, g++, b++,
302  dither_col = ((dither_col + 1) & 15),
303  dest_pixel_ptr++ )
304  *dest_pixel_ptr =
305  DMAP( gammamap[*r], dither_col, dither_row ) +
306  DMAP( gammamap[*g], dither_col, dither_row ) * 6 +
307  DMAP( gammamap[*b], dither_col, dither_row ) * 36 +
309 
310  /* Write this scanline to the device. */
311  write_scanline( y );
312 }
313 
314 
315 
316 /*****************************************************************
317  * TAG( put_line_mono )
318  *
319  * For small color maps. Dither into monochrome.
320  */
321 
322 put_line_mono( y )
323 int y;
324 {
325  register unsigned char *r, *g, *b;
326  register int i, dither_col, dither_row;
327  register starbase_color_index_type *dest_pixel_ptr;
328  int xmax = hdr.xmax;
329  int bw_val;
330  int g_offset, b_offset;
331 
332  /* In case we have less than 3 color channels. */
333  for (i = 2; i >= hdr.ncolors; i--)
334  bcopy(rows[0], rows[i], hdr.xmax - hdr.xmin);
335 
336  dither_row = y % 16;
337  dither_col = 0;
338  r = rows[0];
339  g = rows[1];
340  b = rows[2];
341  dest_pixel_ptr = &dest_pixels[0];
342 
343  /* Linear map. */
344  if ( linear_flag )
345  for ( i = 0; i < xmax; i++, r++, g++, b++,
346  dither_col = ((dither_col + 1) & 15),
347  dest_pixel_ptr++ )
348  {
349  bw_val =
350  (35*(*r) + 55*(*g) + 10*(*b)) / 100;
351  *dest_pixel_ptr =
352  DMAP( bw_val, dither_col, dither_row ) + COLMAP_OFFSET;
353  }
354 
355  /* RLE file with color map. */
356  else if ( hdr.ncmap )
357  {
358  /* Compute offsets to the green and blue sections of the color map. */
359  g_offset = 1 << hdr.cmaplen;
360  b_offset = 2 * g_offset;
361 
362  for ( i = 0; i < xmax; i++, r++, g++, b++,
363  dither_col = ((dither_col + 1) & 15),
364  dest_pixel_ptr++ )
365  {
366  bw_val =
367  ( 35 * hdr.cmap[*r] +
368  55 * hdr.cmap[*g + g_offset] +
369  10 * hdr.cmap[*b + b_offset] ) / 100;
370  *dest_pixel_ptr =
371  DMAP( bw_val, dither_col, dither_row ) + COLMAP_OFFSET;
372  }
373  }
374 
375  /* Gamma correction is the default. */
376  else
377  for ( i = 0; i < xmax; i++, r++, g++, b++,
378  dither_col = ((dither_col + 1) & 15),
379  dest_pixel_ptr++ )
380  {
381  bw_val =
382  (35*gammamap[*r] + 55*gammamap[*g] + 10*gammamap[*b]) / 100;
383  *dest_pixel_ptr =
384  DMAP( bw_val, dither_col, dither_row ) + COLMAP_OFFSET;
385  }
386 
387  /* Write this scanline to the device. */
388  write_scanline( y );
389 }
390 
391 
392 
393 /*****************************************************************
394  * TAG( direct_setup )
395  *
396  * Use starbase to talk directly to graphics device.
397  */
398 
399 direct_setup()
400 {
401  single p_lim[2][3], res[3], p1[3], p2[3];
402  int map_size;
403  int dev_xmax, dev_ymax;
404 
405  picture_fd = gopen( display_name, OUTDEV, driver_name, 0 );
406  if ( picture_fd < 0 )
407  {
408  fprintf( stderr, "Can't open device.\n" );
409  exit( 1 );
410  }
411 
412  /* Find out info about this device. */
413  inquire_sizes( picture_fd, p_lim, res, p1, p2, &map_size );
414 
415  if ( map_size >= 256 )
416  {
418  init_8_bit_color_map();
419  }
420  else
421  {
423  init_monochrome_color_map( map_size - COLMAP_OFFSET );
424  }
425 
426  write_color_map( picture_fd );
427 
428  /* Set the screen limits in pixels so we can use starbase in a device
429  * independent way.
430  *
431  * It is assumed that the p_lim values returned by inquire_sizes are the
432  * lower left screen coordinates in (float) pixels and the upper right
433  * screen coordinates in (float) pixels. It is also assumed that the
434  * range of values in x and y coordinates are given from 0 to some
435  * positive maximum value.
436  */
437  dev_xmax = MAX( p_lim[0][0], p_lim[1][0] );
438  dev_ymax = MAX( p_lim[0][1], p_lim[1][1] );
439 
440  if ( hdr.xmax > dev_xmax )
441  hdr.xmax = dev_xmax;
442  if ( hdr.ymax > dev_ymax )
443  hdr.ymax = dev_ymax;
444 
445  /* Make sure that the specified lower left hand corner of the image
446  * will keep the image in bounds.
447  */
448  if ( ( hdr.xmax + pic_x ) > dev_xmax )
449  pic_x = dev_xmax - hdr.xmax;
450  if ( ( hdr.ymax + pic_y ) > dev_ymax )
451  pic_y = dev_ymax - hdr.ymax;
452 
453  /* Set to use the whole display surface. */
454  mapping_mode( picture_fd, DISTORT );
455 
456  /* Set to address the pixels in a device independent way. */
457  vdc_extent( picture_fd, 0.0, 0.0, 0.0,
458  (single)dev_xmax, (single)dev_ymax, 0.0 );
459  clip_rectangle( picture_fd, 0.0, (single)dev_xmax, 0.0, (single)dev_ymax );
460 
461 }
462 
463 
464 
465 /*****************************************************************
466  * TAG( write_color_map )
467  *
468  * Write color map to device.
469  *
470  */
471 
472 write_color_map( star_fd )
473 int star_fd;
474 {
475  define_color_table( star_fd, COLMAP_OFFSET, n_colmap_colors, colmap );
476 
477 }
478 
479 
480 
481 /*****************************************************************
482  * TAG( write_scanline )
483  *
484  * Write scanline to device.
485  *
486  */
487 
488 write_scanline( y )
489 int y;
490 {
491  block_write( picture_fd,
492  (single)(hdr.xmin + pic_x), (single)(y + pic_y),
493  hdr.xmax - hdr.xmin, 1,
494  dest_pixels, FALSE );
495 }
496 
497 
498 #ifdef NEED_BSTRING
499 
500 /*****************************************************************
501  * TAG( bcopy )
502  *
503  * Move contents of a block to a new location.
504  * For systems without a bcopy system routine.
505  */
506 void bcopy( src_ptr, dst_ptr, size )
507 register int * src_ptr, * dst_ptr;
508 int size;
509 {
510  register int words;
511  register char * byte_src_ptr, * byte_dst_ptr;
512  register int bytes;
513 
514  /* Tight word copy loop for most or all of the block. */
515  words=size/sizeof(int);
516  bytes = size - words*sizeof(int);
517  while ( words-- )
518  *dst_ptr++ = *src_ptr++;
519 
520  /* Tight byte copy loop for the remainder. */
521  byte_src_ptr = (char *)src_ptr;
522  byte_dst_ptr = (char *)dst_ptr;
523  while ( bytes-- )
524  *byte_dst_ptr++ = *byte_src_ptr++;
525 }
526 #endif
FILE * rle_open_f(char *prog_name, char *file_name, char *mode)
Definition: rle_open_f.c:216
int pos_flag
Definition: read98721.c:45
single starbase_color_type[3]
Definition: getbob.c:39
rle_hdr hdr
Definition: getx10.c:84
int pic_x
Definition: getbob.c:85
int xmin
Definition: rle.h:100
int errN[256]
Definition: getbob.c:61
int put_mode
Definition: getbob.c:92
void make_square(double N, divN, modN, magic)
Definition: dither.c:192
void rle_names(rle_hdr *the_hdr, const char *pgmname, const char *fname, int img_num)
Definition: rle_hdr.c:48
float gam
Definition: getbob.c:65
static starbase_color_type colmap[216]
Definition: getbob.c:96
char * cmd_name(char **argv)
Definition: cmd_name.c:31
void main(int argc, char **argv)
Definition: aliastorle.c:121
float r_base_color
Definition: getbob.c:99
#define FALSE
Definition: giftorle.c:39
starbase_color_index_type dest_pixels[1023]
Definition: getbob.c:55
rle_map * cmap
Definition: rle.h:112
int boolean
Definition: getbob.c:31
float b_base_color
Definition: getbob.c:101
int rle_getrow(rle_hdr *the_hdr, scanline)
Definition: rle_getrow.c:333
int divN[256]
Definition: to8.c:45
float single
Definition: getbob.c:34
int ymin
Definition: rle.h:100
int scanargs(int argc, char **argv, const char *format,...)
Definition: scanargs.c:94
int dev_color_map_size
Definition: getbob.c:89
unsigned char starbase_color_index_type
Definition: getbob.c:40
int dm16[16][16]
Definition: to8.c:42
string infname
Definition: getbob.c:68
const char * cmd
Definition: rle.h:133
int xmax
Definition: rle.h:100
char * driver_name
Definition: read98721.c:43
unsigned char scanline[4][1023]
Definition: getbob.c:52
void rle_get_setup_ok(rle_hdr *the_hdr, const char *prog_name, const char *file_name)
Definition: rle_getrow.c:254
#define MAX(i, j)
Definition: get4d.c:23
#define RLE_CLR_BIT(glob, bit)
Definition: rle.h:124
char * display_name
Definition: read98721.c:42
boolean gamma_flag
Definition: getbob.c:75
#define EIGHT_BIT_COLOR_MODE
Definition: getbob.c:49
int ncmap
Definition: rle.h:100
int ymax
Definition: rle.h:100
boolean linear_flag
Definition: getbob.c:74
float g_base_color
Definition: getbob.c:100
int cmaplen
Definition: rle.h:100
char * string
Definition: getbob.c:30
int gammamap[256]
Definition: getx10.c:68
#define RLE_ALPHA
Definition: rle.h:65
int picture_fd
Definition: read98721.c:77
#define RASTERSIZE_LIM
Definition: get_orion.c:24
#define DMAP(v, x, y)
Definition: get_orion.c:310
#define MONOCHROME_MODE
Definition: get_orion.c:25
#define COLMAP_OFFSET
Definition: getap.c:72
rle_hdr * rle_hdr_init(rle_hdr *the_hdr)
Definition: rle_hdr.c:267
int n_colmap_colors
Definition: getbob.c:95
boolean dummy
Definition: getbob.c:77
unsigned char * rows[4]
Definition: getbob.c:52
FILE * rle_file
Definition: rle.h:114
int pic_y
Definition: getbob.c:86
int ncolors
Definition: rle.h:100