Utah Raster Toolkit  9999-git
URT Development version (post-3.1b)
rle_hdr.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  * rle_hdr.c - Functions to manipulate rle_hdr structures.
20  *
21  * Author: Spencer W. Thomas
22  * EECS Dept.
23  * University of Michigan
24  * Date: Mon May 20 1991
25  * Copyright (c) 1991, University of Michigan
26  */
27 static char rcsid[] = "$Header: /tmp_mnt/n/itn/hendrix/u/spencer/RCS/rle_hdr.c,v 3.0.1.1 1992/04/30 14:08:07 spencer Exp spencer $";
28 
29 #include "rle.h"
30 
31 /*****************************************************************
32  * TAG( rle_names )
33  *
34  * Load program and file names into header.
35  * Inputs:
36  * the_hdr: Header to modify.
37  * pgmname: The program name.
38  * fname: The file name.
39  * img_num: Number of the image within the file.
40  * Outputs:
41  * the_hdr: Modified header.
42  * Algorithm:
43  * If values previously filled in (by testing is_init field),
44  * free them. Make copies of file name and program name,
45  * modifying file name for standard i/o. Set is_init field.
46  */
47 void
49 rle_hdr *the_hdr;
50 CONST_DECL char *pgmname;
51 CONST_DECL char *fname;
52 int img_num;
53 {
54 #if 0
55  /* Can't do this because people do hdr1 = hdr2, which copies
56  the pointers. */
57 
58  /* If filled in, free previous values. */
59  if ( the_hdr->is_init == RLE_INIT_MAGIC &&
60  the_hdr->cmd != NULL && the_hdr->file_name != NULL )
61  {
62  if ( pgmname != the_hdr->cmd )
63  free( the_hdr->cmd );
64  if ( fname != the_hdr->file_name )
65  free( the_hdr->file_name );
66  }
67 #endif
68 
69  /* Mark as filled in. */
70  the_hdr->is_init = RLE_INIT_MAGIC;
71 
72  /* Default file name for stdin/stdout. */
73  if ( fname == NULL || strcmp( fname, "-" ) == 0 || *fname == '\0' )
74  fname = "Standard I/O";
75  if ( pgmname == NULL )
76  pgmname = rle_dflt_hdr.cmd;
77 
78  /* Fill in with copies of the strings. */
79  if ( the_hdr->cmd != pgmname )
80  {
81  char *tmp = (char *)malloc( strlen( pgmname ) + 1 );
82  RLE_CHECK_ALLOC( pgmname, tmp, 0 );
83  strcpy( tmp, pgmname );
84  the_hdr->cmd = tmp;
85  }
86 
87  if ( the_hdr->file_name != fname )
88  {
89  char *tmp = (char *)malloc( strlen( fname ) + 1 );
90  RLE_CHECK_ALLOC( pgmname, tmp, 0 );
91  strcpy( tmp, fname );
92  the_hdr->file_name = tmp;
93  }
94 
95  the_hdr->img_num = img_num;
96 }
97 
98 
99 /* Used by rle_hdr_cp and rle_hdr_init to avoid recursion loops. */
100 static int no_recurse = 0;
101 
102 /*****************************************************************
103  * TAG( rle_hdr_cp )
104  *
105  * Make a "safe" copy of a rle_hdr structure.
106  * Inputs:
107  * from_hdr: Header to be copied.
108  * Outputs:
109  * to_hdr: Copy of from_hdr, with all memory referred to
110  * by pointers copied. Also returned as function
111  * value. If NULL, a static header is used.
112  * Assumptions:
113  * It is safe to call rle_hdr_init on to_hdr.
114  * Algorithm:
115  * Initialize to_hdr, copy from_hdr to it, then copy the memory
116  * referred to by all non-null pointers.
117  */
118 rle_hdr *
120 rle_hdr *from_hdr, *to_hdr;
121 {
122  static rle_hdr dflt_hdr;
123  CONST_DECL char *cmd, *file;
124  int num;
125 
126  /* Save command, file name, and image number if already initialized. */
127  if ( to_hdr && to_hdr->is_init == RLE_INIT_MAGIC )
128  {
129  cmd = to_hdr->cmd;
130  file = to_hdr->file_name;
131  num = to_hdr->img_num;
132  }
133  else
134  {
135  cmd = file = NULL;
136  num = 0;
137  }
138 
139  if ( !no_recurse )
140  {
141  no_recurse++;
142  rle_hdr_init( to_hdr );
143  no_recurse--;
144  }
145 
146  if ( to_hdr == NULL )
147  to_hdr = &dflt_hdr;
148 
149  *to_hdr = *from_hdr;
150 
151  if ( to_hdr->bg_color )
152  {
153  int size = to_hdr->ncolors * sizeof(int);
154  to_hdr->bg_color = (int *)malloc( size );
155  RLE_CHECK_ALLOC( to_hdr->cmd, to_hdr->bg_color, "background color" );
156  bcopy( from_hdr->bg_color, to_hdr->bg_color, size );
157  }
158 
159  if ( to_hdr->cmap )
160  {
161  int size = to_hdr->ncmap * (1 << to_hdr->cmaplen) * sizeof(rle_map);
162  to_hdr->cmap = (rle_map *)malloc( size );
163  RLE_CHECK_ALLOC( to_hdr->cmd, to_hdr->cmap, "color map" );
164  bcopy( from_hdr->cmap, to_hdr->cmap, size );
165  }
166 
167  /* Only copy array of pointers, as the original comment memory
168  * never gets overwritten.
169  */
170  if ( to_hdr->comments )
171  {
172  int size = 0;
173  CONST_DECL char **cp;
174  for ( cp=to_hdr->comments; *cp; cp++ )
175  size++; /* Count the comments. */
176  /* Check if there are really any comments. */
177  if ( size )
178  {
179  size++; /* Copy the NULL pointer, too. */
180  size *= sizeof(char *);
181  to_hdr->comments = (CONST_DECL char **)malloc( size );
182  RLE_CHECK_ALLOC( to_hdr->cmd, to_hdr->comments, "comments" );
183  bcopy( from_hdr->comments, to_hdr->comments, size );
184  }
185  else
186  to_hdr->comments = NULL; /* Blow off empty comment list. */
187  }
188 
189  /* Restore the names to their original values. */
190  to_hdr->cmd = cmd;
191  to_hdr->file_name = file;
192 
193  /* Lines above mean nothing much happens if cmd and file are != NULL. */
194  rle_names( to_hdr, to_hdr->cmd, to_hdr->file_name, num );
195 
196  return to_hdr;
197 }
198 
199 /*****************************************************************
200  * TAG( rle_hdr_clear )
201  *
202  * Clear out the allocated memory pieces of a header.
203  *
204  * This routine is intended to be used internally by the library, to
205  * clear a header before putting new data into it. It clears all the
206  * fields that would be set by reading in a new image header.
207  * Therefore, it does not clear the program and file names.
208  *
209  * Inputs:
210  * the_hdr: To be cleared.
211  * Outputs:
212  * the_hdr: After clearing.
213  * Assumptions:
214  * If is_init field is RLE_INIT_MAGIC, the header has been
215  * properly initialized. This will fail every 2^(-32) times, on
216  * average.
217  * Algorithm:
218  * Free memory and set to zero all pointers, except program and
219  * file name.
220  */
221 void
223 rle_hdr *the_hdr;
224 {
225  /* Try to free memory. Assume if is_init is properly set that this
226  * header has been previously initialized, therefore it is safe to
227  * free memory.
228  */
229  if ( the_hdr && the_hdr->is_init == RLE_INIT_MAGIC )
230  {
231  if ( the_hdr->bg_color )
232  free( the_hdr->bg_color );
233  the_hdr->bg_color = 0;
234  if ( the_hdr->cmap )
235  free( the_hdr->cmap );
236  the_hdr->cmap = 0;
237  /* Unfortunately, we don't know how to free the comment memory. */
238  if ( the_hdr->comments )
239  free( the_hdr->comments );
240  the_hdr->comments = 0;
241  }
242 }
243 
244 
245 
246 /*****************************************************************
247  * TAG( rle_hdr_init )
248  *
249  * Initialize a rle_hdr structure.
250  * Inputs:
251  * the_hdr: Header to be initialized.
252  * Outputs:
253  * the_hdr: Initialized header.
254  * Assumptions:
255  * If the_hdr->is_init is RLE_INIT_MAGIC, the header has been
256  * previously initialized.
257  * If the_hdr is a copy of another rle_hdr structure, the copy
258  * was made with rle_hdr_cp.
259  * Algorithm:
260  * If the_hdr is rle_dflt_hdr, do nothing!
261  * If the_hdr is NULL, return a copy of rle_dflt_hdr.
262  * If the_hdr->is_init is RLE_INIT_MAGIC, free all memory
263  * pointed to by non-null pointers.
264  * Copy rle_dflt_hdr into the_hdr.
265  */
266 rle_hdr *
268 rle_hdr *the_hdr;
269 {
270  rle_hdr *ret_hdr;
271 
272  rle_dflt_hdr.rle_file = stdout;
273  /* The rest of rle_dflt_hdr is set by the loader's data initialization */
274 
275  if ( the_hdr == &rle_dflt_hdr )
276  return the_hdr;
277 
278  rle_hdr_clear( the_hdr );
279 
280  /* Only call rle_hdr_cp if not called from there. */
281  if ( !no_recurse )
282  {
283  no_recurse++;
284  ret_hdr = rle_hdr_cp( &rle_dflt_hdr, the_hdr );
285  no_recurse--;
286  }
287  else
288  ret_hdr = the_hdr;
289 
290  return ret_hdr;
291 }
rle_hdr * rle_hdr_cp(rle_hdr *from_hdr, rle_hdr *to_hdr)
Definition: rle_hdr.c:119
const char ** comments
Definition: rle.h:113
void rle_names(rle_hdr *the_hdr, const char *pgmname, const char *fname, int img_num)
Definition: rle_hdr.c:48
rle_map * cmap
Definition: rle.h:112
int * bg_color
Definition: rle.h:100
long int is_init
Definition: rle.h:131
const char * cmd
Definition: rle.h:133
static int no_recurse
Definition: rle_hdr.c:100
int img_num
Definition: rle.h:135
#define RLE_INIT_MAGIC
Definition: rle.h:79
static char rcsid[]
Definition: rle_hdr.c:27
#define CONST_DECL
Definition: rle_config.h:42
int ncmap
Definition: rle.h:100
int cmaplen
Definition: rle.h:100
unsigned short rle_map
Definition: rle.h:57
void rle_hdr_clear(rle_hdr *the_hdr)
Definition: rle_hdr.c:222
const char * file_name
Definition: rle.h:134
rle_hdr * rle_hdr_init(rle_hdr *the_hdr)
Definition: rle_hdr.c:267
rle_hdr rle_dflt_hdr
Definition: rle_global.c:66
FILE * rle_file
Definition: rle.h:114
int ncolors
Definition: rle.h:100
#define RLE_CHECK_ALLOC(pgm, ptr, name)
Definition: rle.h:86