Utah Raster Toolkit  9999-git
URT Development version (post-3.1b)
rlestereo.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 /*
19  * rlestereo.c - Merge two RLE images to form a single red-green or red-blue
20  * image suitable for viewing with them goofy glasses.
21  *
22  * Author: Craig E. Kolb
23  * Department of Mathematics
24  * Yale Unversity
25  * Date: Mon Jul 30 1990
26  * Copyright (C) 1990, Craig E. Kolb
27  */
28 #ifndef lint
29 char rcsid[] = "$Header: /l/spencer/src/urt/tools/RCS/rlestereo.c,v 3.0.1.3 1992/04/30 14:14:07 spencer Exp $";
30 #endif
31 /*
32 rlestereo() Tag the file.
33 */
34 
35 #include <stdio.h>
36 #include "rle.h"
37 
38 #define LEFTSCALE 0.7 /* Default left scale factor. */
39 #define RIGHTSCALE 1.0 /* Default right scale factor. */
40 
41 /*
42  * Macro to convert input values to greyscale, taking colormap into
43  * account.
44  */
45 #define REDC 0.30
46 #define GREENC 0.59
47 #define BLUEC 0.11
48 #define GREYCONV(r,g,b,m) (REDC*m[0][r]+GREENC*m[1][g]+BLUEC*m[2][b])
49 
50 float LeftScale = LEFTSCALE; /* Scale factor for left channel. */
51 float RightScale = RIGHTSCALE; /* Scale factor for right channel. */
52 int GreenFlag = 0; /* True if second channel is green. */
53 int Xres, Yres; /* Image resolution. */
54 int lcolors, rcolors; /* # channels in left/right images. */
55 int RightIndex; /* Index of second channel (1 or 2). */
56 int lchan1, lchan2; /* Channel indices for left image. */
57 int rchan1, rchan2; /* Channel indices for right image. */
58 rle_pixel **lmap, **rmap; /* Colormap for left/right images. */
59 
60 #ifdef USE_PROTOTYPES
61 void convert_line(rle_pixel **, rle_pixel **, rle_pixel **);
62 int get_rle_setup(rle_hdr *, int *, int *);
63 #else
64 void convert_line();
65 int get_rle_setup();
66 #endif
67 /*
68  * Read two named RLE files and produces a single image suitable for viewing
69  * with red-blue or red-green glasses. The 'left' image is converted to
70  * greyscale and written on the red channel. The 'right' image is converted
71  * to greyscale and written on the blue or green channel. The intensity of the
72  * two channels may be scaled in order to compensate for the relative
73  * intensities of the two base colors as viewed through the glasses.
74  *
75  * Options:
76  *
77  * -g Produce red-green image rather than red-blue.
78  * -l scale Scale factor for left-eye image (default 0.7).
79  * -r scale Scale factor for right-eye image (default 1.0).
80  */
81 
82 void
84 int argc;
85 char **argv;
86 {
87  int y, i, Xtmp, Ytmp, scaleflag = 0;
88  char *leftname = NULL, *rightname = NULL;
89  char *outname = NULL;
90  FILE *outfile = stdout;
91  int oflag;
92  rle_pixel **lline, **rline, **outline;
93  rle_hdr left_hdr, right_hdr, out_hdr;
94  int rle_cnt = 0, rle_err;
95  char *err_name = NULL;
96 
97  left_hdr = *rle_hdr_init( NULL );
98  right_hdr = *rle_hdr_init( NULL );
99  out_hdr = *rle_hdr_init( NULL );
100 
101  if (scanargs(argc, argv,
102  "% g%- l%-leftscale!f r%-rightscale!f o%-outfile!s \n\
103  leftimage!s rightimage!s",
104  &GreenFlag, &scaleflag, &LeftScale, &scaleflag, &RightScale,
105  &oflag, &outname,
106  &leftname, &rightname) == 0) {
107  exit(-1);
108  }
109 
110  /*
111  * Open left and right images.
112  */
113  (void)rle_hdr_init( &left_hdr );
114  (void)rle_hdr_init( &right_hdr );
115  left_hdr.rle_file = rle_open_f(cmd_name(argv), leftname, "r");
116  right_hdr.rle_file = rle_open_f(cmd_name(argv), rightname, "r");
117  rle_names( &left_hdr, cmd_name(argv), leftname, 0 );
118  rle_names( &right_hdr, cmd_name(argv), rightname, 0 );
119  rle_names( &out_hdr, left_hdr.cmd, outname, 0 );
120 
121  for ( rle_cnt = 0;; rle_cnt++ )
122  {
123  /*
124  * Read headers of both images.
125  */
126  if ( (rle_err =
127  get_rle_setup(&left_hdr, &Xres, &Yres)) != RLE_SUCCESS )
128  {
129  err_name = leftname;
130  break;
131  }
132  if ( (rle_err =
133  get_rle_setup(&right_hdr, &Xtmp, &Ytmp)) != RLE_SUCCESS )
134  {
135  err_name = rightname;
136  break;
137  }
138 
139  /* Open the output file when first header is successfully read. */
140  if ( rle_cnt == 0 )
141  outfile = rle_open_f( cmd_name( argv ), outname, "w" );
142 
143  if (Xres != Xtmp || Yres != Ytmp) {
144  fprintf(stderr,"Images are of different sizes.\n");
145  exit(-1);
146  }
147 
148  (void)rle_hdr_cp( &left_hdr, &out_hdr );
149  out_hdr.ncolors = 3;
150  out_hdr.ncmap = 0;
151  out_hdr.rle_file = outfile;
152  rle_addhist(argv, &left_hdr, &out_hdr);
153  rle_put_setup(&out_hdr);
154 
155  /*
156  * Ignore alpha and any channels > #2.
157  */
158  RLE_CLR_BIT(left_hdr, RLE_ALPHA);
159  RLE_CLR_BIT(right_hdr, RLE_ALPHA);
160  for (i = 3; i < left_hdr.ncolors; i++)
161  RLE_CLR_BIT(left_hdr, i);
162  for (i = 3; i < right_hdr.ncolors; i++)
163  RLE_CLR_BIT(right_hdr, i);
164 
165  lcolors = left_hdr.ncolors > 3 ? 3 : left_hdr.ncolors;
166  rcolors = right_hdr.ncolors > 3 ? 3 : right_hdr.ncolors;
167 
168  if (lcolors == 1)
169  lchan1 = lchan2 = 0;
170  else if (lcolors == 2) {
171  lchan1 = 1;
172  lchan2 = 0;
173  } else {
174  lchan1 = 1;
175  lchan2 = 2;
176  }
177 
178  if (rcolors == 1)
179  rchan1 = rchan2 = 0;
180  else if (rcolors == 2) {
181  rchan1 = 1;
182  rchan2 = 0;
183  } else {
184  rchan1 = 1;
185  rchan2 = 2;
186  }
187 
188  if ( rle_row_alloc(&left_hdr, &lline) < 0 ||
189  rle_row_alloc(&right_hdr, &rline) < 0 ||
190  rle_row_alloc(&out_hdr, &outline) < 0 )
191  RLE_CHECK_ALLOC( left_hdr.cmd, 0, "images" );
192  /*
193  * Zero unused channel of output scanline.
194  */
195  if (GreenFlag) {
196  RightIndex = 1;
197  bzero(outline[2], Xres * sizeof(rle_pixel));
198  } else {
199  RightIndex = 2;
200  bzero(outline[1], Xres * sizeof(rle_pixel));
201  }
202 
203  /*
204  * In case there's a colormap, DTRT. We use a gamma of 1.
205  * here because we want the output image to have the same
206  * gamma as the left image.
207  */
208  lmap = buildmap(&left_hdr, 3, 1., 1.0);
209  rmap = buildmap(&right_hdr, 3, 1., 1.0);
210  /*
211  * For each output scanline...
212  */
213  for (y = 0; y < Yres; y++) {
214  /*
215  * Read left and right scanline, converting each
216  * to greyscale data.
217  */
218  rle_getrow(&left_hdr, lline);
219  rle_getrow(&right_hdr, rline);
220  convert_line(outline, lline, rline);
221  rle_putrow(outline, Xres, &out_hdr);
222  }
223  while ( rle_getskip(&left_hdr) != 32768 )
224  ;
225  while ( rle_getskip(&right_hdr) != 32768 )
226  ;
227 
228  rle_row_free(&left_hdr, lline);
229  rle_row_free(&right_hdr, rline);
230  rle_row_free(&out_hdr, outline);
231 
232  rle_puteof( &out_hdr );
233  }
234  fclose(left_hdr.rle_file);
235  fclose(right_hdr.rle_file);
236 
237  /* Check for an error. EOF or EMPTY is ok if at least one image
238  * has been read. Otherwise, print an error message.
239  */
240  if ( rle_cnt == 0 || (rle_err != RLE_EOF && rle_err != RLE_EMPTY) )
241  rle_get_error( rle_err, cmd_name( argv ), err_name );
242  exit(0);
243 }
244 
245 int
247 int *xres, *yres;
248 rle_hdr *the_hdr;
249 {
250  int err;
251 
252  err = rle_get_setup(the_hdr);
253  *xres = the_hdr->xmax - the_hdr->xmin + 1;
254  *yres = the_hdr->ymax - the_hdr->ymin + 1;
255  the_hdr->xmax -= the_hdr->xmin;
256  the_hdr->xmin = 0;
257  return err;
258 }
259 
260 void
262 rle_pixel **out, **left, **right;
263 {
264  register int i;
265 
266  /*
267  * Convert input scanlines to 'stereo' output scanline.
268  */
269  for (i = 0; i < Xres; i++) {
270  out[0][i] = LeftScale * GREYCONV(left[0][i], left[lchan1][i],
271  left[lchan2][i], lmap);
272  out[RightIndex][i] = RightScale * GREYCONV(right[0][i],
273  right[rchan1][i], right[rchan2][i], rmap);
274  }
275 }
FILE * rle_open_f(char *prog_name, char *file_name, char *mode)
Definition: rle_open_f.c:216
char rcsid[]
Definition: rleswap.c:28
int xmin
Definition: rle.h:100
rle_pixel ** rmap
Definition: rlestereo.c:58
void convert_line(rle_pixel **out, rle_pixel **left, rle_pixel **right)
Definition: rlestereo.c:261
rle_hdr * rle_hdr_cp(rle_hdr *from_hdr, rle_hdr *to_hdr)
Definition: rle_hdr.c:119
#define LEFTSCALE
Definition: rlestereo.c:38
int lchan1
Definition: rlestereo.c:56
float RightScale
Definition: rlestereo.c:51
#define USE_PROTOTYPES
Definition: rle_config.h:22
void rle_names(rle_hdr *the_hdr, const char *pgmname, const char *fname, int img_num)
Definition: rle_hdr.c:48
void rle_row_free(rle_hdr *the_hdr, rle_pixel **scanp)
Definition: rle_row_alc.c:114
#define RLE_EMPTY
Definition: rle.h:73
char * cmd_name(char **argv)
Definition: cmd_name.c:31
void main(int argc, char **argv)
Definition: aliastorle.c:121
int rle_get_setup(rle_hdr *the_hdr)
Definition: rle_getrow.c:74
int rle_row_alloc(rle_hdr *the_hdr, rle_pixel ***scanp)
Definition: rle_row_alc.c:56
int rchan2
Definition: rlestereo.c:57
int rle_getrow(rle_hdr *the_hdr, scanline)
Definition: rle_getrow.c:333
#define REDC
Definition: rlestereo.c:45
#define RLE_SUCCESS
Definition: rle.h:70
int RightIndex
Definition: rlestereo.c:55
int ymin
Definition: rle.h:100
int rle_get_error(int code, const char *pgmname, const char *fname)
Definition: rle_error.c:76
int lcolors
Definition: rlestereo.c:54
int get_rle_setup(rle_hdr *the_hdr, int *xres, int *yres)
Definition: rlestereo.c:246
int scanargs(int argc, char **argv, const char *format,...)
Definition: scanargs.c:94
int Xres
Definition: rlestereo.c:53
rle_pixel ** buildmap(rle_hdr *the_hdr, int minmap, double orig_gamma, double new_gamma)
Definition: buildmap.c:56
const char * cmd
Definition: rle.h:133
void rle_puteof(rle_hdr *the_hdr)
Definition: rle_putrow.c:474
void rle_putrow(rows, int rowlen, rle_hdr *the_hdr)
Definition: rle_putrow.c:96
int xmax
Definition: rle.h:100
float LeftScale
Definition: rlestereo.c:50
rle_pixel ** lmap
Definition: rlestereo.c:58
#define RLE_EOF
Definition: rle.h:74
void rle_addhist(argv, rle_hdr *in_hdr, rle_hdr *out_hdr)
Definition: rle_addhist.c:54
unsigned int rle_getskip(rle_hdr *the_hdr)
Definition: rle_getskip.c:57
int rcolors
Definition: rlestereo.c:54
#define RLE_CLR_BIT(glob, bit)
Definition: rle.h:124
#define GREYCONV(r, g, b, m)
Definition: rlestereo.c:48
int ncmap
Definition: rle.h:100
int ymax
Definition: rle.h:100
unsigned char rle_pixel
Definition: rle.h:56
void rle_put_setup(rle_hdr *the_hdr)
Definition: rle_putrow.c:453
int rchan1
Definition: rlestereo.c:57
#define RLE_ALPHA
Definition: rle.h:65
#define BLUEC
Definition: rlestereo.c:47
int Yres
Definition: rlestereo.c:53
int GreenFlag
Definition: rlestereo.c:52
int lchan2
Definition: rlestereo.c:56
#define RIGHTSCALE
Definition: rlestereo.c:39
rle_hdr * rle_hdr_init(rle_hdr *the_hdr)
Definition: rle_hdr.c:267
#define GREENC
Definition: rlestereo.c:46
FILE * rle_file
Definition: rle.h:114
int ncolors
Definition: rle.h:100
#define RLE_CHECK_ALLOC(pgm, ptr, name)
Definition: rle.h:86