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)  

pktopbm.c
Go to the documentation of this file.
1 /*
2  pktopbm, adapted from "pktopx in C by Tomas Rokicki" by AJCD 1/8/90
3 
4  compile with: cc -lpbm -o pktopbm pktopbm.c
5  */
6 
7 #include <stdio.h>
8 #include <string.h>
9 #include "pbm.h"
10 
11 #define NAMELENGTH 80
12 #define MAXROWWIDTH 3200
13 #define MAXPKCHAR 256
14 
15 typedef int integer ;
16 typedef unsigned char quarterword ;
17 typedef char boolean ;
19 
20 static FILE *pkfile ;
21 static char pkname[NAMELENGTH+1] ;
23 static char *filename[MAXPKCHAR] ;
24 static bit **bitmap = NULL ;
25 static integer dynf ;
29 static integer flagbyte ;
30 
31 /* add a suffix to a filename in an allocated space */
32 static void
34  char *name, *suffix ;
35 {
36  char *slash = rindex(name, '/');
37  char *dot = rindex(name, '.');
38 
39  if ((dot && slash ? dot < slash : !dot) && strcmp(name, "-"))
40  strcat(name, suffix);
41 }
42 
43 /* get a byte from the PK file */
45 {
46  pktopbm_pkloc++ ;
47  return(getc(pkfile)) ;
48 }
49 
50 /* get a 16-bit half word from the PK file */
51 static integer get16()
52 {
54  return((a<<8) + pktopbm_pkbyte()) ;
55 }
56 
57 /* get a 32-bit word from the PK file */
58 static integer get32()
59 {
60  integer a = get16() ;
61  if (a > 32767) a -= 65536 ;
62  return((a<<16) + get16()) ;
63 }
64 
65 /* get a nibble from current input byte, or new byte if no current byte */
66 static integer getnyb()
67 {
68  eightbits temp ;
69  if (bitweight == 0) {
71  bitweight = 16 ;
72  }
74  inputbyte -= temp * bitweight ;
75  bitweight >>= 4 ;
76  return(temp) ;
77 }
78 
79 /* get a bit from the current input byte, or a new byte if no current byte */
80 static boolean getbit()
81 {
82  boolean temp ;
83  bitweight >>= 1 ;
84  if (bitweight == 0) {
86  bitweight = 128 ;
87  }
88  temp = (inputbyte >= bitweight) ;
89  if (temp) inputbyte -= bitweight ;
90  return(temp) ;
91 }
92 
93 /* unpack a dynamically packed number. dynf is dynamic packing threshold */
95 {
96  integer i, j ;
97  i = getnyb() ;
98  if (i == 0) { /* large run count, >= 3 nibbles */
99  do {
100  j = getnyb() ; /* count extra nibbles */
101  i++ ;
102  } while (j == 0) ;
103  while (i > 0) {
104  j = (j<<4) + getnyb() ; /* add extra nibbles */
105  i-- ;
106  }
107  return (j - 15 +((13 - dynf)<<4) + dynf) ;
108  } else if (i <= dynf) return (i) ; /* number > 0 and <= dynf */
109  else if (i < 14) return (((i - dynf - 1)<<4) + getnyb() + dynf + 1) ;
110  else {
111  if (i == 14) repeatcount = pkpackednum() ; /* get repeat count */
112  else repeatcount = 1 ; /* value 15 indicates repeat count 1 */
113  return(pkpackednum()) ;
114  }
115 }
116 
117 /* skip specials in PK files, inserted by Metafont or some other program */
118 static void
120 {
121  integer i, j;
122  do {
124  if (flagbyte >= 240)
125  switch(flagbyte) {
126  case 240: /* specials of size 1-4 bytes */
127  case 241:
128  case 242:
129  case 243:
130  i = 0 ;
131  for (j = 240 ; j <= flagbyte ; j ++) i = (i<<8) + pktopbm_pkbyte() ;
132  for (j = 1 ; j <= i ; j ++) pktopbm_pkbyte() ; /* ignore special */
133  break ;
134  case 244: /* no-op, parameters to specials */
135  get32() ;
136  case 245: /* start of postamble */
137  case 246: /* no-op */
138  break ;
139  case 247: /* pre-amble in wrong place */
140  case 248:
141  case 249:
142  case 250:
143  case 251:
144  case 252:
145  case 253:
146  case 254:
147  case 255:
148  pm_error("unexpected flag byte %d", flagbyte) ;
149  }
150  } while (!(flagbyte < 240 || flagbyte == 245)) ;
151 }
152 
153 /* ignore character packet */
154 static void
155 ignorechar(car, endofpacket)
156  integer car, endofpacket;
157 {
158  while (pktopbm_pkloc != endofpacket) pktopbm_pkbyte() ;
159  if (car < 0 || car >= MAXPKCHAR)
160  pm_message("Character %d out of range", car) ;
161  skipspecials() ;
162 }
163 
164 int
166  int argc ;
167  char *argv[] ;
168 {
169  integer endofpacket ;
170  boolean turnon ;
171  integer i, j;
172  integer car ;
173  integer bmx=0, bmy=0;
174  bit row[MAXROWWIDTH+1] ;
175  char *usage = "pkfile[.pk] [[-x width] [-y height] [-c num] pbmfile]...";
176 
177  pbm_init(&argc, argv);
178  for (i = 0 ; i < MAXPKCHAR ; i ++) filename[i] = NULL ;
179 
180  pm_message("This is PKtoPBM, version 2.4") ;
181 
182  if (--argc < 1) pm_usage(usage) ;
183 
184  strcpy(pkname, *++argv) ;
185  pktopbm_add_suffix(pkname, ".pk") ;
186 
187  car = 0 ;
188  while (++argv, --argc) {
189  if (argv[0][0] == '-' && argv[0][1])
190  switch (argv[0][1]) {
191  case 'X':
192  case 'x':
193  if (argv[0][2]) bmx = atoi(*argv+2) ;
194  else if (++argv, --argc) bmx = atoi(*argv) ;
195  else pm_usage(usage) ;
196  continue ;
197  case 'Y':
198  case 'y':
199  if (argv[0][2]) bmy = atoi(*argv+2) ;
200  else if (++argv, --argc) bmy = atoi(*argv) ;
201  else pm_usage(usage) ;
202  continue ;
203  case 'C':
204  case 'c':
205  if (argv[0][2]) car = atoi(*argv+2) ;
206  else if (++argv, --argc) car = atoi(*argv) ;
207  else pm_usage(usage) ;
208  break ;
209  default:
210  pm_usage(usage) ;
211  } else if (car < 0 || car >= MAXPKCHAR) {
212  pm_error("character must be in range 0 to %d (-c)", MAXPKCHAR-1) ;
213  } else filename[car++] = *argv ;
214  }
215 
217  if (pktopbm_pkbyte() != 247)
218  pm_error("bad PK file (pre command missing)") ;
219  if (pktopbm_pkbyte() != 89)
220  pm_error("wrong version of packed file") ;
221  j = pktopbm_pkbyte() ; /* get header comment size */
222  for (i = 1 ; i <= j ; i ++) pktopbm_pkbyte() ; /* ignore header comment */
223  get32() ; /* ignore designsize */
224  get32() ; /* ignore checksum */
225  if (get32() != get32()) /* h & v pixels per point */
226  pm_message("Warning: aspect ratio not 1:1") ;
227  skipspecials() ;
228  while (flagbyte != 245) { /* not at postamble */
229  integer cheight, cwidth ;
230  integer xoffs=0, yoffs=0;
231  FILE *ofp;
232 
233  dynf = (flagbyte>>4) ; /* get dynamic packing value */
234  flagbyte &= 15 ;
235  turnon = (flagbyte >= 8) ; /* black or white initially? */
236  if (turnon) flagbyte &= 7 ; /* long or short form */
237  if (flagbyte == 7) { /* long form preamble */
238  integer packetlength = get32() ; /* character packet length */
239  car = get32() ; /* character number */
240  endofpacket = packetlength + pktopbm_pkloc ; /* calculate end of packet */
241  if (car >= MAXPKCHAR || car < 0) {
242  ignorechar(car, endofpacket);
243  continue;
244  }
245  get32() ; /* ignore tfmwidth */
246  get32() ; /* ignore horiz escapement */
247  get32() ; /* ignore vert escapement */
248  cwidth = get32() ; /* bounding box width */
249  cheight = get32() ; /* bounding box height */
250  if (cwidth < 0 || cheight < 0 || cwidth > 65535 || cheight > 65535) {
251  ignorechar(car, endofpacket);
252  continue;
253  }
254  if (bmx) xoffs= get32() ; /* horiz offset */
255  if (bmy) yoffs= get32() ; /* vert offset */
256  } else if (flagbyte > 3) { /* extended short form */
257  integer packetlength = ((flagbyte - 4)<<16) + get16() ;
258  /* packet length */
259  car = pktopbm_pkbyte() ; /* char number */
260  endofpacket = packetlength + pktopbm_pkloc ; /* calculate end of packet */
261  if (car >= MAXPKCHAR) {
262  ignorechar(car, endofpacket);
263  continue;
264  }
265  pktopbm_pkbyte() ; /* ignore tfmwidth (3 bytes) */
266  get16() ; /* ignore tfmwidth (3 bytes) */
267  get16() ; /* ignore horiz escapement */
268  cwidth = get16() ; /* bounding box width */
269  cheight = get16() ; /* bounding box height */
270  if (bmx) /* horiz offset */
271  if ((xoffs=get16()) >= 32768)
272  xoffs-= 65536;
273  if (bmy) /* vert offset */
274  if ((yoffs=get16()) >= 32768)
275  yoffs-= 65536;
276  } else { /* short form preamble */
277  integer packetlength = (flagbyte<<8) + pktopbm_pkbyte() ;
278  /* packet length */
279  car = pktopbm_pkbyte() ; /* char number */
280  endofpacket = packetlength + pktopbm_pkloc ; /* calculate end of packet */
281  if (car >= MAXPKCHAR) {
282  ignorechar(car, endofpacket);
283  continue;
284  }
285  pktopbm_pkbyte() ; /* ignore tfmwidth (3 bytes) */
286  get16() ; /* ignore tfmwidth (3 bytes) */
287  pktopbm_pkbyte() ; /* ignore horiz escapement */
288  cwidth = pktopbm_pkbyte() ; /* bounding box width */
289  cheight = pktopbm_pkbyte() ; /* bounding box height */
290  if (bmx) /* horiz offset */
291  if ((xoffs=pktopbm_pkbyte()) >= 128)
292  xoffs-= 256;;
293  if (bmy) /* vert offset */
294  if ((yoffs=pktopbm_pkbyte()) >= 128)
295  yoffs-= 256;;
296  }
297  if (filename[car]) {
298  if (!bmx) bmx= cwidth;
299  if (!bmy) bmy= cheight;
300  bitmap = pbm_allocarray(bmx, bmy) ;
301  if (bitmap == NULL)
302  pm_error("out of memory allocating bitmap") ;
303  } else {
304  ignorechar(car, endofpacket);
305  continue;
306  }
307  bitweight = 0 ;
308  if (dynf == 14) { /* bitmapped character */
309  for (i = 0 ; i < bmy ; i ++) /* make it blank */
310  for (j = 0 ; j < bmx ; j ++)
311  bitmap[i][j]= PBM_WHITE;
312  for (i = 0 ; i < cheight ; i ++) {
313  int yi= i+(bmy-yoffs-1);
314  for (j = 0 ; j < cwidth ; j ++) {
315  int xj= j-xoffs;
316  if (getbit() && 0<=xj && xj<bmx && 0<=yi && yi<bmy)
317  bitmap[yi][xj] = PBM_BLACK ;
318  }
319  }
320  } else { /* dynamically packed char */
321  integer rowsleft = cheight ;
322  integer hbit = cwidth ;
323  integer rp = 0;
324  repeatcount = 0 ;
325  while (rowsleft > 0) {
326  integer count = pkpackednum() ; /* get current colour count */
327  while (count > 0) {
328  if (count < hbit) { /* doesn't extend past row */
329  hbit -= count ;
330  while (count--)
331  row[rp++] = turnon ? PBM_BLACK : PBM_WHITE;
332  } else { /* reaches end of row */
333  count -= hbit ;
334  while (hbit--)
335  row[rp++] = turnon ? PBM_BLACK : PBM_WHITE;
336  for (i = 0; i <= repeatcount; i++) { /* fill row */
337  int yi= i+cheight-rowsleft+(bmy-yoffs-1);
338  if (0<=yi && yi < bmy)
339  for (j = 0; j < cwidth; j++) {
340  int xj= j-xoffs;
341  if (0<=xj && xj<bmx)
342  bitmap[yi][xj] = row[j] ;
343  }
344  }
345  rowsleft -= repeatcount + 1;
346  repeatcount = rp = 0 ;
347  hbit = cwidth ;
348  }
349  }
350  turnon = !turnon ;
351  }
352  if (rowsleft != 0 || hbit != cwidth)
353  pm_error("bad pk file (more bits than required)") ;
354  }
355  if (endofpacket != pktopbm_pkloc)
356  pm_error("bad pk file (bad packet length)") ;
357 
358  ofp = pm_openw(filename[car]);
359  filename[car] = NULL;
360  pbm_writepbm(ofp, bitmap, bmx, bmy, 0) ;
361  pbm_freearray(bitmap, bmy) ;
362  pm_close(ofp) ;
363  skipspecials() ;
364  }
365  while (! feof(pkfile)) pktopbm_pkbyte() ; /* skip trailing junk */
366  pm_close(pkfile);
367  for (car = 0; car < MAXPKCHAR; car++)
368  if (filename[car])
369  pm_message("Warning: No character in position %d (file %s).",
370  car, filename[car]) ;
371  pm_message("%d bytes read from packed file.", pktopbm_pkloc-1) ;
372  exit(0);
373 }
rp
Definition: action.c:992
#define count(a)
Definition: aptex-macros.h:781
#define name
END END END break
Definition: bibtex-3.c:1974
int strcmp()
Definition: coll.cpp:143
char * strcpy()
char * temp
Definition: dvidvi.c:137
#define bmx
static char usage[]
Definition: giftopnm.c:59
#define dot
Definition: globals.h:56
#define a(n)
Definition: gpos-common.c:148
#define NULL
Definition: ftobjs.h:61
small capitals from c petite p scientific i
Definition: afcover.h:80
void exit()
int atoi(const char *)
#define getc
Definition: line.c:39
FILE * pm_openw(char *name)
Definition: libpbm1.c:624
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_writepbm(FILE *file, bit **bits, int cols, int rows, int forceplain)
Definition: libpbm3.c:136
unsigned char bit
Definition: pbm.h:9
#define pbm_allocarray(cols, rows)
Definition: pbm.h:34
#define pbm_freearray(bits, rows)
Definition: pbm.h:37
#define PBM_BLACK
Definition: pbm.h:11
#define PBM_WHITE
Definition: pbm.h:10
int integer
Definition: pbmtopk.c:38
quarterword eightbits
Definition: pbmtopk.c:42
char quarterword
Definition: pbmtopk.c:39
static integer car
Definition: pbmtopk.c:102
const char * suffix
Definition: pkg_icu.cpp:27
static eightbits pktopbm_pkbyte()
Definition: pktopbm.c:44
static integer pktopbm_pkloc
Definition: pktopbm.c:22
static integer flagbyte
Definition: pktopbm.c:29
char boolean
Definition: pktopbm.c:17
int integer
Definition: pktopbm.c:15
static integer get16()
Definition: pktopbm.c:51
static integer repeatcount
Definition: pktopbm.c:28
static integer getnyb()
Definition: pktopbm.c:66
#define MAXROWWIDTH
Definition: pktopbm.c:12
static integer pkpackednum()
Definition: pktopbm.c:94
static void ignorechar(integer car, integer endofpacket)
Definition: pktopbm.c:155
static integer get32()
Definition: pktopbm.c:58
#define NAMELENGTH
Definition: pktopbm.c:11
static void pktopbm_add_suffix(char *name, char *suffix)
Definition: pktopbm.c:33
static char * filename[256]
Definition: pktopbm.c:23
static eightbits inputbyte
Definition: pktopbm.c:26
int main(argc, argv)
Definition: pktopbm.c:165
quarterword eightbits
Definition: pktopbm.c:18
#define MAXPKCHAR
Definition: pktopbm.c:13
static FILE * pkfile
Definition: pktopbm.c:20
static void skipspecials()
Definition: pktopbm.c:119
unsigned char quarterword
Definition: pktopbm.c:16
static integer dynf
Definition: pktopbm.c:25
static boolean getbit()
Definition: pktopbm.c:80
static eightbits bitweight
Definition: pktopbm.c:27
static char pkname[80+1]
Definition: pktopbm.c:21
#define pm_error
Definition: png22pnm.c:118
#define pm_close(file)
Definition: png22pnm.c:120
#define pm_message
Definition: png22pnm.c:116
static int row
Definition: ps2pk.c:587
Definition: gf2pbm.c:137
#define FILE
Definition: t1stdio.h:34
#define feof(f)
Definition: t1stdio.h:109
int j
Definition: t4ht.c:1589
FILE * ofp
Definition: t1asm.c:89
char * rindex(char *s, int c)
Definition: shhopt.c:47
#define argv
Definition: xmain.c:270
#define argc
Definition: xmain.c:269