Utah Raster Toolkit  9999-git
URT Development version (post-3.1b)
rletoalias.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  * rletoalias.c - Convert Utah's rle images to Alias "pix" format
20  *
21  * Author: Raul Rivero
22  * Mathematics Dept.
23  * University of Oviedo
24  * Date: Mon Dec 30 1991
25  * Copyright (c) 1991, Raul Rivero
26  *
27  */
28 #ifndef lint
29 static char rcs_id[] = "$Header: /l/spencer/src/urt/cnv/RCS/rletoalias.c,v 3.0.1.1 1992/04/30 13:58:47 spencer Exp $";
30 #endif
31 /*
32 aliastorle() Tag the file.
33 */
34 
35 #include <stdio.h>
36 #include <math.h>
37 #include "rle.h"
38 
39 #define byte unsigned char
40 #define Fread(p, s, n, f) if ( fread(p, s, n, f) != n ) error(3)
41 #define Fwrite(p, s, n, f) if ( fwrite(p, s, n, f) != n ) error(4)
42 #define VPRINTF if (verbose) fprintf
43 #define PSEUDOCOLOR 1
44 #define DIRECTCOLOR 2
45 #define TRUECOLOR 3
46 #define GRAYSCALE 4
47 
48 /*
49  * Alias header.
50  */
51 typedef struct {
52  short xsize, ysize;
53  short xinit, yinit;
54  short depth;
55 } alias_hdr;
56 
57 /*
58  * I use a intermediate format ( a simple bitmap ) with
59  * this format ...
60  */
61 typedef struct {
62  int xsize, ysize; /* sizes */
63  int depth; /* # of colors */
64  int colors; /* # of colors */
65  byte *r, *g, *b; /* components or bitmap (planes < 8) */
66  byte *cmap; /* cmap if planes < 8 */
67 } bitmap_hdr;
68 
69 typedef byte color_map[3];
70 
71 /*
72  * the flag for verbose.
73  */
74 int verbose= 0;
75 /*
76  * RLE file header (here for command name and file name).
77  */
78 rle_hdr the_hdr;
79 
80 #ifdef USE_PROTOTYPES
81 static void read_rle( FILE *, bitmap_hdr *);
82 static void write_alias( FILE *, bitmap_hdr *);
83 static void error( int );
84 static void rlecmap_to_bitmapcmap( rle_hdr *, bitmap_hdr * );
85 static void code_alias24( byte *, byte *, byte *, int, FILE * );
86 static char *Malloc( long int );
87 #else
88 static void read_rle(), write_alias(), error(), rlecmap_to_bitmapcmap();
89 static void code_alias24();
90 static char *Malloc();
91 #endif
92 
93 /*****************************************************************
94  * TAG( main )
95  *
96  * Usage: rletoalias [-v] [-o outfile] [infile]
97  *
98  * Inputs:
99  * -v: Verbose switch.
100  * infile: Input a color RLE file. Stdin used if
101  * not specified.
102  * Outputs:
103  * outfile: Output Alias pix file. Stdout used if
104  * not specified.
105  * Assumptions:
106  * [None]
107  * Algorithm:
108  * [None]
109  */
110 
111 void
113 int argc;
114 char **argv;
115 {
116  char *inname = NULL;
117  char *outname = NULL;
118  FILE *infile;
119  FILE *outfile = stdout;
120  int oflag = 0;
121  bitmap_hdr bitmap;
122 
123  the_hdr = *rle_hdr_init( (rle_hdr *)NULL );
124  /*
125  * Get options
126  */
127  if ( !scanargs( argc, argv, "% v%- o%-outfile!s infile%s",
128  &verbose, &oflag, &outname, &inname ))
129  exit( 1 );
130 
131  /*
132  * Open rle file.
133  */
134  rle_names( &the_hdr, cmd_name( argv ), inname, 0 );
135  infile = rle_open_f(the_hdr.cmd, inname, "r");
136 
137  /*
138  * Translate Utah's rle format to our bitmap.
139  */
140  read_rle(infile, &bitmap);
141  fclose(infile); /* we finish with this file */
142 
143  outfile = rle_open_f(cmd_name(argv), outname, "w");
144  /* An output file name ? */
145  rle_names( &the_hdr, cmd_name( argv ), outname, 0 );
146  VPRINTF(stderr, "Writing to file %s\n", the_hdr.file_name);
147  outfile= rle_open_f(the_hdr.cmd, outname, "w");
148 
149  write_alias(outfile, &bitmap);
150  fclose(outfile); /* it is not necesary, but ... */
151 
152  exit(0);
153 }
154 
155 static void
156 read_rle(handle, image)
157 FILE *handle;
158 bitmap_hdr *image;
159 {
160  register int i, j;
161  rle_pixel **row;
162  byte *r, *g = 0, *b = 0;
163  int totalsize;
164  color_map *map = 0;
165  int type = 0;
166  int two_lines;
167  int offset_last;
168 
169  /*
170  * Read the file's configuration.
171  */
172  the_hdr.rle_file = handle;
173  rle_get_setup_ok( &the_hdr, NULL, NULL );
174 
175  /*
176  * Fill our bitmap.
177  */
178  image->xsize = the_hdr.xmax - the_hdr.xmin + 1;
179  image->ysize = the_hdr.ymax - the_hdr.ymin + 1;
180  image->depth = ( the_hdr.ncolors < 3 ? the_hdr.cmaplen : 24 );
181  image->colors = ( 1 << image->depth );
182  totalsize= image->xsize * image->ysize;
183  offset_last = totalsize - image->xsize;
184  two_lines = 2 * image->xsize;
185  VPRINTF(stderr, "Image size: %dx%d\n", image->xsize, image->ysize);
186  VPRINTF(stderr, "Image depth: %d\n", image->depth);
187  VPRINTF(stderr, "%s colormap\n",
188  (the_hdr.ncmap ? "With" : "Without"));
189 
190  /*
191  * Check the coherence and image type.
192  */
193  VPRINTF(stderr, "Image type ");
194  switch ( the_hdr.ncolors ) {
195  case 1: switch ( the_hdr.ncmap ) {
196  case 0: type = GRAYSCALE; /* 8 planes, no cmap */
197  VPRINTF(stderr, "GRAYSCALE\n");
198  break;
199  case 3: type = PSEUDOCOLOR; /* 8 planes, cmap */
200  VPRINTF(stderr, "PSEUDOCOLOR\n");
201  break;
202  default: VPRINTF(stderr, "unkown\n");
203  error(6);
204  break;
205  }
206  break;
207  case 3: switch ( the_hdr.ncmap ) {
208  case 0: type = DIRECTCOLOR; /* 24 planes, no cmap */
209  VPRINTF(stderr, "DIRECTCOLOR\n");
210  break;
211  case 3: type = TRUECOLOR; /* 24 planes, cmap */
212  VPRINTF(stderr, "TRUECOLOR\n");
213  break;
214  default: VPRINTF(stderr, "unkown\n");
215  error(6);
216  break;
217  }
218 
219  break;
220  default: error(6);
221  VPRINTF(stderr, "unkown\n");
222  break;
223  }
224 
225  /*
226  * Allocate some memory.
227  */
228  if (rle_row_alloc(&the_hdr, &row) < 0)
229  error(2);
230  if (image->depth > 8 || type == GRAYSCALE) {
231  /*
232  * 24 planes => we need three components
233  * GRAYSCALE use 8 planes but it's defined like 24 planes
234  */
235  r= image->r = (byte *) Malloc(totalsize);
236  g= image->g = (byte *) Malloc(totalsize);
237  b= image->b = (byte *) Malloc(totalsize);
238  if ( type == TRUECOLOR) {
239  image->colors = 256; /* well, a trap to rlecmap_to_bit... */
240  rlecmap_to_bitmapcmap(&the_hdr, image);
241  map = (color_map *) image->cmap; /* will be more easy use it */
242  }
243  }else {
244  /* 8 planes => one component and cmap */
245  r= image->r = (byte *) Malloc(totalsize);
246  /* Convert rle cmap to bitmap cmap */
247  rlecmap_to_bitmapcmap(&the_hdr, image);
248  map = (color_map *) image->cmap; /* will be more easy use it */
249  }
250 
251  /*
252  * Read the input image and convert it to a simple bitmap.
253  * RLE writes lines in reverse order, so we point to last
254  * line.
255  */
256  VPRINTF(stderr, "Uncompressing RLE file\n");
257  r += offset_last;
258  g += offset_last;
259  b += offset_last;
260  for (j= 0; j< image->ysize; j++) {
262  switch ( type ) {
263  case GRAYSCALE :
264  case DIRECTCOLOR: for (i= 0; i< image->xsize; i++) {
265  *r++ = row[0][i];
266  *g++ = row[1][i];
267  *b++ = row[2][i];
268  }
269  break;
270  case PSEUDOCOLOR: for (i= 0; i<image->xsize; i++) {
271  *r++ = row[0][i];
272  }
273  break;
274  case TRUECOLOR : for (i= 0; i< image->xsize; i++) {
275  *r++ = map[row[0][i]][0];
276  *g++ = map[row[1][i]][1];
277  *b++ = map[row[2][i]][i];
278  }
279  break;
280  default : error(6);
281  break;
282  }
283  /*
284  * Pointers to next byte of current line, so we substract
285  * two lines.
286  */
287  r -= two_lines;
288  g -= two_lines;
289  b -= two_lines;
290  }
291 
292  /*
293  * TRUECOLOR has map of colors, but we'll not use it.
294  */
295  if ( type == TRUECOLOR )
296  free(image->cmap);
297 }
298 
299 static void
300 rlecmap_to_bitmapcmap(rle, bitmap)
301 rle_hdr *rle;
302 bitmap_hdr *bitmap;
303 {
304  register int i;
305  rle_map *rch, *gch, *bch;
306  byte *ptr;
307 
308  /* Allocate memory */
309  ptr= bitmap->cmap= (byte *) Malloc(bitmap->colors * 3);
310 
311  /*
312  * We'll use 3 ptrs, first to R channel, second to G channel, ...
313  */
314  rch = rle->cmap;
315  gch = &(rle->cmap[bitmap->colors]);
316  bch = &(rle->cmap[2 * bitmap->colors]);
317  for (i= 0; i< bitmap->colors; i++) {
318  *ptr++ = (byte) (*rch++ >> 8);
319  *ptr++ = (byte) (*gch++ >> 8);
320  *ptr++ = (byte) (*bch++ >> 8);
321  }
322 }
323 
324 static void
325 write_alias(handle, image)
326 FILE *handle;
327 bitmap_hdr *image;
328 {
329  register int i;
330  alias_hdr alias;
331  byte *rbuf, *gbuf, *bbuf;
332 
333  /*
334  * Alias 8 bits files are b&w ( no cmap ), so Alias
335  * don't support really a 8 bits file.
336  */
337  if (image->depth <= 8) {
338  fprintf(stderr, "Bitmap with 8 planes\n");
339  error(99);
340  }
341 
342  VPRINTF(stderr, "Writing Alias file\n");
343  /* Fill the Alias header and write it */
344  alias.yinit = 0;
345  alias.xinit = 0;
346  alias.xsize = image->xsize;
347  alias.ysize = image->ysize;
348  alias.depth = image->depth;
349  Fwrite(&alias, sizeof(alias_hdr), 1, handle);
350 
351  /* Set the pointers to buffers */
352  rbuf = image->r;
353  gbuf = image->g;
354  bbuf = image->b;
355 
356  /* Compress each line */
357  for (i= 0; i< image->ysize; i++) {
358  /*
359  * Alias "pix" format do a compression method on
360  * each raster line.
361  */
362  code_alias24(rbuf, gbuf, bbuf, image->xsize, handle);
363  /* Move pointers to next lines */
364  rbuf += image->xsize;
365  gbuf += image->xsize;
366  bbuf += image->xsize;
367  }
368 }
369 
370 static void
371 code_alias24(rbuf, gbuf, bbuf, xmax, handle)
372 byte *rbuf, *gbuf, *bbuf;
373 int xmax;
374 FILE *handle;
375 {
376  byte r, g, b;
377  unsigned int number= 0;
378  int repeat= 1;
379  static byte buf[5120];
380  byte *bufptr, *end;
381 
382  bufptr= buf;
383  end= rbuf + xmax;
384  r= *rbuf++; g= *gbuf++; b= *bbuf++;
385 
386  while (rbuf < end)
387  /*
388  * While we have the same pattern ( and < 255 ), we continue
389  * skipping bytes ( pixels ).
390  */
391  if (r== *rbuf && g== *gbuf && b== *bbuf && repeat < 255) {
392  repeat++;
393  rbuf++; gbuf++; bbuf++;
394  }else {
395  /*
396  * A different triple or repeat == 255 was found, then we add
397  * this to the output buffer.
398  */
399  *bufptr++ = repeat;
400  *bufptr++ = b;
401  *bufptr++ = g;
402  *bufptr++ = r;
403  number += 4;
404  repeat = 1;
405  r= *rbuf++; g= *gbuf++; b= *bbuf++;
406  }
407 
408  /*
409  * We need add the last triplet.
410  */
411  *bufptr++ = repeat;
412  *bufptr++ = b;
413  *bufptr++ = g;
414  *bufptr++ = r;
415  number += 4;
416  /*
417  * And ... write it !
418  */
419  Fwrite(buf, number, 1, handle);
420 }
421 
422 static void
423 error(code)
424 int code;
425 {
426  fprintf(stderr, "%s: ", the_hdr.cmd);
427  switch (code) {
428  case 0: fprintf(stderr, "Usage: %s [-v] [-o outfile] [infile] \n",
429  the_hdr.cmd);
430  break;
431  case 1: fprintf(stderr, "Cannot open file.\n");
432  break;
433  case 2: fprintf(stderr, "Out of memory.\n");
434  break;
435  case 3: fprintf(stderr, "Error while reading input file\n");
436  break;
437  case 4: fprintf(stderr, "Error while writing output file\n");
438  break;
439  case 5: fprintf(stderr, "Input file is not an Alias pix\n");
440  break;
441  case 6: fprintf(stderr, "Incorrect # of planes or # of colors\n");
442  break;
443  case 99: fprintf(stderr, "Not ready\n");
444  break;
445  default: fprintf(stderr, "Unknow erro code (%d)\n", code);
446  break;
447  }
448  exit(1);
449 }
450 
451 /*
452  * My standard functions.
453  */
454 
455 static char *Malloc(size)
456 long int size;
457 {
458  char *ptr;
459 
460  if ((ptr = (char *) malloc(size)) == NULL)
461  error(2);
462 
463  /*
464  * Usually compilers fill buffers with zeros,
465  * but ...
466  */
467  bzero( ptr, size );
468  return ptr;
469 }
FILE * rle_open_f(char *prog_name, char *file_name, char *mode)
Definition: rle_open_f.c:216
int xmin
Definition: rle.h:100
short xsize
Definition: aliastorle.c:48
#define USE_PROTOTYPES
Definition: rle_config.h:22
short depth
Definition: aliastorle.c:50
#define GRAYSCALE
Definition: rletoalias.c:46
void rle_names(rle_hdr *the_hdr, const char *pgmname, const char *fname, int img_num)
Definition: rle_hdr.c:48
char * cmd_name(char **argv)
Definition: cmd_name.c:31
void main(int argc, char **argv)
Definition: aliastorle.c:121
rle_map * cmap
Definition: rle.h:112
int rle_row_alloc(rle_hdr *the_hdr, rle_pixel ***scanp)
Definition: rle_row_alc.c:56
unsigned char color_map[3]
Definition: rletoalias.c:69
short xinit
Definition: aliastorle.c:49
int rle_getrow(rle_hdr *the_hdr, scanline)
Definition: rle_getrow.c:333
#define DIRECTCOLOR
Definition: rletoalias.c:44
int ymin
Definition: rle.h:100
int verbose
Definition: rletorla.c:81
unsigned char * r
Definition: aliastorle.c:61
short yinit
Definition: aliastorle.c:49
int scanargs(int argc, char **argv, const char *format,...)
Definition: scanargs.c:94
#define PSEUDOCOLOR
Definition: rletoalias.c:43
const char * cmd
Definition: rle.h:133
#define Fwrite(p, s, n, f)
Definition: aliastorle.c:41
int xmax
Definition: rle.h:100
#define byte
Definition: aliastorle.c:39
static char rcs_id[]
Definition: rletoalias.c:29
unsigned char * g
Definition: aliastorle.c:61
void rle_get_setup_ok(rle_hdr *the_hdr, const char *prog_name, const char *file_name)
Definition: rle_getrow.c:254
#define VPRINTF
Definition: aliastorle.c:42
int ncmap
Definition: rle.h:100
int ymax
Definition: rle.h:100
unsigned char rle_pixel
Definition: rle.h:56
int cmaplen
Definition: rle.h:100
rle_hdr the_hdr
Definition: rletoalias.c:78
unsigned short rle_map
Definition: rle.h:57
short ysize
Definition: aliastorle.c:48
unsigned char * cmap
Definition: aliastorle.c:62
int colors
Definition: aliastorle.c:60
unsigned char * b
Definition: aliastorle.c:61
const char * file_name
Definition: rle.h:134
#define TRUECOLOR
Definition: rletoalias.c:45
rle_hdr * rle_hdr_init(rle_hdr *the_hdr)
Definition: rle_hdr.c:267
FILE * rle_file
Definition: rle.h:114
int ncolors
Definition: rle.h:100