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  * rlatorle - A program which will convert Wavefront's "rla" or "rlb" images
20  *            into Utah's "rle" image format.
21  *
22  * Author:      Wesley C. Barris
23  *              AHPCRC
24  *              Minnesota Supercomputer Center, Inc.
25  * Date:        June 20, 1990
26  *              Copyright @ 1990, Minnesota Supercomputer Center, Inc.
27  *
28  * RESTRICTED RIGHTS LEGEND
29  *
30  * Use, duplication, or disclosure of this software and its documentation
31  * by the Government is subject to restrictions as set forth in subdivision
32  * { (b) (3) (ii) } of the Rights in Technical Data and Computer Software
33  * clause at 52.227-7013.
34  */
35 static char rcsid[] = "$Header: /l/spencer/src/urt/cnv/RCS/rlatorle.c,v 3.0.1.5 1992/04/30 13:58:32 spencer Exp $";
36 /*
37 rlatorle()				Tag the file.
38 */
39 /*-----------------------------------------------------------------------------
40  * System includes.
41  */
42 #include "rle.h"
43 #include <string.h>
44 #include "rla_header.h"
45 #include "rlb_header.h"
46 
47 #define VPRINTF if (verbose || header) fprintf
48 
49 typedef unsigned char U_CHAR;
50 /*
51  * Global variables.
52  */
53 rle_hdr         hdr;
54 union
55 {
56     RLA_HEADER	rla_head;
57     RLB_HEADER	rlb_head;
58 } head;
59 
60 #ifdef CRAY2CC
61 #define SHORTREAD(var, fp) {fread(&craybuf, 2, 1, fp); *var=craybuf>>48;}
62 #define LONGREAD(var, fp) {fread(&craybuf, 4, 1, fp); *var=craybuf>>32;}
63 #else
64 #define SHORTREAD(var, fp) {fread(var, 2, 1, fp);}
65 #define LONGREAD(var, fp) {fread(var, 4, 1, fp);}
66 #endif
67 
68 static FILE		*fp;
69 static int		act_x_res, act_y_res;
70 static int		width, height;
71 static int		verbose = 0, header = 0, do_matte = 0;
72 static int		rlb_flag = 0;
73 /*-----------------------------------------------------------------------------
74  *                                        Read the Wavefront image file header.
75  */
read_rla_header(act_x_res,act_y_res,width,height)76 void read_rla_header(act_x_res, act_y_res, width, height)
77 int *act_x_res;
78 int *act_y_res;
79 int *width;
80 int *height;
81 {
82 
83 #ifdef CRAY2CC
84    long craybuf;
85 
86    SHORTREAD(&head.rla_head.window.left, fp);
87    SHORTREAD(&head.rla_head.window.right, fp);
88    SHORTREAD(&head.rla_head.window.bottom, fp);
89    SHORTREAD(&head.rla_head.window.top, fp);
90    SHORTREAD(&head.rla_head.active_window.left, fp);
91    SHORTREAD(&head.rla_head.active_window.right, fp);
92    SHORTREAD(&head.rla_head.active_window.bottom, fp);
93    SHORTREAD(&head.rla_head.active_window.top, fp);
94    SHORTREAD(&head.rla_head.frame, fp);
95    SHORTREAD(&head.rla_head.storage_type, fp);
96    SHORTREAD(&head.rla_head.num_chan, fp);
97    SHORTREAD(&head.rla_head.num_matte, fp);
98    SHORTREAD(&head.rla_head.num_aux, fp);
99    SHORTREAD(&head.rla_head.aux_mask, fp);
100    fread(&head.rla_head.gamma, 16, 1, fp);
101    fread(&head.rla_head.red_pri, 24, 1, fp);
102    fread(&head.rla_head.green_pri, 24, 1, fp);
103    fread(&head.rla_head.blue_pri, 24, 1, fp);
104    fread(&head.rla_head.white_pt, 24, 1, fp);
105    LONGREAD(&head.rla_head.job_num, fp);
106    fread(&head.rla_head.name, 128, 1, fp);
107    fread(&head.rla_head.desc, 128, 1, fp);
108    fread(&head.rla_head.program, 64, 1, fp);
109    fread(&head.rla_head.machine, 32, 1, fp);
110    fread(&head.rla_head.user, 32, 1, fp);
111    fread(&head.rla_head.date, 20, 1, fp);
112    if (rlb_flag) {
113       fread(&head.rlb_head.aspect, 24, 1, fp);
114       fread(&head.rlb_head.aspect_ratio, 8, 1, fp);
115       fread(&head.rlb_head.chan, 32, 1, fp);
116       SHORTREAD(&head.rlb_head.field, fp);
117       SHORTREAD(&head.rlb_head.filter_type, fp);
118       LONGREAD(&head.rlb_head.magic_number, fp);
119       LONGREAD(&head.rlb_head.lut_size, fp);
120       LONGREAD(&head.rlb_head.user_space_size, fp);
121       LONGREAD(&head.rlb_head.wf_space_size, fp);
122       SHORTREAD(&head.rlb_head.lut_type, fp);
123       SHORTREAD(&head.rlb_head.mix_type, fp);
124       SHORTREAD(&head.rlb_head.encode_type, fp);
125       SHORTREAD(&head.rlb_head.padding, fp);
126       fread(&head.rlb_head.space, 100, 1, fp);
127       }
128    else {
129       fread(&head.rla_head.aspect, 32, 1, fp);
130       fread(&head.rla_head.chan, 32, 1, fp);
131       fread(&head.rla_head.space, 128, 1, fp);
132       }
133 #else
134    if (fread(&head, 740, 1, fp) != 1) {
135       fprintf(stderr, "Error reading Wavefront file header!\n");
136       exit(-2);
137       }
138 #endif
139    *act_x_res = head.rla_head.active_window.right-
140        head.rla_head.active_window.left+1;
141    *act_y_res = head.rla_head.active_window.top-
142        head.rla_head.active_window.bottom+1;
143    *width     = head.rla_head.window.right-head.rla_head.window.left+1;
144    *height    = head.rla_head.window.top-head.rla_head.window.bottom+1;
145    VPRINTF(stderr, "Full image:         %dx%d\n", *width, *height);
146    VPRINTF(stderr, "Active window:      %dx%d\n", *act_x_res, *act_y_res);
147    VPRINTF(stderr, "Number of channels: %d\n", head.rla_head.num_chan);
148    VPRINTF(stderr, "Number of mattes:   %d\n", head.rla_head.num_matte);
149    VPRINTF(stderr, "Image gamma:        %s\n", head.rla_head.gamma);
150    VPRINTF(stderr, "Original filename:  %s\n", head.rla_head.name);
151    VPRINTF(stderr, "Description:        %s\n", head.rla_head.desc);
152    VPRINTF(stderr, "Machine:            %s\n", head.rla_head.machine);
153    VPRINTF(stderr, "User:               %s\n", head.rla_head.user);
154    VPRINTF(stderr, "Date:               %s\n", head.rla_head.date);
155    if ( rlb_flag ) {
156        VPRINTF(stderr, "Aspect:             %s\n", head.rlb_head.aspect);
157        VPRINTF(stderr, "Aspect ratio:       %s\n", head.rlb_head.aspect_ratio);
158        }
159    else {
160        VPRINTF(stderr, "Aspect:             %s\n", head.rla_head.aspect);
161        VPRINTF(stderr, "Aspect ratio:       %s\n", "-unused-");
162        }
163    VPRINTF(stderr, "Channel color space %s\n", head.rla_head.chan);
164    if ( rlb_flag )
165        VPRINTF(stderr, "Interlaced?         %hd\n", head.rlb_head.filter_type);
166    else
167        VPRINTF(stderr, "Interlaced?         %s\n", "-unused-");
168    if (do_matte)
169       VPRINTF(stderr, "Converting matte channel only...\n");
170 }
171 /*-----------------------------------------------------------------------------
172  *                                             Write the rle image file header.
173  */
write_rle_header()174 void write_rle_header()
175 {
176    hdr.xmin    = head.rla_head.window.left;
177    hdr.xmax    = head.rla_head.window.right;
178    hdr.ymin    = head.rla_head.window.bottom;
179    hdr.ymax    = head.rla_head.window.top;
180    hdr.alpha   = (head.rla_head.num_matte && !do_matte ? 1 : 0);
181    hdr.ncolors = (do_matte ? 1 : head.rla_head.num_chan);
182    /*hdr.ncmap   = (map ? 3 : 0);*/
183    /*hdr.cmaplen = (map ? 8 : 0);*/
184    /*hdr.cmap    = (map ? color_map : NULL);*/
185    rle_putcom(head.rla_head.desc, &hdr);
186    /*hdr.background = 0;*/
187    if (hdr.alpha)
188       RLE_SET_BIT(hdr, RLE_ALPHA);
189    if (!do_matte) {
190       RLE_SET_BIT(hdr, RLE_RED);
191       RLE_SET_BIT(hdr, RLE_GREEN);
192       RLE_SET_BIT(hdr, RLE_BLUE);
193       }
194    rle_put_setup(&hdr);
195 }
196 /*-----------------------------------------------------------------------------
197  *                                            Decode run length encoded pixels.
198  */
199 void
decode(c_in,c_out,len)200 decode(c_in, c_out, len)
201 U_CHAR	*c_in;
202 U_CHAR	*c_out;
203 int	len;
204 {
205    int	ct;
206 
207    while(len > 0) {
208       ct = *c_in++;
209       len--;
210       if (ct < 128) {
211 /*
212  * Repeat pixel value ct+1 times.
213  */
214          while (ct-- >= 0)
215             *c_out++ = *c_in;
216          c_in++;
217          len--;
218          }
219       else {
220 /*
221  * Copy ct unencoded values.
222  */
223          for (ct = 256-ct; ct-- > 0; len--)
224             *c_out++ = *c_in++;
225          }
226       }
227 }
228 /*-----------------------------------------------------------------------------
229  *                                      Write the rle data portion of the file.
230  */
write_rle_data()231 void write_rle_data()
232 {
233    int		*offset;
234    int		x;
235    int		bottom;
236    int		left;
237    int		scan;
238 #ifdef CRAY2CC
239    long		craybuf;
240 #endif
241    U_CHAR	*red, *green, *blue, *matte;
242    U_CHAR	*buf;
243    short	len;
244    rle_pixel	*scanline[4];
245 /*
246  * Read scanline offset table.
247  */
248    if (!(offset = (int *)malloc(sizeof(int) * act_y_res))) {
249       fprintf(stderr, "Offset malloc failed!\n");
250       exit(-3);
251       }
252 #ifdef CRAY2CC
253    for (scan=0;scan<act_y_res;scan++) {
254       fread(&craybuf, 4, 1, fp); offset[scan] = craybuf >> 32;
255       }
256 #else
257    if (fread(offset, 4, act_y_res, fp) != act_y_res) {
258       fprintf(stderr, "Offset table read failed!\n");
259       exit(-4);
260       }
261 #endif
262 /*
263  * Allocate some memory.
264  */
265    if (!(buf = (U_CHAR *)malloc(width * 2))) {
266       fprintf(stderr, "Buf malloc failed!\n");
267       exit(-7);
268       }
269    if (!(red = (U_CHAR *)malloc(width * 4))) {
270       fprintf(stderr, "Red scanline malloc failed!\n");
271       exit(-8);
272       }
273    green = &red[width];
274    blue  = &green[width];
275    matte = &blue[width];
276    /*bzero((char *)blank, width*4);*/
277    if (((scanline[0]=(rle_pixel *)malloc(width))==NULL) ||
278        ((scanline[1]=(rle_pixel *)malloc(width))==NULL) ||
279        ((scanline[2]=(rle_pixel *)malloc(width))==NULL) ||
280        ((scanline[3]=(rle_pixel *)malloc(width))==NULL)) {
281       fprintf(stderr, "Unable to malloc space for pixels\n");
282       exit(-1);
283       }
284 /*
285  * Loop through the rla files image window, write blank lines outside
286  * active window.
287  */
288    bottom = head.rla_head.active_window.bottom;
289    left   = head.rla_head.active_window.left;
290    for (scan = head.rla_head.window.bottom;
291 	scan <= head.rla_head.window.top; scan++) {
292 /*
293  * Check for black regions outside active window.
294  */
295       if ((scan < head.rla_head.active_window.bottom) ||
296           (scan > head.rla_head.active_window.top))
297          rle_skiprow(&hdr, 1);
298       else {
299          if (fseek(fp, (long)offset[scan-bottom], 0)) {
300             fprintf(stderr, "rla file incomplete!\n");
301             exit(-9);
302             }
303 /*
304  * Red scanline.
305  */
306          SHORTREAD(&len, fp);
307          fread(buf, 1, (int)len, fp);
308          decode(buf, red, (int)len);
309 /*
310  * Green scanline.
311  */
312          SHORTREAD(&len, fp);
313          fread(buf, 1, (int)len, fp);
314          decode(buf, green, (int)len);
315 /*
316  * Blue scanline.
317  */
318          SHORTREAD(&len, fp);
319          fread(buf, 1, (int)len, fp);
320          decode(buf, blue, (int)len);
321 /*
322  * Matte scanline.
323  */
324          SHORTREAD(&len, fp);
325          fread(buf, 1, (int)len, fp);
326          decode(buf, matte, (int)len);
327 /*
328  * Write out RGBM for each pixel.
329  */
330          for (x=head.rla_head.window.left;
331 	      x<=head.rla_head.window.right; x++) {
332             if ((x < head.rla_head.active_window.left) ||
333                 (x > head.rla_head.active_window.right)) {
334                scanline[0][x] = 0;
335                scanline[1][x] = 0;
336                scanline[2][x] = 0;
337                scanline[3][x] = 0;
338                }
339             else
340                if (do_matte) {
341                   scanline[0][x] = (red[x-left] ||
342                                   green[x-left] ||
343                                    blue[x-left] ? 255 : 0);
344                   }
345                else {
346                   scanline[0][x] = matte[x-left];
347                   scanline[1][x] = red[x-left];
348                   scanline[2][x] = green[x-left];
349                   scanline[3][x] = blue[x-left];
350                   }
351             }
352          if (do_matte)
353             rle_putrow(scanline, width, &hdr);
354          else
355             rle_putrow(scanline + 1, width, &hdr);
356          } /* end of if scan is within active y */
357       } /* end of for every scanline */
358    VPRINTF(stderr, "Done -- write oef to RLE data.\n");
359    rle_puteof(&hdr);
360 /*
361  * Free up some stuff.
362  */
363    free(offset);
364    /*free(blank);*/
365    free(buf);
366    free(red);
367    free(scanline[0]);
368    free(scanline[1]);
369    free(scanline[2]);
370    free(scanline[3]);
371 }
372 /*-----------------------------------------------------------------------------
373  *                      Convert an Wavefront image file into an rle image file.
374  */
375 int
main(argc,argv)376 main(argc, argv)
377 int argc;
378 char **argv;
379 {
380    char		*periodP, *inname = NULL, *outname = NULL;
381    static char	filename[BUFSIZ];
382    int		oflag = 0;
383 /*
384  * Get those options.
385  */
386    if (!scanargs(argc,argv,
387        "% b%- v%- h%- m%- o%-outfile!s infile.rla%s",
388        &rlb_flag,
389        &verbose,
390        &header,
391        &do_matte,
392        &oflag, &outname,
393        &inname))
394       exit(-1);
395 /*
396  * Open the file.
397  */
398    if (inname == NULL) {
399       strcpy(filename, "stdin");
400       fp = stdin;
401       }
402    else {
403       periodP = strrchr(inname, (int)'.');
404       strcpy(filename, inname);
405       if (periodP) {
406          if (rlb_flag) {
407             if (strcmp(periodP, ".rlb")) { /* does not end in rla */
408                if (!strcmp(periodP, ".rla")) {
409                   fprintf(stderr, "This is an rla file -- don't use the -b flag.\n");
410                   exit(1);
411                   }
412                strcat(filename, ".rlb");
413                }
414             }
415          else {
416             if (strcmp(periodP, ".rla")) { /* does not end in rla */
417                if (!strcmp(periodP, ".rlb"))
418                   rlb_flag = 1;
419                else
420                   strcat(filename, ".rla");
421                }
422             }
423          }
424       else				/* no ext -- add one */
425          if (rlb_flag)
426             strcat(filename, ".rlb");
427          else
428             strcat(filename, ".rla");
429       if (!(fp = fopen(filename, "r"))) {
430          fprintf(stderr, "Cannot open %s for reading.\n", filename);
431          exit(-1);
432          }
433       }
434 /*
435  * Read the Wavefront file file header.
436  */
437    read_rla_header(&act_x_res, &act_y_res, &width, &height);
438    if (header)
439       exit(0);
440 /*
441  * Write the rle file header.
442  */
443    hdr = *rle_hdr_init( (rle_hdr *)NULL );
444    hdr.rle_file = rle_open_f( cmd_name(argv), outname, "w" );
445    rle_names( &hdr, cmd_name(argv), outname, 0 );
446    rle_addhist(argv, (rle_hdr *)NULL, &hdr);
447    write_rle_header();
448 /*
449  * Write the rle file data.
450  */
451    write_rle_data();
452    fclose(fp);
453 
454    return 0;
455 }
456