/* pktopbm, adapted from "pktopx in C by Tomas Rokicki" by AJCD 1/8/90 compile with: cc -lpbm -o pktopbm pktopbm.c */ #include #include #define NAMELENGTH 80 #define MAXROWWIDTH 3200 #define MAXPKCHAR 256 #define round(a) ((int)(a+0.5)) typedef int integer ; typedef unsigned char quarterword ; typedef char boolean ; typedef quarterword eightbits ; typedef FILE *bytefile ; bytefile pkfile ; char pkname[NAMELENGTH+1] ; integer pkloc ; integer i, j ; char *filename[MAXPKCHAR] ; bit **bitmap = NULL ; integer dynf ; eightbits inputbyte ; eightbits bitweight ; integer repeatcount ; integer flagbyte ; add_suffix(name, suffix) char *name, *suffix ; { int haveext = 0; if (name) { while (*name) { if (*name == '/') haveext = 0 ; else if (*name == '.') haveext = 1 ; name++ ; } if (!haveext) { *name++ = '.'; strcpy(name,suffix) ; } } } initialize() { integer i ; fprintf(stderr, "This is PKtoPBM, C Version 2.3\n") ; for (i = 0 ; i < MAXPKCHAR ; i ++) filename[i] = NULL ; } jumpout() { exit(1) ; } openpkfile() { if ((pkfile = fopen(pkname, "r")) == NULL) { fprintf(stderr, " Can't open pk file %s!\n", pkname) ; } pkloc = 0 ; } eightbits pkbyte() { pkloc++ ; return(getc(pkfile)) ; } integer get16() { integer a = pkbyte() ; return((a<<8) + pkbyte()) ; } integer get32() { integer a = get16() ; if (a > 32767) a -= 65536 ; return((a<<16) + get16()) ; } integer getnyb() { eightbits temp ; if (bitweight == 0) { inputbyte = pkbyte() ; bitweight = 16 ; } temp = inputbyte / bitweight ; inputbyte -= temp * bitweight ; bitweight >>= 4 ; return(temp) ; } boolean getbit() { boolean temp ; bitweight >>= 1 ; if (bitweight == 0) { inputbyte = pkbyte() ; bitweight = 128 ; } temp = (inputbyte >= bitweight) ; if (temp) inputbyte -= bitweight ; return(temp) ; } integer pkpackednum() { integer i, j ; i = getnyb() ; if (i == 0) { do { j = getnyb() ; i++ ; } while (!(j != 0)) ; while (i > 0) { j = (j<<4) + getnyb() ; i-- ; } return(j - 15 +((13 - dynf)<<4) + dynf) ; } else if (i <= dynf) return(i) ; else if (i < 14) return(((i - dynf - 1)<<4) + getnyb() + dynf + 1) ; else { if (i == 14) repeatcount = pkpackednum() ; else repeatcount = 1 ; return(pkpackednum()) ; } } skipspecials() { integer i, j, k ; do { flagbyte = pkbyte() ; if (flagbyte >= 240) switch(flagbyte) { case 240: case 241: case 242: case 243: i = 0 ; for (j = 240 ; j <= flagbyte ; j ++) i = (i<<8) + pkbyte() ; for (j = 1 ; j <= i ; j ++) k = pkbyte() ; break ; case 244: i = get32() ; break ; case 245: break ; case 246: break ; case 247: case 248: case 249: case 250: case 251: case 252: case 253: case 254: case 255: fprintf(stderr, " Unexpected flag byte %d!\n", flagbyte) ; jumpout() ; } } while (!((flagbyte < 240) || (flagbyte == 245))) ; } usage() { fprintf(stderr, " Usage: pktopbm pkfile[.pk] [[-c num] pbmfile]...\n"); jumpout() ; } dialog(gargc, gargv) int gargc ; char **gargv ; { integer car ; if (--gargc < 1) usage() ; strcpy(pkname, *++gargv) ; add_suffix(pkname, "pk") ; car = 0 ; while (++gargv, --gargc) { if (gargv[0][0] == '-' && gargv[0][1]) switch (gargv[0][1]) { case 'c': if (gargv[0][2]) car = atoi(*gargv+2) ; else if (++gargv, --gargc) car = atoi(*gargv) ; else usage() ; break ; default: usage() ; } else if (car < 0 || car >= MAXPKCHAR) { fprintf(stderr, " Character must be in range 0 to %d (-c)!\n", MAXPKCHAR-1) ; jumpout() ; } else filename[car++] = *gargv ; } } main(argc, argv) int argc ; char *argv[] ; { integer endofpacket ; integer designsize ; integer checksum ; integer hppp, vppp ; integer cheight, cwidth ; integer horesc ; integer packetlength ; integer rowsleft ; boolean turnon ; integer hbit ; integer count ; integer rp ; integer i, j, k ; integer car ; bit row[MAXROWWIDTH+1] ; initialize() ; dialog(argc, argv) ; openpkfile() ; if (pkbyte() != 247) { fprintf(stderr, " Bad pk file (pre command missing)!\n") ; jumpout() ; } if (pkbyte() != 89) { fprintf(stderr, " Wrong version of packed file!\n") ; jumpout() ; } j = pkbyte() ; for (i = 1 ; i <= j ; i ++) k = pkbyte() ; designsize = get32() ; checksum = get32() ; hppp = get32() ; vppp = get32() ; if (hppp != vppp) fprintf(stderr, " Warning: aspect ratio not 1:1!\n") ; skipspecials() ; while (flagbyte != 245) { dynf = (flagbyte>>4) ; flagbyte &= 15 ; turnon = (flagbyte >= 8) ; if (turnon) flagbyte &= 7 ; if (flagbyte == 7) { packetlength = get32() ; car = get32() ; endofpacket = packetlength + pkloc ; if ((car >= MAXPKCHAR) || (car < 0)) goto lab9997 ; i = get32() ; /* tfmwidth */ horesc = get32() ; i = get32() ; cwidth = get32() ; cheight = get32() ; if ((cwidth < 0) || (cheight < 0) || (cwidth > 65535) || (cheight > 65535)) goto lab9997 ; i = get32() ; j = get32() ; } else if (flagbyte > 3) { packetlength =((flagbyte - 4)<<16) + get16() ; car = pkbyte() ; endofpacket = packetlength + pkloc ; if (car >= MAXPKCHAR) goto lab9997 ; i = pkbyte() ; /* tfmwidth */ i = get16() ; horesc = get16() ; cwidth = get16() ; cheight = get16() ; i = get16() ; j = get16() ; } else { packetlength = (flagbyte<<8) + pkbyte() ; car = pkbyte() ; endofpacket = packetlength + pkloc ; if (car >= MAXPKCHAR) goto lab9997 ; i = pkbyte() ; /* tfmwidth */ i = get16() ; horesc = pkbyte() ; cwidth = pkbyte() ; cheight = pkbyte() ; i = pkbyte() ; j = pkbyte() ; } if (filename[car]) { bitmap = pbm_allocarray(cwidth, cheight) ; if (bitmap == NULL) { fprintf(stderr, " Out of memory allocating bitmap!\n") ; jumpout() ; } } else goto lab9997 ; bitweight = 0 ; if (dynf == 14) { for (i = 0 ; i < cheight ; i ++) for (j = 0 ; j < cwidth ; j ++) { if (getbit()) bitmap[i][j] = PBM_BLACK ; else bitmap[i][j] = PBM_WHITE ; } } else { rowsleft = cheight ; hbit = cwidth ; repeatcount = rp =0 ; while (rowsleft > 0) { count = pkpackednum() ; while (count > 0) { if (count < hbit) { hbit -= count ; while (count--) { if (turnon) row[rp++] = PBM_BLACK ; else row[rp++] = PBM_WHITE ; } } else { count -= hbit ; while (hbit--) { if (turnon) row[rp++] = PBM_BLACK ; else row[rp++] = PBM_WHITE ; } for (i = 0; i <= repeatcount; i++) for (j = 0; j < cwidth; j++) bitmap[i + cheight-rowsleft][j] = row[j] ; rowsleft -= repeatcount + 1; repeatcount = rp = 0 ; hbit = cwidth ; } } turnon = ! turnon ; } if ((rowsleft != 0) || (hbit != cwidth)) { fprintf(stderr, " Bad pk file (more bits than required)!\n") ; jumpout() ; } } if (endofpacket != pkloc) { fprintf(stderr, " Bad pk file (bad packet length)!\n") ; jumpout() ; } /* output bitmap to file */ { FILE *fp ; if (!strcmp(filename[car], "-")) fp = stdout ; else { if ((fp = fopen(filename[car], "w")) == NULL) { fprintf(stderr, " Can't open file %s!\n", filename[car]) ; jumpout() ; } } filename[car] = NULL; pbm_writepbm(fp, bitmap, cwidth, cheight, 0) ; pbm_freearray(bitmap, cheight) ; if (fp != stdout) (void)fclose(fp) ; } goto lab9998 ; lab9997: while (pkloc != endofpacket) i = pkbyte() ; if (car < 0 || car >= MAXPKCHAR) fprintf(stderr, " Character %d out of range!\n", car) ; lab9998: skipspecials() ; } while (! feof(pkfile)) i = pkbyte() ; pkloc-- ; for (car = 0; car < MAXPKCHAR; car++) if (filename[car]) fprintf(stderr, " Warning: No character in position %d (file %s).\n", car, filename[car]) ; fprintf(stderr, "%d bytes read from packed file.\n", pkloc) ; exit(0); }