Utah Raster Toolkit  9999-git
URT Development version (post-3.1b)
get_orion.c
Go to the documentation of this file.
1 /*
2  * getOrion.c - Put RLE images on a High-Level Hardware Orion
3  *
4  * Author: Gianpaolo F M Tommasi
5  * Computer Laboratory
6  * University of Cambridge
7  * Last Edit: 19 July 1987
8  *
9  * Based on code by Spencer W Thomas, John W Peterson and Mark Blommenthal
10  * Copyright (c) 1986, University of Utah
11  *
12  */
13 
14 #include <stdio.h>
15 #include <math.h>
16 #include <graphics/grafix.h>
17 #include <graphics/window.h>
18 #include <graphics/control.h>
19 #include <graphics/events.h>
20 #include <sys/ioctl.h>
21 #include <machine/graphics.h>
22 #include "rle.h"
23 
24 #define RASTERSIZE_LIM 1280
25 #define MONOCHROME_MODE 1
26 #define EIGHT_BIT_COLOUR_MODE 2
27 #define MONOCHROME_ENTRIES 128
28 
29 /* TRUE and FALSE defined in graphics/grafix.h */
30 
31 typedef int boolean; /* logical vars and values */
32 
33 /* RLE image header. */
34 rle_hdr *hdr;
35 
36 /* RLE Scanline storage & row pointers */
37 unsigned char scanline[4][RASTERSIZE_LIM], *rows[4];
38 
39 /* Scanline to be written to device points to scanline bitmap*/
40 unsigned char dest_pixels[RASTERSIZE_LIM];
41 
42 /* Variables for translate_bits: bitmap for scan line and rectangle */
45 
46 
47 /* dither matrix */
48 int dm16[16][16];
49 
50 /* tables for quantisation */
51 int errN[256], divN[256];
52 
53 /* The gamma map and default gamma */
54 int gammamap[256];
55 float gam = 2.0; /* good default value */
56 
57 /* Colour map flags */
61 
62 /* What mode to dither into. Either 8 bit color or monochrome */
64 
65 /* Colour map to be written to device */
67 int colmap[256][3];
68 
69 /* StarPoint variables */
74 int thePart;
75 boolean isActive = FALSE;
77 
78 /* Debug flag */
80 
81 /* reverse order of scan lines */
83 
84 /* make a special case of having 1 colour channel and 3 colour map
85  channels */
87 
88 
89 /****************************************************************************
90  * TAG( main )
91  *
92  * Usage:
93  * getOrion [-D] [-b] [-f] [-g gamma] [-l] [-r] [file]
94  *
95  * Inputs:
96  * -D: Degub mode.
97  * -b: Dither to monochrome picture
98  * -f: Use all the 256 entries of the device colour look-up table
99  * -g gam: Gamma map, use a gamma of gam (floating point number)
100  * -l: Linear map (gamma of 1)
101  * -r: Reverse the order of display of scanlines, i.e. start from
102 
103  * the top
104  * file: Input Run Length Encoded file, stdin used if not
105  * specified.
106  * Outputs:
107  * Puts image on the screen.
108  * Assumptions:
109  * Input file is in RLE format.
110  * Algorithm:
111  * [none]
112  */
113 
115 int argc;
116 char *argv[];
117 {
118  int i, temp;
119  int bw_flag = 0;
120  char *infname = NULL, *window_name;
121  FILE *fopen();
122  Rect r;
123 
124  hdr = *rle_hdr_init( (rle_hdr *)NULL );
125 
126  /* Get command line arguments */
127  if (scanargs(argc, argv, "getOrion D%- w%- f%- g%-gamma!f l%- r%- infile
128 %s",
129  &debug_flag, &bw_flag, &all_colours_flag,
130  &gamma_flag, &gam, &linear_flag, &reverse_flag, &infname) == 0)
131  exit(1);
132 
133  /* Open file for reading, if no filename was specified, read from
134  stdin */
135  rle_names( &hdr, cmd_name( argv ), infname, 0 );
136  hdr.rle_file = rle_open_f(hdr.cmd, infname, "r");
137 
138  temp = rle_get_setup(&hdr);
139  if (temp < 0) {
140  fprintf(stderr, "getOrion: error reading setup information from %s\n",
141  infname ? infname : "stdin");
142  fprintf(stderr, "with return code %d\n", temp);
143  exit(1);
144  }
145 
146  if (debug_flag) rle_debug(1);
147 
148  /* a linear map has no gamma correction */
149  if (linear_flag) gam = 1.0;
150 
151  /* Set up gamma correction table */
152  init_gamma_map();
153 
154  /* we're only interested in R, G and B */
156  for (i = 3; i < hdr.ncolors; i++)
157  RLE_CLR_BIT(hdr, i);
158 
159  /* Set up rows to point to our copy of the scanline */
160  for (i = 0; i < 3; i++)
161  rows[i] = scanline[i];
162 
163  /* Pretend origin is at 0,0 */
164  hdr.xmax -= hdr.xmin;
165  hdr.xmin = 0;
166  hdr.ymax -= hdr.ymin;
167  hdr.ymin = 0;
168 
169  /* shift the colour map, if present, down to 8 bits precision */
170  for (i = 0; i < hdr.ncmap * (1 << hdr.cmaplen); i++)
171  hdr.cmap[i] = hdr.cmap[i] >> 8;
172 
173  if (bw_flag) {
175  init_monochrome_colour_map();
176  }
177  else if ((hdr.ncmap == 3) && hdr.ncolors == 1) {
178  /* one channel and 24-bit colour map supplied */
179  init_24_bit_colour_map();
180  onec_threem_mode = TRUE;
181  }
182  else
183  /* use 216 standard colour map */
184  init_8_bit_colour_map();
185 
186  /* Initialise the device and create window */
187  InitGraf();
188  window_size_x = hdr.xmax + 1;
189  window_size_y = hdr.ymax + 1;
190  SetRect (&r, 50, 50, window_size_x, window_size_y);
191  if (infname == NULL)
192  window_name = "piped";
193  else {
194  window_name = infname;
195  }
196  rle_window = NewWindow(NIL, r, window_name, VISIBLE, noGrowDocProc, FRONT,
197  GOAWAY, 0, 7);
198  PenPat(black);
199  UpdateWindow(rle_window, TRUE);
200  write_colour_map();
201 
202  /* make the scan line bit map */
203  scanbitmap = NewRBitMap(window_size_x, 1, 8); /* really need only one pla
204 ne */
205 
206  /* Get the scanlines */
207  for (i = hdr.ymin; i <= hdr.ymax; i++) {
209  if (put_mode == MONOCHROME_MODE)
210  put_line_mono(i);
211  else
212  put_line_8(i);
213  }
214 
215  /* loop */
216  EventLoop();
217 }
218 
219 
220 
221 
222 /*************************************************
223  * TAG (init_gamma_map )
224  *
225  * Compute a gamma correction map
226  */
227 
228 init_gamma_map()
229 {
230  int i;
231 
232  for (i = 0; i < 256; i++) {
233  gammamap[i] = (int) (0.5 + 255 * pow(i / 255.0, 1.0/gam));
234  }
235 }
236 
237 
238 /*********************************
239  * TAG( init_8_bit_colour_map )
240  *
241  * Initialise the 8 bit colour map
242  */
243 
244 init_8_bit_colour_map()
245 {
246  double gamma;
247 
248  /* Set up the colour map entries. We will use 216 colours. */
249  n_colmap_colours = 216;
250 
251  /* calculate tables but don't gamma correct the colour map */
252  gamma = 1.0;
254 }
255 
256 
257 /************************************************************
258  * TAG( init_monochrome_colour_map )
259  *
260  * Initialize the monchrome colour map. This routine is called when the -b
261  * flag is used.
262  */
263 
264 init_monochrome_colour_map()
265 {
266  int i, bwmap[256];
267  double gamma;
268 
269  /* Set up the colour map entries into a single greyscale ramp */
271 
272  /* calculate tables but don't gamma correct the colour map */
273  gamma = 1.0;
275  for (i = 0; i < n_colmap_colours; i++)
276  colmap[i][0] = colmap[i][1] = colmap[i][2] = bwmap[i];
277 
278 }
279 
280 
281 
282 /***********************************************
283  * TAG (init_24_bit_colour_map)
284  *
285  * Sets the colour map to the one supplied in the RLE header
286  *
287  */
288 
289 init_24_bit_colour_map()
290 {
291  int i, g_offset, b_offset;
292 
293  /* set up the colour map entries, will use the number supplied in the
294  header */
296  g_offset = n_colmap_colours;
297  b_offset = 2 * g_offset;
298 
299  /* set the device colour map to the one in the header */
300  for (i = 0; i < n_colmap_colours; i++) {
301  colmap[i][0] = hdr.cmap[i];
302  colmap[i][1] = hdr.cmap[i + g_offset];
303  colmap[i][2] = hdr.cmap[i + b_offset];
304  }
305 }
306 
307 
308 
309 /* Dithering operation */
310 #define DMAP(v, x, y) (errN[v]>dm16[x][y] ? divN[v]+1 : divN[v])
311 
312 /************************************************************
313  * TAG(put_line_8)
314  *
315  * Map a 24 bit scanline to 8 bits through the dither matrix
316  */
317 
318 put_line_8(yscan)
319 int yscan;
320 {
321  unsigned char *r, *g, *b;
322  int i, dither_col, dither_row;
323  int xmax = hdr.xmax;
324  int g_offset, b_offset;
325  unsigned char *dest_pixel_ptr;
326 
327  /* treat 1 colour and 3 colmap channels as special case */
328  if (onec_threem_mode) {
329  bcopy(rows[0], dest_pixels, xmax+1);
330  write_scanline(yscan);
331  return;
332  }
333 
334  dither_row = yscan % 16;
335  dither_col = 0;
336  dest_pixel_ptr = dest_pixels;
337  r = rows[0];
338  /* check if we have less than three colour channels */
339  g = rows[(hdr.ncolors >= 2 ? 1 : 0)];
340  b = rows[(hdr.ncolors >= 3 ? 2 : 0)];
341 
342  /* RLE file with colour map */
343  if (hdr.ncmap) {
344  /* offsets to the green and blue sections of the map */
345  g_offset = 1 << hdr.cmaplen;
346  b_offset = 2 * g_offset;
347 
348  for (i = 0; i <= xmax; i++, r++, g++, b++,
349  dither_col = ((dither_col + 1) & 15),
350  dest_pixel_ptr++)
351  *dest_pixel_ptr =
352  DMAP(hdr.cmap[*r], dither_col, dither_row) +
353  DMAP(hdr.cmap[*g + g_offset], dither_col,
354  dither_row) * 6 +
355  DMAP(hdr.cmap[*b + b_offset], dither_col,
356  dither_row) * 36;
357  }
358 
359  else
360  for (i = 0; i <= xmax; i++, r++, g++, b++,
361  dither_col = ((dither_col + 1) & 15),
362  dest_pixel_ptr++) {
363  *dest_pixel_ptr =
364  DMAP(*r, dither_col, dither_row) +
365  DMAP(*g, dither_col, dither_row) * 6 +
366  DMAP(*b, dither_col, dither_row) * 36;
367  }
368 
369  /* Write the scanline to the device */
370  write_scanline(yscan);
371 }
372 
373 
374 /*****************************************************************
375  * TAG( put_line_mono )
376  *
377  * Dither into monochrome
378  */
379 
380 put_line_mono(yscan)
381 int yscan;
382 {
383  unsigned char *r, *g, *b;
384  int i, dither_col, dither_row;
385  unsigned char *dest_pixel_ptr;
386  int xmax = hdr.xmax;
387  int bw_val;
388  int g_offset, b_offset;
389 
390  dither_row = yscan % 16;
391  dither_col = 0;
392  dest_pixel_ptr = dest_pixels;
393 
394  r = rows[0];
395  /* check if we have less than three colour channels */
396  g = rows[(hdr.ncolors >= 2 ? 1 : 0)];
397  b = rows[(hdr.ncolors >= 3 ? 2 : 0)];
398 
399  /* RLE file with colour map */
400  if (hdr.ncmap) {
401  /* offsets in table */
402  g_offset = 1 << hdr.cmaplen;
403  b_offset = 2 * g_offset;
404 
405  for (i = 0; i <= xmax; i++, r++, g++, b++,
406  dither_col = ((dither_col + 1) & 15),
407  dest_pixel_ptr++) {
408  bw_val =
409  (35 * hdr.cmap[*r] +
410  55 * hdr.cmap[*g + g_offset] +
411  10 * hdr.cmap[*b + b_offset]) / 100;
412  *dest_pixel_ptr = DMAP(bw_val, dither_col, dither_row);
413  }
414  }
415 
416  /* Gamma correction is the default */
417  else
418  for (i = 0; i <= xmax; i++, r++, g++, b++,
419  dither_col = ((dither_col + 1) & 15),
420  dest_pixel_ptr++) {
421  bw_val =
422  (35*(*r) + 55*(*g) + 10*(*b)) / 100;
423  *dest_pixel_ptr =
424  DMAP(bw_val, dither_col, dither_row);
425  }
426 
427  /* write the scanline */
428  write_scanline(yscan);
429 }
430 
431 
432 /* graphics device colour look-up table operations */
433 #define WriteCLT(cltp) (ioctl (_gdev, GTIOCSCLT, &(cltp)))
434 #define ReadCLT(cltp) (ioctl (_gdev, GTIOCGCLT, &(cltp)))
435 
436 /***********************************************
437  * TAG ( write_colour_map )
438  *
439  * Loads the graphics colour look up table
440  */
441 
442 write_colour_map()
443 {
444  int cltable[256], i;
445  int *cltp = cltable; /* to avoid warning */
446  int terminate;
447 
448  /* Need to preserve colours 240-255 by default */
449  if (all_colours_flag)
450  terminate = 256;
451  else {
452  /* read in current CLT */
453  ReadCLT(cltp);
454  terminate = (n_colmap_colours < 240 ? n_colmap_colours : 240);
455  }
456 
457  /* create the colour look up table, changing only required number of
458  colours, and gamma correcting */
459  for (i = 0; i < terminate; i++)
460  cltable[i] = (gammamap[colmap[i][0]] << 16) +
461  (gammamap[colmap[i][1]] << 8) +
462  gammamap[colmap[i][2]];
463 
464  /* Write it to the device */
465  WriteCLT(cltp);
466 }
467 
468 
469 /********************************************************
470  * TAG ( write_scanline )
471  *
472  * writes the scanline data, held in dest_pixels, to the device
473  */
474 
475 write_scanline(yscan)
476 int yscan;
477 {
478  if (!reverse_flag)
479  yscan = hdr.ymax - yscan;
480 
481  /* the following may seem like a long-winded way of doing things,
482  * but it's a lot quicker than setting points and lines with the usual
483  * routines .
484  */
485 
486  /* set destination rectangle */
487  SetRect(&trandr, 0, yscan, window_size_x, 1);
488 
489  /* translate the scanline data to the corresponding strip in the
490  window */
491  translate_bits(&((*rle_window).port.portBits), trandr);
492 
493  /* add strip to the update list of window and update */
494  AddUpdate(rle_window, trandr, 255);
495  UpdateWindow(rle_window, TRUE);
496 }
497 
498 
499 /* translate_bits - takes a scanline (dest_pixels) and translates the bits
500  * within the bytes so to be able to display it in BW mode. It extracts
501  * a plane of bits made out of the bits from the same position within a
502  * byte from the source scanline. Each plane is then rasterop-ed to the
503  * corresponding plane in the window bit map. The version is not general
504  * since it has been tuned to the current requirement, a more general
505  * version can be found in the StarPoint Library.
506  * Inputs: db is the destination BitMap,
507  * dr is a rectangle specifying where in the window to put the scanlin
508 e
509  */
510 
511 translate_bits(db, dr)
512 BitMapPtr db;
513 Rect dr;
514 {
515  Ptr sa = scanbitmap.baseAddr;
516  unsigned sw = scanbitmap.rowBits;
517  Ptr da = db->baseAddr;
518  int dy = top(dr);
519  unsigned dw = db->rowBits;
520  unsigned dh = db->colBits;
521  unsigned dps = db->planeSize;
522  int cw = width (db->bounds);
523  int ch = height (db->bounds);
524  unsigned w = window_size_x;
525  int *scanad;
526  unsigned char *srcad;
527  register int dest;
528  int bitpos, bytes_in_source;
529  int plane = 7; /* all planes are of interest */
530 
531  while(plane+1) {
532  scanad = scanbitmap.baseAddr; /* baseAddr is always word-aligned */
533  srcad = dest_pixels;
534  bitpos = dest = 0;
535  bytes_in_source = window_size_x;
536 
537  while(bytes_in_source){
538  /* *srcad++ >> plane is a logical shift */
539  dest = dest | (((*srcad++ >> plane) & 0x01) << bitpos);
540  if (bitpos++ == 31) {
541  *scanad++ = dest;
542  dest = bitpos = 0;
543  }
544  bytes_in_source--;
545  }
546  *scanad = dest; /* might be some residue */
547 
548  /* raster op the translated scanline to the plane in window */
549  rasterop(sa, sw, 1, 0, 0,
550  da, dw, dh, 1, 23, cw, ch,
551  0, dy, w, 1, srcCopy);
552 
553  plane--;
554  da += dps;
555  }
556 }
557 
558 
559 /********************************************************************
560  * TAG( EventLoop )
561  *
562  * Deals with StarPoint.
563  */
564 
565 
566 EventLoop ()
567 {
568  while (TRUE)
569  {
570  GetNextEvent (everyEvent, &myEvent);
571  switch (myEvent.what)
572  {
573  case mouseDown:
574  whichWindow = (WindowPtr) myEvent.refCon;
575  switch (FindWindow (myEvent.where, whichWindow))
576  {
577  case inGoAway:
578  if (TrackGoAway (whichWindow, myEvent.where))
579  {
580  MyClose ();
581  }
582  break;
583 
584  case inDrag:
585  DragWindow (whichWindow, myEvent.where, stdBoundsRect);
586  break;
587 
588  case inContent:
589  if (whichWindow != FrontWindow ())
590  {
591  BringToFront (whichWindow);
592  }
593  else
594  {
595  myPt = myEvent.where;
596  GlobalToLocal (&myPt);
597  }
598  break;
599  }
600  break; /* End of mouseDown */
601 
602  case activate:
603  MyActivate ();
604  break;
605  }
606  } /* while (TRUE) */
607 }
608 
609 
610 MyClose ()
611 {
612  exit (0);
613 }
614 
615 
616 
617 MyActivate ()
618 {
619  WindowPtr theWindow;
620  Bool theState;
621 
622  theWindow = (WindowPtr) myEvent.message;
623  theState = (myEvent.modifiers & activateFlag) != 0;
624  if (theState)
625  {
626  if (!isActive)
627  {
628  HiliteWindow (theWindow, TRUE);
629  SetPort (theWindow);
630  isActive = TRUE;
631  }
632  }
633  else
634  {
635  HiliteWindow (theWindow, FALSE);
636  isActive = FALSE;
637  }
638 }
FILE * rle_open_f(char *prog_name, char *file_name, char *mode)
Definition: rle_open_f.c:216
Rect trandr
Definition: get_orion.c:44
rle_hdr hdr
Definition: getx10.c:84
int xmin
Definition: rle.h:100
EventRecord myEvent
Definition: get_orion.c:71
boolean onec_threem_mode
Definition: get_orion.c:86
int errN[256]
Definition: getbob.c:61
int boolean
Definition: get_orion.c:31
BitMap scanbitmap
Definition: get_orion.c:43
int put_mode
Definition: getbob.c:92
#define EIGHT_BIT_COLOUR_MODE
Definition: get_orion.c:26
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
void rle_debug(int on_off)
Definition: rle_getrow.c:293
Boolean debug_flag
Definition: get_orion.c:79
char * cmd_name(char **argv)
Definition: cmd_name.c:31
int window_size_x
Definition: get_orion.c:76
void main(int argc, char **argv)
Definition: aliastorle.c:121
int rle_get_setup(rle_hdr *the_hdr)
Definition: rle_getrow.c:74
starbase_color_index_type dest_pixels[1023]
Definition: getbob.c:55
rle_map * cmap
Definition: rle.h:112
int rle_getrow(rle_hdr *the_hdr, scanline)
Definition: rle_getrow.c:333
int divN[256]
Definition: to8.c:45
boolean isActive
Definition: get_orion.c:75
boolean reverse_flag
Definition: get_orion.c:82
boolean all_colours_flag
Definition: get_orion.c:60
int ymin
Definition: rle.h:100
int window_size_y
Definition: get_orion.c:76
void dithermap(int levels, double gamma, rgbmap, divN, modN, magic)
Definition: dither.c:80
int dm16[16][16]
Definition: to8.c:42
#define WriteCLT(cltp)
Definition: get_orion.c:433
const char * cmd
Definition: rle.h:133
int xmax
Definition: rle.h:100
int n_colmap_colours
Definition: get_orion.c:66
int thePart
Definition: get_orion.c:74
WindowPtr whichWindow
Definition: get_orion.c:72
#define ReadCLT(cltp)
Definition: get_orion.c:434
unsigned char scanline[4][1023]
Definition: getbob.c:52
#define RLE_CLR_BIT(glob, bit)
Definition: rle.h:124
int colmap[216][3]
Definition: to8.c:39
boolean gamma_flag
Definition: getbob.c:75
int ncmap
Definition: rle.h:100
int ymax
Definition: rle.h:100
boolean linear_flag
Definition: getbob.c:74
int cmaplen
Definition: rle.h:100
int gammamap[256]
Definition: getx10.c:68
#define RLE_ALPHA
Definition: rle.h:65
#define RASTERSIZE_LIM
Definition: get_orion.c:24
#define MONOCHROME_ENTRIES
Definition: get_orion.c:27
#define DMAP(v, x, y)
Definition: get_orion.c:310
#define MONOCHROME_MODE
Definition: get_orion.c:25
Point myPt
Definition: get_orion.c:73
WindowPtr rle_window
Definition: get_orion.c:70
unsigned char * rows[4]
Definition: getbob.c:52
FILE * rle_file
Definition: rle.h:114
int ncolors
Definition: rle.h:100
void bwdithermap(int levels, double gamma, bwmap, divN, modN, magic)
Definition: dither.c:142