Utah Raster Toolkit  9999-git
URT Development version (post-3.1b)
rletovcr.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  * rletovcr.c - Convert RLE to VICAR format.
20  *
21  * Author: Spencer W. Thomas
22  * Information Technology and Networking
23  * University of Michigan Medical Center
24  * Date: Tue Feb 18 1992
25  * Copyright (c) 1992, University of Michigan
26  */
27 
28 /*
29 Based on.
30  File: wff2vcr.c
31  Author: K.R. Sloan
32  Last Modified: 17 February 1992
33  Purpose: convert a .wff file to VICAR
34 
35  NOTE: this program is based on bare minimum specifications for VICAR
36  images. It works on the images that I have seen, and on the images
37  produced by wff2vcr (of course?). It is not to be taken as a
38  specification of VICAR images. If you spot an obvious error, or
39  know enough to provide guidance on further extensions, please
40  contact <sloan@cis.uab.edu>
41 
42  NOTE: the VICAR files have 8 bits per sample
43 
44  the .wff files must be I. If the BitsPerSample is less than
45  8, then samples are extended to 8 bits (correctly!). If the
46  BitsPerSample is greater than 8, the samples are truncated.
47  */
48 
49 #include <stdio.h>
50 #include <math.h>
51 #include "rle.h"
52 
53 int VERBOSE = 0;
54 
55 
56 /* VICAR stuff */
57  /* tags, and guesses as to meaning... */
58 static int LBLSIZE; /* size of header, must be int mult of NS */
59 #if 0
60 /* These aren't used by the program, but are kept for documentation. */
61 static char FORMAT[80]; /* 'BYTE' is OK */
62 static char TYPE[80]; /* 'IMAGE' is OK */
63 static int BUFSIZe; /* integer multiple of NS ? */
64 static int DIM; /* == 3? */
65 static int EOL; /* == 0? */
66 static int RECSIZE; /* == LBLSIZE? */
67 static char ORG[80]; /* `BSQ` is OK */
68 static int NL; /* height */
69 static int NS; /* width */
70 static int NB; /* samples per pixel? */
71 static int N1; /* == NL? */
72 static int N2; /* == NS? */
73 static int N3; /* == NB? */
74 static int N4; /* 0 is OK */
75 static int NBB; /* 0 is OK */
76 static int NLB; /* 0 is OK */
77 static char HOST[80]; /* machine type? */
78 static char INTFMT[80]; /* integer format? */
79 static char REALFMT[80]; /* read format? */
80 static char TASK[80]; /* processing applied? */
81 static char USER[80]; /* who was responsible? */
82 static char DAT_TIM[80]; /* when? */
83 static char COMMENT[80]; /* comment! */
84 #endif
85 
86 WriteVICARHeader(fd, width, height, BandsPerPixel)
87 FILE *fd;
88 int width, height, BandsPerPixel;
89 {
90  int pad;
91  char *buffer, *bp;
92 
93  /*
94  LBLSIZE must be an integer multiple of width.
95  It also needs to be large enough for everything below to fit.
96  We use 1024 as a reasonable minimum size, and pick the first integer
97  multiple of 'width' to be the LBLSIZE.
98 
99  Look - I don't really understand VICAR format. We're just hacking...
100 
101  */
102  LBLSIZE = width; while(LBLSIZE < 1024) LBLSIZE += width;
103  /* Allocate a buffer. */
104  buffer = (char *)malloc( LBLSIZE );
105  bp = buffer;
106 
107 #define incr(bp,fudge)
108  bp += strlen( bp );
109  if ( bp - buffer + fudge > LBLSIZE )
110  {
111  bp = buffer = realloc( buffer, LBLSIZE += width );
112  bp += strlen( bp );
113  }
114 
115  sprintf(bp,"LBLSIZE=%-d ",LBLSIZE); /* see above */
116  incr( bp, 20 );
117  sprintf(bp," FORMAT='BYTE'");
118  incr( bp, 20 );
119  sprintf(bp," TYPE='IMAGE'");
120  incr( bp, 20 );
121  sprintf(bp," BUFSIZ=%-d",20*LBLSIZE);
122  incr( bp, 20 );
123  sprintf(bp," DIM=3");
124  incr( bp, 20 );
125  sprintf(bp," EOL=0");
126  incr( bp, 20 );
127  sprintf(bp," RECSIZE=%-d",LBLSIZE);
128  incr( bp, 20 );
129  sprintf(bp," ORG='BSQ'");
130  incr( bp, 20 );
131  sprintf(bp," NL=%-d",height);
132  incr( bp, 20 );
133  sprintf(bp," NS=%-d",width);
134  incr( bp, 20 );
135  sprintf(bp," NB=1");
136  incr( bp, 20 );
137  sprintf(bp," N1=%-d",height);
138  incr( bp, 20 );
139  sprintf(bp," N2=%-d",width);
140  incr( bp, 20 );
141  sprintf(bp," N3=1");
142  incr( bp, 20 );
143  sprintf(bp," N4=0");
144  incr( bp, 20 );
145  sprintf(bp," NBB=0");
146  incr( bp, 20 );
147  sprintf(bp," NLB=0");
148  incr( bp, 100 );
149  sprintf(bp," COMMENT='created by rletovcr'");
150  bp += strlen( bp );
151 
152 #undef incr
153 
154  /* Rewrite LBLSIZE in case it changed (unlikely). */
155  sprintf( buffer, "LBLSIZE=%-d", LBLSIZE );
156 
157  while ( bp < buffer + LBLSIZE )
158  *bp++ = 0;
159 
160  fwrite( buffer, 1, LBLSIZE, fd );
161  free( buffer );
162 }
163 
164 static void WriteVICARScanLine(fd, VICARScanLine, VICARScanLineLength)
165 FILE *fd;
166 unsigned char *VICARScanLine;
167 int VICARScanLineLength;
168 {
169  (void)fwrite(VICARScanLine, 1, VICARScanLineLength, fd);
170 }
171 
172 static unsigned char *
173 read_image( the_hdr )
174 rle_hdr *the_hdr;
175 {
176  int y,width,height;
177  unsigned char *VICARImage;
178  rle_pixel **rows;
179 
180  /* Read the RLE file header. */
181  rle_get_setup_ok( the_hdr, NULL, NULL );
182  /* Don't read alpha channel. */
183  RLE_CLR_BIT( *the_hdr, RLE_ALPHA );
184 
185  /* Sanity check. */
186  if ( the_hdr->ncolors > 1 || the_hdr->cmap )
187  {
188  fprintf( stderr,
189  "%s: Only black & white images can be converted to VICAR.\n",
190  the_hdr->cmd );
191  if ( the_hdr->ncolors > 1 )
192  fprintf( stderr, "\t%s has %d colors.\n",
193  the_hdr->file_name, the_hdr->ncolors );
194  else
195  fprintf( stderr, "\t%s has a color map.\n",
196  the_hdr->file_name );
197  exit( 1 );
198  }
199 
200  /* Shift image over to save space. */
201  the_hdr->xmax -= the_hdr->xmin;
202  the_hdr->xmin = 0;
203  width = the_hdr->xmax + 1;
204  height = the_hdr->ymax - the_hdr->ymin + 1;
205 
206  VICARImage = (unsigned char *) malloc(width * height);
207  RLE_CHECK_ALLOC( the_hdr->cmd, VICARImage, "image" );
208  rows = (rle_pixel **)malloc( the_hdr->ncolors * sizeof(rle_pixel *));
209 
210  for ( y = the_hdr->ymin; y <= the_hdr->ymax; y++ )
211  {
212  rows[0] = VICARImage + width * (the_hdr->ymax - y);
213  rle_getrow( the_hdr, rows );
214  }
215  free( rows );
216 
217  return VICARImage;
218 }
219 
220 static void
221 write_image( the_hdr, outFD, VICARImage )
222 rle_hdr *the_hdr;
223 FILE *outFD;
224 unsigned char *VICARImage;
225 {
226  int width, height, y;
227 
228  if (VERBOSE) fprintf(stderr,"%s: Writing VICARHeader\n", the_hdr->cmd);
229 
230  width = the_hdr->xmax - the_hdr->xmin + 1;
231  height = the_hdr->ymax - the_hdr->ymin + 1;
232  WriteVICARHeader(outFD, width, height, the_hdr->ncolors);
233 
234  if (VERBOSE) fprintf(stderr,"%s: Writing VICAR image", the_hdr->cmd);
235 
236  for ( y = 0; y < height; y++ )
237  {
238  WriteVICARScanLine(outFD, VICARImage + y * width, width);
239  if (VERBOSE) fprintf(stderr,".");
240  }
241 
242  if (VERBOSE) fprintf(stderr,"\n");
243 
244  if (ferror(outFD))
245  fprintf(stderr,"%s: Error writing image\n", the_hdr->cmd);
246 
247  if (VERBOSE)
248  fprintf(stderr,"%s: finished writing the image\n", the_hdr->cmd);
249 
250  fflush(outFD);
251 }
252 
254 int argc;
255 char *argv[];
256 {
257  char *infname = NULL, outfname = NULL;
258  int oflag = 0;
259  unsigned char *VICARImage;
260  rle_hdr the_hdr;
261  FILE *outFD;
262 
263  if ( scanargs( argc, argv, "% v%- o%-outfile!s infile%s\n(\
264 \tConvert URT image to VICAR format (as currently understood).)",
265  &VERBOSE, &oflag, &outfname, &infname ) == 0 )
266  exit( 1 );
267 
268  the_hdr = *rle_hdr_init( (rle_hdr *)NULL );
269  rle_names( &the_hdr, cmd_name( argv ), infname );
270 
271  the_hdr.rle_file = rle_open_f( the_hdr.cmd, infname, "r" );
272 
273  VICARImage = read_image( &the_hdr );
274 
275  outFD = rle_open_f( the_hdr.cmd, outfname, "w" );
276 
277  write_image( &the_hdr, outFD, VICARImage );
278 
279  exit(0);
280 }
FILE * rle_open_f(char *prog_name, char *file_name, char *mode)
Definition: rle_open_f.c:216
#define incr(bp, fudge)
int xmin
Definition: rle.h:100
void main(int argc, char **argv)
Definition: aliastorle.c:121
rle_map * cmap
Definition: rle.h:112
int rle_getrow(rle_hdr *the_hdr, scanline)
Definition: rle_getrow.c:333
int ymin
Definition: rle.h:100
int scanargs(int argc, char **argv, const char *format,...)
Definition: scanargs.c:94
static int LBLSIZE
Definition: rletovcr.c:58
const char * cmd
Definition: rle.h:133
int xmax
Definition: rle.h:100
int VERBOSE
Definition: rletovcr.c:53
void rle_get_setup_ok(rle_hdr *the_hdr, const char *prog_name, const char *file_name)
Definition: rle_getrow.c:254
#define RLE_CLR_BIT(glob, bit)
Definition: rle.h:124
int ymax
Definition: rle.h:100
unsigned char rle_pixel
Definition: rle.h:56
#define RLE_ALPHA
Definition: rle.h:65
const char * file_name
Definition: rle.h:134
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
#define RLE_CHECK_ALLOC(pgm, ptr, name)
Definition: rle.h:86