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