w32tex
About: TeX Live provides a comprehensive TeX system including all the major TeX-related programs, macro packages, and fonts that are free software. Windows sources.
  Fossies Dox: w32tex-src.tar.xz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

atktopbm.c
Go to the documentation of this file.
1 /* atktopbm.c - convert Andrew Toolkit raster object to portable bitmap
2 **
3 ** Copyright (C) 1991 by Bill Janssen
4 **
5 ** Permission to use, copy, modify, and distribute this software and its
6 ** documentation for any purpose and without fee is hereby granted, provided
7 ** that the above copyright notice appear in all copies and that both that
8 ** copyright notice and this permission notice appear in supporting
9 ** documentation. This software is provided "as is" without express or
10 ** implied warranty.
11 */
12 
13 #include <stdio.h>
14 #include <sys/types.h>
15 #include "pbm.h"
16 
17 void ReadATKRaster ARGS((FILE *file, int *rwidth, int *rheight, unsigned char **destaddr));
18 static long ReadRow ARGS((register FILE *file, register unsigned char *row, register long length));
19 
20 int
22  int argc;
23  char *argv[];
24  {
25  FILE *ifp;
26  register bit *bitrow, *bP;
27  int rows, cols, row, col, charcount;
28  unsigned char *data, mask;
29 
30 
31  pbm_init ( &argc, argv );
32 
33  if ( argc > 2 )
34  pm_usage( "[raster obj]" );
35 
36  if ( argc == 2 )
37  ifp = pm_openr( argv[1] );
38  else
39  ifp = stdin;
40 
41  ReadATKRaster( ifp, &cols, &rows, &data );
42 
43  pm_close( ifp );
44 
46  bitrow = pbm_allocrow( cols );
47 
48  for ( row = 0; row < rows; ++row )
49  {
50  charcount = 0;
51  mask = 0x80;
52  for ( col = 0, bP = bitrow; col < cols; ++col, ++bP )
53  {
54  if ( charcount >= 8 )
55  {
56  ++data;
57  charcount = 0;
58  mask = 0x80;
59  }
60  *bP = ( *data & mask ) ? PBM_BLACK : PBM_WHITE;
61  ++charcount;
62  mask >>= 1;
63  }
64  ++data;
65  pbm_writepbmrow( stdout, bitrow, cols, 0 );
66  }
67 
68  pm_close( stdout );
69  exit( 0 );
70  }
71 
72 /* readatkraster
73 **
74 ** Routine for reading rasters in .raster form. (BE2 rasters version 2.)
75 */
76 
77 /* codes for data stream */
78 #define WHITEZERO 'f'
79 #define WHITETWENTY 'z'
80 #define BLACKZERO 'F'
81 #define BLACKTWENTY 'Z'
82 #define OTHERZERO 0x1F
83 
84 #define WHITEBYTE 0x00
85 #define BLACKBYTE 0xFF
86 
87 /* error codes (copied from $ANDREW/atk/basics/common/dataobj.ch) */
88 /* return values from Read */
89 #define dataobject_NOREADERROR 0
90 #define dataobject_PREMATUREEOF 1
91 #define dataobject_NOTBE2DATASTREAM 2 /* backward compatibility */
92 #define dataobject_NOTATKDATASTREAM 2 /* preferred version */
93 #define dataobject_MISSINGENDDATAMARKER 3
94 #define dataobject_OBJECTCREATIONFAILED 4
95 #define dataobject_BADFORMAT 5
96 
97 /* ReadRow(file, row, length)
98 ** Reads from 'file' the encoding of bytes to fill in 'row'. Row will be
99 ** truncated or padded (with WHITE) to exactly 'length' bytes.
100 **
101 ** Returns the code that terminated the row. This may be
102 ** '|' correct end of line
103 ** '\0' if the length was satisfied (before a terminator)
104 ** EOF if the file ended
105 ** '\' '{' other recognized ends.
106 ** The '|' is the expected end and pads the row with WHITE.
107 ** The '\' and '{' are error conditions and may indicate the
108 ** beginning of some other portion of the data stream.
109 ** If the terminator is '\' or '{', it is left at the front of the input.
110 ** '|' is gobbled up.
111 */
112 
113 /* macros to generate case entries for switch statement */
114 #define case1(v) case v
115 #define case4(v) case v: case (v)+1: case (v)+2: case(v)+3
116 #define case6(v) case4(v): case ((v)+4): case ((v)+5)
117 #define case8(v) case4(v): case4((v)+4)
118 
119 static long
121  register FILE *file; /* where to get them from */
122  register unsigned char *row; /* where to put bytes */
123  register long length; /* how many bytes in row must be filled */
124 {
125  /* Each input character is processed by the central loop. There are
126  ** some input codes which require two or three characters for
127  ** completion; these are handled by advancing the state machine.
128  ** Errors are not processed; instead the state machine is reset
129  ** to the Ready state whenever a character unacceptable to the
130  ** current state is read.
131  */
132  enum stateCode {
133  Ready, /* any input code is allowed */
134  HexDigitPending, /* have seen the first of a hex digit pair */
135  RepeatPending, /* repeat code has been seen:
136  must be followed by two hex digits */
137  RepeatAndDigit}; /* have seen repeat code and its first
138  following digit */
139  enum stateCode InputState; /* current state */
140  register int c; /* the current input character */
141  register long repeatcount = 0; /* current repeat value */
142  register long hexval; /* current hex value */
143  long pendinghex = 0; /* the first of a pair of hex characters */
144 
145  /* We cannot exit when length becomes zero because we need to check
146  ** to see if a row ending character follows. Thus length is checked
147  ** only when we get a data generating byte. If length then is
148  ** zero, we ungetc the byte.
149  */
150 
151  InputState = Ready;
152  while ((c=getc(file)) != EOF) switch (c) {
153 
154  case8(0x0):
155  case8(0x8):
156  case8(0x10):
157  case8(0x18):
158  case1(' '):
159  /* control characters and space are legal and ignored */
160  break;
161  case1(0x40): /* '@' */
162  case1(0x5B): /* '[' */
163  case4(0x5D): /* ']' '^' '_' '`' */
164  case4(0x7D): /* '}' '~' DEL 0x80 */
165  default: /* all above 0x80 */
166  /* error code: Ignored at present. Reset InputState. */
167  InputState = Ready;
168  break;
169 
170  case1(0x7B): /* '{' */
171  case1(0x5C): /* '\\' */
172  /* illegal end of line: exit anyway */
173  ungetc(c, file); /* retain terminator in stream */
174  /* DROP THROUGH */
175  case1(0x7C): /* '|' */
176  /* legal end of row: may have to pad */
177  while (length-- > 0)
178  *row++ = WHITEBYTE;
179  return c;
180 
181  case1(0x21):
182  case6(0x22):
183  case8(0x28):
184  /* punctuation characters: repeat byte given by two
185  ** succeeding hex chars
186  */
187  if (length <= 0) {
188  ungetc(c, file);
189  return('\0');
190  }
191  repeatcount = c - OTHERZERO;
192  InputState = RepeatPending;
193  break;
194 
195  case8(0x30):
196  case8(0x38):
197  /* digit (or following punctuation) - hex digit */
198  hexval = c - 0x30;
199  goto hexdigit;
200  case6(0x41):
201  /* A ... F - hex digit */
202  hexval = c - (0x41 - 0xA);
203  goto hexdigit;
204  case6(0x61):
205  /* a ... f - hex digit */
206  hexval = c - (0x61 - 0xA);
207  goto hexdigit;
208 
209  case8(0x67):
210  case8(0x6F):
211  case4(0x77):
212  /* g ... z - multiple WHITE bytes */
213  if (length <= 0) {
214  ungetc(c, file);
215  return('\0');
216  }
217  repeatcount = c - WHITEZERO;
218  hexval = WHITEBYTE;
219  goto store;
220  case8(0x47):
221  case8(0x4F):
222  case4(0x57):
223  /* G ... Z - multiple BLACK bytes */
224  if (length <= 0) {
225  ungetc(c, file);
226  return('\0');
227  }
228  repeatcount = c - BLACKZERO;
229  hexval = BLACKBYTE;
230  goto store;
231 
232 hexdigit:
233  /* process a hex digit. Use InputState to determine
234  what to do with it. */
235  if (length <= 0) {
236  ungetc(c, file);
237  return('\0');
238  }
239  switch(InputState) {
240  case Ready:
241  InputState = HexDigitPending;
242  pendinghex = hexval << 4;
243  break;
244  case HexDigitPending:
245  hexval |= pendinghex;
246  repeatcount = 1;
247  goto store;
248  case RepeatPending:
249  InputState = RepeatAndDigit;
250  pendinghex = hexval << 4;
251  break;
252  case RepeatAndDigit:
253  hexval |= pendinghex;
254  goto store;
255  }
256  break;
257 
258 store:
259  /* generate byte(s) into the output row
260  Use repeatcount, depending on state. */
261  if (length < repeatcount)
262  /* reduce repeat count if it would exceed
263  available space */
265  length -= repeatcount; /* do this before repeatcount-- */
266  while (repeatcount-- > 0)
267  *row++ = hexval;
268  InputState = Ready;
269  break;
270 
271  } /* end of while( - )switch( - ) */
272  return EOF;
273 }
274 #undef case1
275 #undef case4
276 #undef case6
277 #undef case8
278 
279 void
280 ReadATKRaster(file, rwidth, rheight, destaddr)
281  FILE *file;
282  unsigned char **destaddr;
283  int *rwidth, *rheight;
284 {
285  register long row, rowlen; /* count rows; byte length of row */
286  int version;
287  int options;
288  long xscale, yscale;
289  long xoffset, yoffset, subwidth, subheight;
290  char keyword[6];
291  int discardid;
292  int objectid; /* id read for the incoming pixel image */
293  long tc; /* temp */
294  int width, height; /* dimensions of image */
295 
296  if (fscanf(file, "\\begindata{raster,%d", &discardid) != 1
297  || getc(file) != '}' || getc(file) != '\n')
298  pm_error ("input file not Andrew raster object");
299 
300  fscanf(file, " %d ", &version);
301  if (version < 2)
302  pm_error ("version too old to parse");
303 
304  /* ignore all these features: */
305  fscanf(file, " %u %ld %ld %ld %ld %ld %ld",
306  &options, &xscale, &yscale, &xoffset,
307  &yoffset, &subwidth, &subheight);
308 
309  /* scan to end of line in case this is actually something beyond V2 */
310  while (((tc=getc(file)) != '\n') && (tc != '\\') && (tc != EOF)) {}
311 
312  /* read the keyword */
313  fscanf(file, " %5s", keyword);
314  if (strcmp(keyword, "bits") != 0)
315  pm_error ("keyword is not bits!");
316 
317  fscanf(file, " %d %d %d ", &objectid, &width, &height);
318 
319  if (width < 1 || height < 1 || width > 1000000 || height > 1000000)
320  pm_error ("bad width or height");
321 
322  *rwidth = width;
323  *rheight = height;
324  rowlen = (width + 7) / 8;
325  *destaddr = (unsigned char *) malloc (sizeof(unsigned char) * height *
326 rowlen);
327  for (row = 0; row < height; row++)
328  {
329  long c;
330 
331  c = ReadRow(file, *destaddr + (row * rowlen), rowlen);
332  if (c != '|')
333  {
334  if (c == EOF)
335  pm_error ("premature EOF");
336  else
337  pm_error ("bad format");
338  break;
339  }
340  }
341  while (! feof(file) && getc(file) != '\\') {}; /* scan for \enddata */
342  if (fscanf(file, "enddata{raster,%d", &discardid) != 1
343  || getc(file) != '}' || getc(file) != '\n')
344  pm_error ("missing end-of-object marker");
345 }
int charcount
Definition: afm2pfm.c:108
#define width(a)
Definition: aptex-macros.h:198
#define height(a)
Definition: aptex-macros.h:200
#define case6(v)
Definition: atktopbm.c:116
#define BLACKZERO
Definition: atktopbm.c:80
#define WHITEZERO
Definition: atktopbm.c:78
void ReadATKRaster()
#define BLACKBYTE
Definition: atktopbm.c:85
#define OTHERZERO
Definition: atktopbm.c:82
#define case8(v)
Definition: atktopbm.c:117
static long ReadRow()
#define WHITEBYTE
Definition: atktopbm.c:84
#define case1(v)
Definition: atktopbm.c:114
int main(int argc, argv)
Definition: atktopbm.c:21
#define case4(v)
Definition: atktopbm.c:115
static char * options
Definition: bmeps.c:236
int strcmp()
Definition: coll.cpp:143
struct rect data
Definition: dvipdfm.c:64
#define c(n)
Definition: gpos-common.c:150
int col
Definition: gsftopk.c:443
unsigned char * bP
Definition: hbf2gf.c:371
void exit()
#define EOF
Definition: afmparse.c:59
static int hexval(int c)
Definition: writet1.c:387
#define getc
Definition: line.c:39
#define length(c)
Definition: ctangleboot.c:65
#define malloc
Definition: alloca.c:91
#define hexdigit(c)
#define version
Definition: nup.c:10
void pm_usage(char *usage)
Definition: libpbm1.c:343
void pbm_init(int *argcP, argv)
Definition: libpbm1.c:332
FILE * pm_openr(char *name)
Definition: libpbm1.c:600
void pbm_writepbminit(FILE *file, int cols, int rows, int forceplain)
Definition: libpbm3.c:22
void pbm_writepbmrow(FILE *file, bit *bitrow, int cols, int forceplain)
Definition: libpbm3.c:95
#define pbm_allocrow(cols)
Definition: pbm.h:36
unsigned char bit
Definition: pbm.h:9
#define PBM_BLACK
Definition: pbm.h:11
#define PBM_WHITE
Definition: pbm.h:10
static int rows
Definition: pbmclean.c:15
static int cols
Definition: pbmmask.c:21
#define ARGS(alist)
Definition: pbmplus.h:235
integer xoffset[256]
Definition: pbmtopk.c:48
integer yoffset[256]
Definition: pbmtopk.c:49
static word rowlen
Definition: picttoppm.c:116
static integer repeatcount
Definition: pktopbm.c:28
#define pm_error
Definition: png22pnm.c:118
#define pm_close(file)
Definition: png22pnm.c:120
static double yscale
Definition: ppmtopjxl.c:47
static double xscale
Definition: ppmtopjxl.c:46
static int row
Definition: ps2pk.c:587
#define mask(n)
Definition: lbitlib.c:93
#define store(x, y, t)
Definition: interp.c:112
Definition: filedef.h:30
def_key keyword[6]
Definition: t1part.c:256
#define FILE
Definition: t1stdio.h:34
#define ungetc(c, f)
Definition: t1stdio.h:106
#define feof(f)
Definition: t1stdio.h:109
char * file
Definition: t4ht.c:931
FILE * ifp
Definition: t1asm.c:88
#define argv
Definition: xmain.c:270
#define argc
Definition: xmain.c:269