Utah Raster Toolkit  9999-git
URT Development version (post-3.1b)
rletorla.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  * rletorla - A program which will convert Utah's "rle" images to
20  * Wavefronts "rlb" image format.
21  *
22  * Author: Wesley C. Barris
23  * AHPCRC
24  * Minnesota Supercomputer Center, Inc.
25  * Date: Thu June 21 1990
26  * Copyright (c) Wesley C. Barris
27  */
28 /*-----------------------------------------------------------------------------
29  * System includes.
30  */
31 #include <unistd.h>
32 #include <stdio.h>
33 #include "rlb_header.h"
34 #include "rle.h"
35 
36 #ifdef USE_STDLIB_H
37 #include <stdlib.h>
38 #else
39 
40 #ifdef USE_STRING_H
41 #include <string.h>
42 #else
43 #include <strings.h>
44 #define strrchr rindex
45 #define strchr index
46 #endif
47 
48 #ifdef VOID_STAR
49 extern void *malloc();
50 #else
51 extern char *malloc();
52 #endif
53 extern void free();
54 
55 #endif /* USE_STDLIB_H */
56 
57 #define VPRINTF if (verbose || header) fprintf
58 #define GRAYSCALE 001 /* 8 bits, no colormap */
59 #define PSEUDOCOLOR 010 /* 8 bits, colormap */
60 #define TRUECOLOR 011 /* 24 bits, colormap */
61 #define DIRECTCOLOR 100 /* 24 bits, no colormap */
62 #define TRUE 1
63 #define FALSE 0
64 
65 typedef unsigned char U_CHAR;
66 
67 /*
68  * Wavefront type declarations.
69  */
70 RLB_HEADER rlb_head;
71 /*
72  * Utah type declarations.
73  */
75 /*
76  * Other declarations.
77  */
78 FILE *fpin, *fpout;
79 char rlaname[BUFSIZ], progname[30], *str;
81 int verbose = 0, header = 0;
82 int i;
83 /*-----------------------------------------------------------------------------
84  * Read the rle header.
85  */
86 void read_rle_header(minx, maxx, miny, maxy)
87 int *minx, *maxx, *miny, *maxy;
88 {
91  *minx = rle_dflt_hdr.xmin;
92  *maxx = rle_dflt_hdr.xmax;
93  *miny = rle_dflt_hdr.ymin;
94  *maxy = rle_dflt_hdr.ymax;
95  VPRINTF(stderr, "Image size: %dx%d\n", *maxx-*minx+1, *maxy-*miny+1);
96  if (rle_dflt_hdr.ncolors == 1 && rle_dflt_hdr.ncmap == 3) {
100  VPRINTF(stderr, "Mapped color image with a map of length %d.\n", maplen);
101  }
102  else if (rle_dflt_hdr.ncolors == 3 && rle_dflt_hdr.ncmap == 0) {
104  VPRINTF(stderr, "24 bit color image, no colormap.\n");
105  }
106  else if (rle_dflt_hdr.ncolors == 3 && rle_dflt_hdr.ncmap == 3) {
107  visual = TRUECOLOR;
109  maplen = (1 << rle_dflt_hdr.cmaplen);
110  VPRINTF(stderr, "24 bit color image with color map of length %d\n" ,maplen);
111  }
112  else if (rle_dflt_hdr.ncolors == 1 && rle_dflt_hdr.ncmap == 0) {
113  visual = GRAYSCALE;
114  VPRINTF(stderr, "Grayscale image.\n");
115  }
116  else {
117  fprintf(stderr,
118  "ncolors = %d, ncmap = %d, I don't know how to handle this!\n",
120  exit(-1);
121  }
122  if (rle_dflt_hdr.alpha == 0) {
123  is_alpha = FALSE;
124  VPRINTF(stderr, "No alpha channel.\n");
125  }
126  else if (rle_dflt_hdr.alpha == 1) {
127  is_alpha = TRUE;
128  VPRINTF(stderr, "Alpha channel exists!\n");
129  }
130  else {
131  fprintf(stderr, "alpha = %d, I don't know how to handle this!\n",
133  exit(-1);
134  }
135  switch (rle_dflt_hdr.background) {
136  case 0:
137  VPRINTF(stderr, "Use all pixels, ignore background color.");
138  break;
139  case 1:
140  VPRINTF(stderr,
141  "Use only non-background pixels, ignore background color.");
142  break;
143  case 2:
144  VPRINTF(stderr,
145  "Use only non-background pixels, clear to background color (default).");
146  break;
147  default:
148  VPRINTF(stderr, "Unknown background flag!\n");
149  break;
150  }
151  for (i = 0; i < rle_dflt_hdr.ncolors; i++)
152  VPRINTF(stderr, " %d", rle_dflt_hdr.bg_color[i]);
153  if (rle_dflt_hdr.ncolors == 1 && rle_dflt_hdr.ncmap == 3) {
154  VPRINTF(stderr, " (%d %d %d)\n",
158  }
159  else if (rle_dflt_hdr.ncolors == 3 && rle_dflt_hdr.ncmap == 3) {
160  VPRINTF(stderr, " (%d %d %d)\n",
164  }
165  else
166  VPRINTF(stderr, "\n");
168  for (i = 0; rle_dflt_hdr.comments[i] != NULL; i++)
169  VPRINTF(stderr, "%s\n", rle_dflt_hdr.comments[i]);
170 }
171 /*-----------------------------------------------------------------------------
172  * Write the wavefront header.
173  */
174 void write_rlb_header(minx, maxx, miny, maxy, frame_number)
175 int minx, maxx, miny, maxy, frame_number;
176 {
177  char *ctime();
178  char *d_str;
179  long second;
180  long time();
181 
182  bzero(&rlb_head, 740);
183  rlb_head.window.left = minx;
184  rlb_head.window.right = maxx;
185  rlb_head.window.top = maxy;
186  rlb_head.window.bottom = miny;
191  rlb_head.frame = frame_number;
192  rlb_head.num_chan = 3;
193  rlb_head.num_matte = 1;
194  strcpy(rlb_head.gamma, "2.2000");
195  strcpy(rlb_head.red_pri, "0.670 0.330");
196  strcpy(rlb_head.green_pri, "0.210 0.710");
197  strcpy(rlb_head.blue_pri, "0.140 0.080");
198  strcpy(rlb_head.white_pt, "0.310 0.316");
199  d_str = strrchr(rlaname, '/');
200  if ( d_str == NULL )
201  d_str = rlaname;
202  strncpy(rlb_head.name, d_str, 29);
203  rlb_head.name[29] = '\0';
204  strcpy(rlb_head.desc, "A Wavefront file converted from an rle file.");
205  strcpy(rlb_head.program, progname);
206  gethostname(rlb_head.machine, 32);
207  strcpy(rlb_head.user, getenv("USER"));
208  second = time((long *)NULL);
209  d_str = ctime(&second);
210  strncpy(rlb_head.date, &d_str[4], 12);
211  strncpy(&rlb_head.date[12], &d_str[19], 5);
212  rlb_head.date[17] = '\0';
213  strcpy(rlb_head.aspect, "user defined");
214  sprintf(rlb_head.aspect_ratio, "%3.2f", (float)(maxx-minx+1)/(maxy-miny+1));
215  strcpy(rlb_head.chan, "rgb");
216 /*
217  * The following fields do not really need to be set because they should
218  * all be zero and already are because bzero was used on the entire header.
219  */
220 /*
221  rlb_head.aux_mask = 0;
222  rlb_head.encode_type = 0;
223  rlb_head.field = 0;
224  rlb_head.filter_type = 0;
225  rlb_head.job_num = 0;
226  rlb_head.lut_size = 0;
227  rlb_head.lut_type = 0;
228  rlb_head.magic_number = 0;
229  rlb_head.mix_type = 0;
230  rlb_head.num_aux = 0;
231  rlb_head.padding = 0;
232  rlb_head.storage_type = 0;
233  rlb_head.user_space_size = 0;
234  rlb_head.wf_space_size = 0;
235 */
236  fwrite(&rlb_head, 740, 1, fpout);
237 }
238 /*-----------------------------------------------------------------------------
239  * Encode the data before writing.
240  */
241 int encode(c_in, c_out, width)
242 U_CHAR *c_in;
243 U_CHAR *c_out;
244 int width;
245 {
246  int len;
247  int ct;
248 
249  len = 0;
250  while (width > 0) {
251  if ((width > 1) && (c_in[0] == c_in[1])) {
252 /*
253  * Cruise until we find a different pixel value.
254  */
255  for (ct = 2; ct < width; ct++) {
256  if (c_in[ct] != c_in[ct-1])
257  break;
258  if (ct >= 127)
259  break;
260  }
261 /*
262  * Write out the count.
263  */
264  *c_out++ = ct - 1;
265  len++;
266 /*
267  * Write out the value.
268  */
269  *c_out++ = *c_in;
270  len++;
271  width -= ct;
272  c_in += ct;
273  }
274  else {
275 /*
276  * Cruise until they can be encoded again.
277  */
278  for (ct = 1; ct < width; ct++) {
279  if ((width - ct > 1) && (c_in[ct] == c_in[ct+1]))
280  break;
281  if (ct >= 127)
282  break;
283  }
284 /*
285  * Write out the count.
286  */
287  *c_out++ = 256 - ct;
288  len++;
289 /*
290  * Copy string of pixels.
291  */
292  for (; ct-- > 0; len++, width--)
293  *c_out++ = *c_in++;
294  }
295  }
296  return len;
297 }
298 /*-----------------------------------------------------------------------------
299  * Write the data portion of the file.
300  */
301 void write_rlb_data()
302 {
303  rle_pixel **scanline;
304  U_CHAR *red, *green, *blue, *matte;
305  U_CHAR *buf;
306  int *offset;
307  int width, height;
308  int scan, x, y;
309  short len;
310  long offptr;
311 /*
312  * Create a scanline offset table then write it to reserve space in the file.
313  */
316  if (!(offset = (int *)malloc(sizeof(int) * height))) {
317  fprintf(stderr, "Offset malloc failed!\n");
318  exit(-3);
319  }
320  offptr = ftell(fpout);
321  if (fwrite(offset, sizeof(int), height, fpout) != height) {
322  fprintf(stderr, "Offset table write failed!\n");
323  exit(-4);
324  }
325  if (!(buf = (U_CHAR *)malloc(sizeof(U_CHAR) * width * 2))) {
326  fprintf(stderr, "Buf malloc failed!\n");
327  exit(-7);
328  }
329  if (!(red = (U_CHAR *)malloc(sizeof(U_CHAR) * width * 4))) {
330  fprintf(stderr, "Red scanline malloc failed!\n");
331  exit(-8);
332  }
333  green = &red[width];
334  blue = &green[width];
335  matte = &blue[width];
336 /*
337  * Loop through those scan lines.
338  */
339  if (!(rle_row_alloc(&rle_dflt_hdr, &scanline) == 0)) {
340  fprintf(stderr, "rle row alloc failed!\n");
341  exit(-1);
342  }
343  for (scan = 0; scan < height; scan++) {
344  y = rle_getrow(&rle_dflt_hdr, scanline);
345  switch (visual) {
346  case GRAYSCALE: /* 8 bits without colormap */
347  red = scanline[0];
348  green = scanline[0];
349  blue = scanline[0];
350  for (x = 0; x < width; x++)
351  matte[x] = (red[x] || green[x] || blue ? 255 : 0);
352  break;
353  case TRUECOLOR: /* 24 bits with colormap */
354  if (is_alpha) {
355  matte = scanline[-1];
356  for (x = 0; x < width; x++) {
357  red[x] = colormap[scanline[0][x]]>>8;
358  green[x] = colormap[scanline[1][x]+256]>>8;
359  blue[x] = colormap[scanline[2][x]+512]>>8;
360  }
361  }
362  else
363  for (x = 0; x < width; x++) {
364  if (colormap[scanline[0][x]]>>8 != scanline[0][x] ||
365  colormap[scanline[1][x]+256]>>8 != scanline[1][x] ||
366  colormap[scanline[2][x]+512]>>8 != scanline[2][x])
367  fprintf(stderr,"A truecolor image with colormap whose resulting values don't match!\n");
368  red[x] = colormap[scanline[0][x]]>>8;
369  green[x] = colormap[scanline[1][x]+256]>>8;
370  blue[x] = colormap[scanline[2][x]+512]>>8;
371  matte[x] = (red[x] || green[x] || blue ? 255 : 0);
372  }
373  break;
374  case DIRECTCOLOR: /* 24 bits without colormap */
375  if (is_alpha) {
376  matte = scanline[-1];
377  red = scanline[0];
378  green = scanline[1];
379  blue = scanline[2];
380  }
381  else {
382  red = scanline[0];
383  green = scanline[1];
384  blue = scanline[2];
385  for (x = 0; x < width; x++)
386  matte[x] = (red[x] || green[x] || blue ? 255 : 0);
387  }
388  break;
389  case PSEUDOCOLOR: /* 8 bits with colormap */
390  for (x = 0; x < width; x++) {
391  red[x] = colormap[scanline[0][x]]>>8;
392  green[x] = colormap[scanline[0][x]+256]>>8;
393  blue[x] = colormap[scanline[0][x]+512]>>8;
394  matte[x] = (red[x] || green[x] || blue ? 255 : 0);
395  }
396  break;
397  default:
398  break;
399  }
400 /*
401  * Record the location in the file.
402  */
403  offset[scan] = ftell(fpout);
404 /*
405  * Write the red scan line.
406  */
407  len = encode(red, buf, width);
408  fwrite(&len, sizeof(short), 1, fpout);
409  fwrite(buf, sizeof(U_CHAR), (int)len, fpout);
410 /*
411  * Write the green scan line.
412  */
413  len = encode(green, buf, width);
414  fwrite(&len, sizeof(short), 1, fpout);
415  fwrite(buf, sizeof(U_CHAR), (int)len, fpout);
416 /*
417  * Write the blue scan line.
418  */
419  len = encode(blue, buf, width);
420  fwrite(&len, sizeof(short), 1, fpout);
421  fwrite(buf, sizeof(U_CHAR), (int)len, fpout);
422 /*
423  * Write the matte scan line.
424  */
425  len = encode(matte, buf, width);
426  fwrite(&len, sizeof(short), 1, fpout);
427  fwrite(buf, sizeof(U_CHAR), (int)len, fpout);
428  } /* end of for scan = 0 to height */
429 /*
430  * Write that offset table again with correct values.
431  */
432  fseek(fpout, offptr, 0);
433  fwrite(offset, sizeof(int), height, fpout);
434 /*
435  * Free up some stuff.
436  */
437  free(offset);
438  free(buf);
439  free(red);
440 }
441 /*-----------------------------------------------------------------------------
442  * Convert an rle file into an rla file.
443  */
444 int
446 int argc;
447 char **argv;
448 {
449  char *lperiodP, *fname = NULL;
450  int minx, maxx, miny, maxy, frame_number = 1;
451 /*
452  * Get those options.
453  */
454  if (!scanargs(argc,argv,
455  "% v%- h%- infile%s",
456  &verbose,
457  &header,
458  &fname))
459  exit(-1);
460 /*
461  * Open the file.
462  */
463  fpin = rle_open_f( cmd_name( argv ), fname, "r" );
464  if (!header) {
465  strcpy(rlaname, fname);
466  lperiodP = strrchr(rlaname, '.');
467  if (lperiodP)
468  strcpy(lperiodP, ".rla");
469  else
470  strcat(rlaname, ".rla");
471  if (!(fpout = fopen(rlaname, "w"))) {
472  fprintf(stderr, "Cannot open %s for writing.\n", rlaname);
473  exit(-1);
474  }
475  }
476  strncpy(progname, cmd_name( argv ), 29);
477  progname[29] = 0;
478 /*
479  * Read the rle file header.
480  */
481  read_rle_header(&minx, &maxx, &miny, &maxy);
482  if (header)
483  exit(0);
484 /*
485  * Write the rlb file header.
486  */
487  write_rlb_header(minx, maxx, miny, maxy, frame_number);
488 /*
489  * Write the rest of the Wavefront (rlb) file.
490  */
491  write_rlb_data();
492  fclose(fpin);
493  fclose(fpout);
494 
495  return 0;
496 }
FILE * rle_open_f(char *prog_name, char *file_name, char *mode)
Definition: rle_open_f.c:216
int xmin
Definition: rle.h:100
char gamma[16]
Definition: rlb_header.h:33
const char ** comments
Definition: rle.h:113
WINDOW_S active_window
Definition: rlb_header.h:26
#define GRAYSCALE
Definition: rletoalias.c:46
gpr_ $bmf_group_header_array_t header
Definition: getap.c:113
RLB_HEADER rlb_head
Definition: rletorla.c:70
char * cmd_name(char **argv)
Definition: cmd_name.c:31
FILE * fpout
Definition: rletorla.c:78
void main(int argc, char **argv)
Definition: aliastorle.c:121
short frame
Definition: rlb_header.h:27
int rle_get_setup(rle_hdr *the_hdr)
Definition: rle_getrow.c:74
#define FALSE
Definition: giftorle.c:39
char red_pri[24]
Definition: rlb_header.h:34
rle_map * cmap
Definition: rle.h:112
int rle_row_alloc(rle_hdr *the_hdr, rle_pixel ***scanp)
Definition: rle_row_alc.c:56
char program[64]
Definition: rlb_header.h:41
int rle_getrow(rle_hdr *the_hdr, scanline)
Definition: rle_getrow.c:333
int * bg_color
Definition: rle.h:100
short num_matte
Definition: rlb_header.h:30
#define DIRECTCOLOR
Definition: rletoalias.c:44
int i
Definition: get4d.c:29
int maplen
Definition: rletorla.c:80
int ymin
Definition: rle.h:100
int visual
Definition: rletorla.c:80
int verbose
Definition: rletorla.c:81
char * progname
Definition: unslice.c:51
short top
Definition: rla_header.h:20
short num_chan
Definition: rlb_header.h:29
short bottom
Definition: rla_header.h:20
int scanargs(int argc, char **argv, const char *format,...)
Definition: scanargs.c:94
#define PSEUDOCOLOR
Definition: rletoalias.c:43
int xmax
Definition: rle.h:100
char green_pri[24]
Definition: rlb_header.h:35
WINDOW_S window
Definition: rlb_header.h:25
#define TRUE
Definition: giftorle.c:38
FILE * fpin
Definition: rletorla.c:78
rle_map * colormap
Definition: rletorla.c:74
char white_pt[24]
Definition: rlb_header.h:37
char aspect_ratio[8]
Definition: rlb_header.h:46
int background
Definition: rle.h:100
#define VPRINTF
Definition: aliastorle.c:42
int ncmap
Definition: rle.h:100
int ymax
Definition: rle.h:100
char date[20]
Definition: rlb_header.h:44
short left
Definition: rla_header.h:20
char name[128]
Definition: rlb_header.h:39
unsigned char rle_pixel
Definition: rle.h:56
short right
Definition: rla_header.h:20
int cmaplen
Definition: rle.h:100
int alpha
Definition: rle.h:100
#define USE_STDLIB_H
Definition: rle_config.h:25
char desc[128]
Definition: rlb_header.h:40
char chan[32]
Definition: rlb_header.h:47
unsigned char U_CHAR
Definition: rletorla.c:65
unsigned short rle_map
Definition: rle.h:57
int is_alpha
Definition: rletorla.c:80
char machine[32]
Definition: rlb_header.h:42
char rlaname[ 8192 ]
Definition: rletorla.c:79
char * str
Definition: rletorla.c:79
char aspect[24]
Definition: rlb_header.h:45
#define TRUECOLOR
Definition: rletoalias.c:45
rle_hdr rle_dflt_hdr
Definition: rle_global.c:66
FILE * rle_file
Definition: rle.h:114
char user[32]
Definition: rlb_header.h:43
int ncolors
Definition: rle.h:100
char blue_pri[24]
Definition: rlb_header.h:36