Utah Raster Toolkit  9999-git
URT Development version (post-3.1b)
applymap.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  * applymap.c - Apply the color map in an RLE file to the pixel data.
20  *
21  * Author: Spencer W. Thomas
22  * Computer Science Dept.
23  * University of Utah
24  * Date: Tue Jul 8 1986
25  * Copyright (c) 1986, Spencer W. Thomas
26  */
27 
28 #include <stdio.h>
29 #include <rle.h>
30 #include <rle_raw.h>
31 #ifdef USE_STDLIB_H
32 #include <stdlib.h>
33 #else
34 
35 #ifdef VOID_STAR
36 extern void *malloc();
37 #else
38 extern char *malloc();
39 #endif
40 extern void free();
41 
42 #endif /* USE_STDLIB_H */
43 
44 #define map_pixel( pix, cmaplen, cmap ) ((pix) > cmaplen ? (pix) :
45  (cmap[pix]) >> 8)
46 
47 /*****************************************************************
48  * TAG( main )
49  *
50  * Usage:
51  * applymap [-l] [-o outfile] [rlefile]
52  * Inputs:
53  * -l: If specified, a linear map will be placed in the
54  * output file.
55  * rlefile: Input file to have its map applied to its pixels.
56  * Defaults to stdin.
57  * Outputs:
58  * outfile: Result of applying the map in the input file.
59  * Defaults to stdout.
60  * Assumptions:
61  * [None]
62  * Algorithm:
63  * [None]
64  */
65 void
67 int argc;
68 char **argv;
69 {
70  register int i, c, j;
71  char * infname = NULL, * outfname = NULL;
72  FILE *outfile = stdout;
73  int oflag = 0, y, nskip, nrow, one_to_many = 0, lflag = 0;
74  int rle_cnt, rle_err;
75  rle_hdr in_hdr, out_hdr;
76  rle_op ** scan, ** outscan;
77  int * nraw;
78  int cmaplen;
79  rle_map ** cmap = NULL, *linmap = NULL, *mapp;
80 
81  if ( scanargs( argc, argv, "% l%- o%-outfile!s infile%s",
82  &lflag, &oflag, &outfname, &infname ) == 0 )
83  exit( 1 );
84  /* Open input file and read RLE header */
85  in_hdr.rle_file = rle_open_f(cmd_name( argv ), infname, "r");
86 
87  for ( rle_cnt = 0;
88  (rle_err = rle_get_setup( &in_hdr )) == RLE_SUCCESS;
89  rle_cnt++ )
90  {
91  /* Copy header data from the input file */
92  out_hdr = in_hdr;
93  rle_addhist( argv, &in_hdr, &out_hdr );
94 
95  if ( rle_cnt == 0 )
96  /* Open the output file */
97  if ( rle_cnt == 0 )
98  outfile = rle_open_f( cmd_name( argv ), outfname, "w" );
99  out_hdr.rle_file = outfile;
100 
101  nrow = in_hdr.xmax - in_hdr.xmin + 1; /* how wide is it? */
102 
103  if ( in_hdr.ncmap > 0 )
104  {
105  cmaplen = 1 << in_hdr.cmaplen; /* length of the color map */
106  /* Get pointers to the individual rows of the color map */
107  cmap = (rle_map **) malloc( in_hdr.ncmap * sizeof(rle_map *) );
108  for ( c = 0; c < in_hdr.ncmap; c++ )
109  cmap[c] = &in_hdr.cmap[c * cmaplen];
110  }
111  else
112  cmaplen = 0;
113 
114  /* If the input file has only one channel, and has more than one
115  * color map channel, then do a one to many mapping.
116  */
117  if ( in_hdr.ncolors == 1 && in_hdr.ncmap > 1 )
118  {
119  one_to_many = 1;
120  out_hdr.ncolors = in_hdr.ncmap;
121  for ( i = 1; i < out_hdr.ncolors; i++ )
122  RLE_SET_BIT( out_hdr, i ); /* save all these colors */
123  }
124 
125  /* If -l, create a linear color mapfor the output file, otherwise,
126  * it gets no map.
127  */
128  if ( lflag )
129  {
130  linmap = (rle_map *)malloc( cmaplen * out_hdr.ncolors *
131  sizeof(rle_map) );
132  out_hdr.ncmap = out_hdr.ncolors;
133  out_hdr.cmap = linmap;
134  for ( c = 0, mapp = linmap; c < out_hdr.ncolors; c++ )
135  for ( i = 0; i < cmaplen; i++ )
136  *mapp++ = i << (16 - in_hdr.cmaplen); /* right justify */
137  }
138  else
139  {
140  out_hdr.ncmap = 0; /* output file won't have a map */
141  out_hdr.cmap = NULL;
142  }
143 
144  /* Allocate space for the rle opcode information */
145  scan = (rle_op **) malloc( (in_hdr.ncolors + in_hdr.alpha) *
146  sizeof( rle_op * ) );
147  for ( i = in_hdr.ncolors + in_hdr.alpha - 1;
148  i >= 0;
149  i-- )
150  scan[i] = (rle_op *)malloc( (nrow / 3 + 1) * sizeof( rle_op ) );
151 
152  outscan = (rle_op **) malloc( (out_hdr.ncolors + out_hdr.alpha) *
153  sizeof( rle_op * ) );
154 
155  if ( one_to_many )
156  {
157  for ( i = out_hdr.ncolors + out_hdr.alpha - 1;
158  i >= out_hdr.alpha;
159  i-- )
160  outscan[i] = (rle_op *)malloc( (nrow / 3 + 1) *
161  sizeof( rle_op ) );
162  if ( out_hdr.alpha )
163  outscan[0] = scan[0];
164  /* Map background color */
165  if ( in_hdr.ncmap > 0 && in_hdr.background )
166  {
167  out_hdr.bg_color = (int *)malloc( out_hdr.ncolors *
168  sizeof(int) );
169  for ( i = 0; i < out_hdr.ncolors; i++ )
170  out_hdr.bg_color[i] = map_pixel( in_hdr.bg_color[0],
171  cmaplen, cmap[i] );
172  }
173  }
174  else
175  {
176  for ( i = out_hdr.ncolors + out_hdr.alpha - 1;
177  i >= 0;
178  i-- )
179  outscan[i] = scan[i];
180  if ( in_hdr.ncmap > 0 && in_hdr.background )
181  for ( i = 0; i < out_hdr.ncolors; i++ )
182  in_hdr.bg_color[i] = map_pixel( in_hdr.bg_color[i],
183  cmaplen, cmap[i] );
184  }
185 
186  nraw = (int *) malloc( (out_hdr.ncolors + out_hdr.alpha) *
187  sizeof( int ) );
188 
189  if ( in_hdr.alpha )
190  {
191  scan++; /* [-1] points to the alpha channel */
192  outscan++;
193  nraw++;
194  }
195 
196  /* Start the output file */
197  rle_put_setup( &out_hdr );
198 
199  y = in_hdr.ymin - 1;
200  while ( (nskip = rle_getraw( &in_hdr, scan, nraw )) != 32768 )
201  {
202  nskip -= y; /* figure out difference from previous line */
203  y += nskip;
204  if ( nskip > 1 )
205  rle_skiprow( &out_hdr, nskip - 1 );
206  if ( in_hdr.ncmap > 0 )
207  if ( one_to_many )
208  {
209  for ( c = 1; c < out_hdr.ncolors; c++ )
210  nraw[c] = nraw[0]; /* all the same length */
211 
212  for ( i = 0; i < nraw[0]; i++ )
213  switch( scan[0][i].opcode )
214  {
215  case RRunDataOp:
216  for ( c = 0; c < out_hdr.ncolors;
217  c++ )
218  {
219  outscan[c][i] = scan[0][i];
220  outscan[c][i].u.run_val =
221  map_pixel( scan[0][i].u.run_val,
222  cmaplen, cmap[c] );
223  }
224  break;
225  case RByteDataOp:
226  for ( c = 0; c < out_hdr.ncolors;
227  c++ )
228  {
229  outscan[c][i] = scan[0][i];
230  outscan[c][i].u.pixels =
231  (rle_pixel *)malloc( outscan[c][i].length *
232  sizeof (rle_pixel) );
233  for ( j = 0; j < outscan[c][i].length;
234  j++ )
235  outscan[c][i].u.pixels[j] =
236  map_pixel( scan[0][i].u.pixels[j],
237  cmaplen, cmap[c] );
238  }
239  break;
240  }
241  }
242  else
243  {
244  for ( c = 0; c < in_hdr.ncolors; c++ )
245  if ( c < in_hdr.ncmap )
246  for ( i = 0; i < nraw[c]; i++ )
247  switch( scan[c][i].opcode )
248  {
249  case RRunDataOp:
250  scan[c][i].u.run_val =
251  map_pixel( scan[c][i].u.run_val,
252  cmaplen, cmap[c] );
253  break;
254  case RByteDataOp:
255  for ( j = 0; j < scan[c][i].length;
256  j++ )
257  scan[c][i].u.pixels[j] =
258  map_pixel( scan[c][i].u.pixels[j],
259  cmaplen, cmap[c]);
260  break;
261  }
262  }
263  rle_putraw( outscan, nraw, &out_hdr );
264  if ( one_to_many )
265  rle_freeraw( &out_hdr, outscan, nraw );
266  rle_freeraw( &in_hdr, scan, nraw );
267  }
268  rle_puteof( &out_hdr );
269 
270  if ( in_hdr.ncmap > 0 )
271  free( cmap );
272  if ( lflag )
273  free( linmap );
274  if ( in_hdr.alpha )
275  {
276  scan--; /* [-1] points to the alpha channel */
277  outscan--;
278  nraw--;
279  }
280  for ( i = in_hdr.ncolors + in_hdr.alpha - 1; i >= 0; i-- )
281  free( scan[i] );
282  free( scan );
283  if ( one_to_many )
284  {
285  for ( i = out_hdr.ncolors + out_hdr.alpha - 1;
286  i >= out_hdr.alpha;
287  i-- )
288  free( outscan[i] );
289  free( out_hdr.bg_color );
290  }
291  free( outscan );
292  free( nraw );
293  }
294 
295  /* Check for an error. EOF or EMPTY is ok if at least one image
296  * has been read. Otherwise, print an error message.
297  */
298  if ( rle_cnt == 0 || (rle_err != RLE_EOF && rle_err != RLE_EMPTY) )
299  rle_get_error( rle_err, cmd_name( argv ), infname );
300 
301  exit( 0 );
302 }
FILE * rle_open_f(char *prog_name, char *file_name, char *mode)
Definition: rle_open_f.c:216
#define RLE_SET_BIT(glob, bit)
Definition: rle.h:122
#define RRunDataOp
Definition: rle_code.h:41
int xmin
Definition: rle.h:100
void rle_freeraw(rle_hdr *the_hdr, scanraw, nraw)
Definition: rle_getraw.c:268
int length
Definition: rle_raw.h:51
int opcode
Definition: rle_raw.h:49
#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
rle_map * cmap
Definition: rle.h:112
void rle_putraw(rle_op **scanraw, int *nraw, rle_hdr *the_hdr)
Definition: rle_putraw.c:60
int * bg_color
Definition: rle.h:100
#define RLE_SUCCESS
Definition: rle.h:70
int ymin
Definition: rle.h:100
int rle_get_error(int code, const char *pgmname, const char *fname)
Definition: rle_error.c:76
int scanargs(int argc, char **argv, const char *format,...)
Definition: scanargs.c:94
void rle_puteof(rle_hdr *the_hdr)
Definition: rle_putrow.c:474
int xmax
Definition: rle.h:100
#define RLE_EOF
Definition: rle.h:74
void rle_addhist(argv, rle_hdr *in_hdr, rle_hdr *out_hdr)
Definition: rle_addhist.c:54
void rle_skiprow(rle_hdr *the_hdr, int nrow)
Definition: rle_putrow.c:393
int background
Definition: rle.h:100
int ncmap
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
#define map_pixel(pix, cmaplen, cmap)
Definition: applymap.c:44
int cmaplen
Definition: rle.h:100
int alpha
Definition: rle.h:100
#define USE_STDLIB_H
Definition: rle_config.h:25
unsigned short rle_map
Definition: rle.h:57
FILE * rle_file
Definition: rle.h:114
unsigned int rle_getraw(rle_hdr *the_hdr, scanraw, nraw)
Definition: rle_getraw.c:78
int ncolors
Definition: rle.h:100
#define RByteDataOp
Definition: rle_code.h:40