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
WriteVICARHeader(fd,width,height,BandsPerPixel)86 void WriteVICARHeader(fd, width, height, BandsPerPixel)
87 FILE *fd;
88 int width, height, BandsPerPixel;
89 {
90 char *buffer, *bp;
91
92 /*
93 LBLSIZE must be an integer multiple of width.
94 It also needs to be large enough for everything below to fit.
95 We use 1024 as a reasonable minimum size, and pick the first integer
96 multiple of 'width' to be the LBLSIZE.
97
98 Look - I don't really understand VICAR format. We're just hacking...
99
100 */
101 LBLSIZE = width; while(LBLSIZE < 1024) LBLSIZE += width;
102 /* Allocate a buffer. */
103 buffer = (char *)malloc( LBLSIZE );
104 bp = buffer;
105
106 #define incr(bp,fudge) \
107 bp += strlen( bp ); \
108 if ( bp - buffer + fudge > LBLSIZE ) \
109 { \
110 bp = buffer = realloc( buffer, LBLSIZE += width ); \
111 bp += strlen( bp ); \
112 }
113
114 sprintf(bp,"LBLSIZE=%-d ",LBLSIZE); /* see above */
115 incr( bp, 20 );
116 sprintf(bp," FORMAT='BYTE'");
117 incr( bp, 20 );
118 sprintf(bp," TYPE='IMAGE'");
119 incr( bp, 20 );
120 sprintf(bp," BUFSIZ=%-d",20*LBLSIZE);
121 incr( bp, 20 );
122 sprintf(bp," DIM=3");
123 incr( bp, 20 );
124 sprintf(bp," EOL=0");
125 incr( bp, 20 );
126 sprintf(bp," RECSIZE=%-d",LBLSIZE);
127 incr( bp, 20 );
128 sprintf(bp," ORG='BSQ'");
129 incr( bp, 20 );
130 sprintf(bp," NL=%-d",height);
131 incr( bp, 20 );
132 sprintf(bp," NS=%-d",width);
133 incr( bp, 20 );
134 sprintf(bp," NB=1");
135 incr( bp, 20 );
136 sprintf(bp," N1=%-d",height);
137 incr( bp, 20 );
138 sprintf(bp," N2=%-d",width);
139 incr( bp, 20 );
140 sprintf(bp," N3=1");
141 incr( bp, 20 );
142 sprintf(bp," N4=0");
143 incr( bp, 20 );
144 sprintf(bp," NBB=0");
145 incr( bp, 20 );
146 sprintf(bp," NLB=0");
147 incr( bp, 100 );
148 sprintf(bp," COMMENT='created by rletovcr'");
149 bp += strlen( bp );
150
151 #undef incr
152
153 /* Rewrite LBLSIZE in case it changed (unlikely). */
154 sprintf( buffer, "LBLSIZE=%-d", LBLSIZE );
155
156 while ( bp < buffer + LBLSIZE )
157 *bp++ = 0;
158
159 fwrite( buffer, 1, LBLSIZE, fd );
160 free( buffer );
161 }
162
WriteVICARScanLine(fd,VICARScanLine,VICARScanLineLength)163 static void WriteVICARScanLine(fd, VICARScanLine, VICARScanLineLength)
164 FILE *fd;
165 unsigned char *VICARScanLine;
166 int VICARScanLineLength;
167 {
168 (void)fwrite(VICARScanLine, 1, VICARScanLineLength, fd);
169 }
170
171 static unsigned char *
read_image(the_hdr)172 read_image( the_hdr )
173 rle_hdr *the_hdr;
174 {
175 int y,width,height;
176 unsigned char *VICARImage;
177 rle_pixel **rows;
178
179 /* Read the RLE file header. */
180 rle_get_setup_ok( the_hdr, NULL, NULL );
181 /* Don't read alpha channel. */
182 RLE_CLR_BIT( *the_hdr, RLE_ALPHA );
183
184 /* Sanity check. */
185 if ( the_hdr->ncolors > 1 || the_hdr->cmap )
186 {
187 fprintf( stderr,
188 "%s: Only black & white images can be converted to VICAR.\n",
189 the_hdr->cmd );
190 if ( the_hdr->ncolors > 1 )
191 fprintf( stderr, "\t%s has %d colors.\n",
192 the_hdr->file_name, the_hdr->ncolors );
193 else
194 fprintf( stderr, "\t%s has a color map.\n",
195 the_hdr->file_name );
196 exit( 1 );
197 }
198
199 /* Shift image over to save space. */
200 the_hdr->xmax -= the_hdr->xmin;
201 the_hdr->xmin = 0;
202 width = the_hdr->xmax + 1;
203 height = the_hdr->ymax - the_hdr->ymin + 1;
204
205 VICARImage = (unsigned char *) malloc(width * height);
206 RLE_CHECK_ALLOC( the_hdr->cmd, VICARImage, "image" );
207 rows = (rle_pixel **)malloc( the_hdr->ncolors * sizeof(rle_pixel *));
208
209 for ( y = the_hdr->ymin; y <= the_hdr->ymax; y++ )
210 {
211 rows[0] = VICARImage + width * (the_hdr->ymax - y);
212 rle_getrow( the_hdr, rows );
213 }
214 free( rows );
215
216 return VICARImage;
217 }
218
219 static void
write_image(the_hdr,outFD,VICARImage)220 write_image( the_hdr, outFD, VICARImage )
221 rle_hdr *the_hdr;
222 FILE *outFD;
223 unsigned char *VICARImage;
224 {
225 int width, height, y;
226
227 if (VERBOSE) fprintf(stderr,"%s: Writing VICARHeader\n", the_hdr->cmd);
228
229 width = the_hdr->xmax - the_hdr->xmin + 1;
230 height = the_hdr->ymax - the_hdr->ymin + 1;
231 WriteVICARHeader(outFD, width, height, the_hdr->ncolors);
232
233 if (VERBOSE) fprintf(stderr,"%s: Writing VICAR image", the_hdr->cmd);
234
235 for ( y = 0; y < height; y++ )
236 {
237 WriteVICARScanLine(outFD, VICARImage + y * width, width);
238 if (VERBOSE) fprintf(stderr,".");
239 }
240
241 if (VERBOSE) fprintf(stderr,"\n");
242
243 if (ferror(outFD))
244 fprintf(stderr,"%s: Error writing image\n", the_hdr->cmd);
245
246 if (VERBOSE)
247 fprintf(stderr,"%s: finished writing the image\n", the_hdr->cmd);
248
249 fflush(outFD);
250 }
251
main(argc,argv)252 int main(argc,argv)
253 int argc;
254 char *argv[];
255 {
256 char *infname = NULL, *outfname = NULL;
257 int oflag = 0;
258 unsigned char *VICARImage;
259 rle_hdr the_hdr;
260 FILE *outFD;
261
262 if ( scanargs( argc, argv, "% v%- o%-outfile!s infile%s\n(\
263 \tConvert URT image to VICAR format (as currently understood).)",
264 &VERBOSE, &oflag, &outfname, &infname ) == 0 )
265 exit( 1 );
266
267 the_hdr = *rle_hdr_init( (rle_hdr *)NULL );
268 rle_names( &the_hdr, cmd_name( argv ), infname );
269
270 the_hdr.rle_file = rle_open_f( the_hdr.cmd, infname, "r" );
271
272 VICARImage = read_image( &the_hdr );
273
274 outFD = rle_open_f( the_hdr.cmd, outfname, "w" );
275
276 write_image( &the_hdr, outFD, VICARImage );
277
278 exit(0);
279 }
280