Utah Raster Toolkit  9999-git
URT Development version (post-3.1b)
xbmtorle.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  * xbmtorle.c - Convert X Bitmap files to RLE.
20  *
21  * Author: Spencer W. Thomas
22  * EECS Dept.
23  * University of Michigan
24  * Date: Mon Feb 25 1991
25  * Copyright (c) 1991, University of Michigan
26  */
27 static char rcsid[] = "$Header: /l/spencer/src/urt/cnv/RCS/xbmtorle.c,v 3.0.1.1 1992/04/30 14:01:53 spencer Exp $";
28 /*
29 xbmtorle() Tag the file.
30 */
31 
32 #include "rle.h"
33 
34 #define MAX_LINE 500
35 
36 static char *MY_NAME;
37 
38 #ifdef USE_PROTOTYPES
39 static int ReadBitmapFile( FILE *, int *, int *, int *, char ** );
40 #else
41 static int ReadBitmapFile();
42 #endif
43 
44 /*****************************************************************
45  * TAG( main )
46  *
47  * Usage:
48  * xbmtorle [-b bg_color_comps ...] [-f fg_color_comps ...]
49  * [-o outfile] [infile.xbm]
50  * Inputs:
51  * -b: Specify background color (default 0).
52  * -f: Specify foreground color (default 255).
53  * By default, the output image has a single
54  * channel. If the background color or
55  * foreground color are specified with more
56  * components, then that many channels will be
57  * output. If both are specified, the number of
58  * components should match.
59  * infile.xbm: The input X bitmap. Default stdin.
60  * Outputs:
61  * -o outfile: Specify output RLE file name. Default stdout.
62  * Assumptions:
63  * Undoubtedly.
64  * Algorithm:
65  * Reads the bitmap, then builds an RLE image with one pixel per
66  * bit in the input.
67  */
68 void
70 int argc;
71 char **argv;
72 {
73  FILE *xbm_file;
74  int bflag = 0,
75  fflag = 0,
76  oflag = 0;
77  int zero = 0,
78  two_five_five = 255,
79  *bg = &zero,
80  *fg = &two_five_five,
81  nbg = 1,
82  nfg = 1;
83  int width, height, bytes;
84  char *data;
85  char *infname = NULL,
86  *ofname = NULL;
87  register int x, c, y;
88  rle_pixel **scans;
89  rle_hdr out_hdr;
90 
91  if ( scanargs( argc, argv,
92  "% b%-bg_color_comps%*d f%-fg_color_comps%*d o%-outfile!s infile.xbm%s\n(\
93 \tConvert an X bitmap file (NOT X window dump) to URT format.\n\
94 \t-b/-f\tSpecify color to use for background/foreground bits.\n\
95 \t\tFollowed by one or more color components. Number of\n\
96 \t\tcomponents must be the same for both -b and -f.\n\
97 \t\tDefaults are 0 and 255 respectively.)",
98  &bflag, &nbg, &bg, &fflag, &nfg, &fg,
99  &oflag, &ofname, &infname ) == 0 )
100  exit( 1 );
101 
102  MY_NAME = cmd_name( argv );
103 
104  /* Check fg/bg colors if given. */
105  if ( bflag && fflag && nbg != nfg )
106  {
107  fprintf( stderr,
108  "%s: Warning: Number of background color components (%d) not the same as\n\
109  the foreground (%d), using %d\n",
110  MY_NAME, nbg, nfg, nbg < nfg ? nbg : nfg );
111  if ( nbg > nfg )
112  nbg = nfg;
113  else
114  nfg = nbg;
115  }
116 
117  /* If only specified, fix the other. */
118  if ( bflag & !fflag && nbg > 1 )
119  {
120  fg = (int *)malloc( nbg * sizeof(int) );
121  for ( nfg = 0; nfg < nbg; nfg++ )
122  fg[nfg] = 255;
123  }
124  if ( fflag & !bflag && nfg > 1 )
125  {
126  bg = (int *)malloc( nfg * sizeof(int) );
127  for ( nbg = 0; nbg < nfg; nbg++ )
128  bg[nbg] = 0;
129  }
130 
131  /* Read the Bitmap now. */
132  xbm_file = rle_open_f( MY_NAME, infname, "r" );
133  if ( ReadBitmapFile( xbm_file, &width, &height, &bytes, &data ) == 0 )
134  exit( 1 );
135 
136  /* Create the RLE file. */
137  out_hdr = *rle_hdr_init( (rle_hdr *)NULL );
138  rle_names( &out_hdr, MY_NAME, ofname, 0 );
139  out_hdr.ncolors = nbg;
140  out_hdr.bg_color = bg;
141  out_hdr.xmin = out_hdr.ymin = 0;
142  out_hdr.xmax = width - 1;
143  out_hdr.ymax = height - 1;
144  out_hdr.ncmap = out_hdr.cmaplen = 0;
145  out_hdr.comments = 0;
146  out_hdr.rle_file = rle_open_f( MY_NAME, ofname, "w" );
147  rle_addhist( argv, NULL, &out_hdr );
148 
149  rle_row_alloc( &out_hdr, &scans );
150 
151  rle_put_setup( &out_hdr );
152 
153  for ( y = 0; y < height; y++ )
154  {
155  int charcount = 0;
156  char mask = 1;
157  register char *datap;
158 
159  datap = data + (height - y - 1) * bytes;
160  for ( x = 0; x < width; x++ )
161  {
162  if ( charcount >= 8 )
163  {
164  datap++;
165  charcount = 0;
166  mask = 1;
167  }
168  for ( c = 0; c < nbg; c++ )
169  scans[c][x] = ( *datap & mask ) ? fg[c] : bg[c];
170  charcount++;
171  mask = mask << 1;
172  }
173  rle_putrow( scans, width, &out_hdr );
174  }
175  rle_puteof( &out_hdr );
176 }
177 
178 
179 static int
180 ReadBitmapFile( stream, widthP, heightP, bytesP, dataP )
181 FILE *stream;
182 int *widthP, *heightP, *bytesP;
183 char **dataP;
184 {
185  char line[MAX_LINE], name_and_type[MAX_LINE];
186  char *ptr, *t;
187  int version10, raster_length, v;
188  register int bytes, bytes_per_line, padding;
189  register int c1, c2, value1, value2;
190  static int hex_table[256];
191 
192  *widthP = *heightP = -1;
193 
194  for ( ; ; )
195  {
196  if ( fgets( line, MAX_LINE, stream ) == NULL )
197  {
198  fprintf( stderr, "%s: bitmap premature EOF\n", MY_NAME);
199  return 0;
200  }
201  if ( strlen( line ) == MAX_LINE - 1 )
202  {
203  fprintf( stderr, "%s: bitmap line too long\n", MY_NAME );
204  return 0;
205  }
206 
207  if ( sscanf( line, "#define %s %d", name_and_type, &v ) == 2 )
208  {
209  if ( ! (t = rindex( name_and_type, '_' )) )
210  t = name_and_type;
211  else
212  t++;
213  if ( ! strcmp( "width", t ) )
214  *widthP = v;
215  if ( ! strcmp( "height", t ) )
216  *heightP = v;
217  continue;
218  }
219 
220  if ( sscanf( line, "static short %s = {", name_and_type ) == 1 )
221  {
222  version10 = 1;
223  break;
224  }
225  else if ( sscanf( line, "static char %s = {", name_and_type ) == 1 )
226  {
227  version10 = 0;
228  break;
229  }
230  else
231  continue;
232  }
233 
234  if ( *widthP == -1 )
235  {
236  fprintf( stderr, "%s: bitmap width invalid\n", MY_NAME );
237  return 0;
238  }
239  if ( *heightP == -1 )
240  {
241  fprintf( stderr, "%s: bitmap height invalid\n", MY_NAME );
242  return 0;
243  }
244 
245  padding = 0;
246  if ( ((*widthP % 16) >= 1) && ((*widthP % 16) <= 8) && version10 )
247  padding = 1;
248 
249  bytes_per_line = (*widthP+7)/8 + padding;
250  *bytesP = bytes_per_line;
251 
252  raster_length = bytes_per_line * *heightP;
253  *dataP = (char *) malloc( raster_length );
254  if ( *dataP == (char *) 0 )
255  {
256  fprintf( stderr, "%s: out of memory\n", MY_NAME );
257  return 0;
258  }
259 
260  /* Initialize hex_table. */
261  for ( c1 = 0; c1 < 256; c1++ )
262  hex_table[c1] = 256;
263  hex_table['0'] = 0;
264  hex_table['1'] = 1;
265  hex_table['2'] = 2;
266  hex_table['3'] = 3;
267  hex_table['4'] = 4;
268  hex_table['5'] = 5;
269  hex_table['6'] = 6;
270  hex_table['7'] = 7;
271  hex_table['8'] = 8;
272  hex_table['9'] = 9;
273  hex_table['A'] = 10;
274  hex_table['B'] = 11;
275  hex_table['C'] = 12;
276  hex_table['D'] = 13;
277  hex_table['E'] = 14;
278  hex_table['F'] = 15;
279  hex_table['a'] = 10;
280  hex_table['b'] = 11;
281  hex_table['c'] = 12;
282  hex_table['d'] = 13;
283  hex_table['e'] = 14;
284  hex_table['f'] = 15;
285 
286  if ( version10 )
287  for ( bytes = 0, ptr = *dataP; bytes < raster_length; bytes += 2 )
288  {
289  while ( ( c1 = getc( stream ) ) != 'x' )
290  if ( c1 == EOF )
291  goto premature_eof;
292 
293  c1 = getc( stream );
294  c2 = getc( stream );
295  if ( c1 == EOF || c2 == EOF )
296  goto premature_eof;
297  value1 = ( hex_table[c1] << 4 ) + hex_table[c2];
298  if ( value1 >= 256 )
299  fprintf( stderr, "%s: bitmap syntax error\n", MY_NAME );
300  c1 = getc( stream );
301  c2 = getc( stream );
302  if ( c1 == EOF || c2 == EOF )
303  goto premature_eof;
304  value2 = ( hex_table[c1] << 4 ) + hex_table[c2];
305  if ( value2 >= 256 )
306  fprintf( stderr, "%s: bitmap syntax error\n", MY_NAME );
307  *ptr++ = value2;
308  if ( ( ! padding ) || ( ( bytes + 2 ) % bytes_per_line ) )
309  *ptr++ = value1;
310  }
311  else
312  for ( bytes = 0, ptr = *dataP; bytes < raster_length; bytes++ )
313  {
314  while ( ( c1 = getc( stream ) ) != 'x' )
315  if ( c1 == EOF )
316  goto premature_eof;
317  c1 = getc( stream );
318  c2 = getc( stream );
319  if ( c1 == EOF || c2 == EOF )
320  goto premature_eof;
321  value1 = ( hex_table[c1] << 4 ) + hex_table[c2];
322  if ( value1 >= 256 )
323  fprintf( stderr, "%s: bitmap syntax error\n", MY_NAME );
324  *ptr++ = value1;
325  }
326 
327  return 1;
328 
329  premature_eof:
330  fprintf( stderr, "%s: bitmap premature EOF\n", MY_NAME );
331  return 1;
332 }
FILE * rle_open_f(char *prog_name, char *file_name, char *mode)
Definition: rle_open_f.c:216
int xmin
Definition: rle.h:100
const char ** comments
Definition: rle.h:113
#define USE_PROTOTYPES
Definition: rle_config.h:22
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
int rle_row_alloc(rle_hdr *the_hdr, rle_pixel ***scanp)
Definition: rle_row_alc.c:56
static char rcsid[]
Definition: xbmtorle.c:27
#define rindex
Definition: rle_config.h:97
int * bg_color
Definition: rle.h:100
int ymin
Definition: rle.h:100
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
void rle_putrow(rows, int rowlen, rle_hdr *the_hdr)
Definition: rle_putrow.c:96
int xmax
Definition: rle.h:100
void rle_addhist(argv, rle_hdr *in_hdr, rle_hdr *out_hdr)
Definition: rle_addhist.c:54
static char * MY_NAME
Definition: xbmtorle.c:36
int ncmap
Definition: rle.h:100
int ymax
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
int cmaplen
Definition: rle.h:100
#define MAX_LINE
Definition: xbmtorle.c:34
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