{4:}program PKtoGF(input,output);const{6:}maxcounts=400;{:6}type{9:} ASCIIcode=32..126;{:9}{10:}textfile=packed file of char;{:10}{38:} eightbits=0..255;bytefile=packed file of eightbits;{:38}var{11:} xord:array[char]of ASCIIcode;xchr:array[0..255]of char;{:11}{39:} gffile,pkfile:bytefile;{:39}{41:}gfname,pkname:cstring; gfloc,curloc:integer;{:41}{48:}i,j:integer;endofpacket:integer; dynf:integer;car:integer;tfmwidth:integer;xoff,yoff:integer;{:48}{50:} comment:packed array[1..17]of char;magnification:integer; designsize:integer;checksum:integer;hppp,vppp:integer;{:50}{55:} cheight,cwidth:integer;wordwidth:integer;horesc,veresc:integer; packetlength:integer;lasteoc:integer;{:55}{57:} minm,maxm,minn,maxn:integer;mminm,mmaxm,mminn,mmaxn:integer; charpointer,stfmwidth:array[0..255]of integer; shoresc,sveresc:array[0..255]of integer;thischarptr:integer;{:57}{63:} inputbyte:eightbits;bitweight:eightbits; rowcounts:array[0..maxcounts]of integer;rcp:integer;{:63}{67:} countdown:integer;done:boolean;max:integer;repeatcount:integer; xtogo,ytogo:integer;turnon,firston:boolean;count:integer;curn:integer; {:67}{69:}flagbyte:integer;{:69}{78:}verbose:cinttype;{:78}{74:} procedure parsearguments;const noptions=3; var longoptions:array[0..noptions]of getoptstruct; getoptreturnval:integer;optionindex:cinttype;currentoption:0..noptions; begin{79:}verbose:=false;{:79};{75:}currentoption:=0; longoptions[currentoption].name:='help'; longoptions[currentoption].hasarg:=0;longoptions[currentoption].flag:=0; longoptions[currentoption].val:=0;currentoption:=currentoption+1;{:75} {76:}longoptions[currentoption].name:='version'; longoptions[currentoption].hasarg:=0;longoptions[currentoption].flag:=0; longoptions[currentoption].val:=0;currentoption:=currentoption+1;{:76} {77:}longoptions[currentoption].name:='verbose'; longoptions[currentoption].hasarg:=0; longoptions[currentoption].flag:=addressof(verbose); longoptions[currentoption].val:=1;currentoption:=currentoption+1;{:77} {80:}longoptions[currentoption].name:=0; longoptions[currentoption].hasarg:=0;longoptions[currentoption].flag:=0; longoptions[currentoption].val:=0;{:80}; repeat getoptreturnval:=getoptlongonly(argc,argv,'',longoptions, addressof(optionindex));if getoptreturnval=-1 then begin; end else if getoptreturnval=63 then begin usage(1,'pktogf'); end else if(strcmp(longoptions[optionindex].name,'help')=0)then begin usage(0,PKTOGFHELP); end else if(strcmp(longoptions[optionindex].name,'version')=0)then begin printversionandexit('This is PKtoGF, Version 1.1',nil,'Tomas Rokicki'); end;until getoptreturnval=-1; if(optind+1<>argc)and(optind+2<>argc)then begin writeln(stderr, 'pktogf: Need one or two file arguments.');usage(1,'pktogf');end;end; {:74}procedure initialize;var i:integer;begin kpsesetprogname(argv[0]); kpseinitprog('PKTOGF',0,nil,nil);parsearguments; if verbose then writeln(output,'This is PKtoGF, Version 1.1');{12:} for i:=0 to 31 do xchr[i]:='?';xchr[32]:=' ';xchr[33]:='!'; xchr[34]:='"';xchr[35]:='#';xchr[36]:='$';xchr[37]:='%';xchr[38]:='&'; xchr[39]:='''';xchr[40]:='(';xchr[41]:=')';xchr[42]:='*';xchr[43]:='+'; xchr[44]:=',';xchr[45]:='-';xchr[46]:='.';xchr[47]:='/';xchr[48]:='0'; xchr[49]:='1';xchr[50]:='2';xchr[51]:='3';xchr[52]:='4';xchr[53]:='5'; xchr[54]:='6';xchr[55]:='7';xchr[56]:='8';xchr[57]:='9';xchr[58]:=':'; xchr[59]:=';';xchr[60]:='<';xchr[61]:='=';xchr[62]:='>';xchr[63]:='?'; xchr[64]:='@';xchr[65]:='A';xchr[66]:='B';xchr[67]:='C';xchr[68]:='D'; xchr[69]:='E';xchr[70]:='F';xchr[71]:='G';xchr[72]:='H';xchr[73]:='I'; xchr[74]:='J';xchr[75]:='K';xchr[76]:='L';xchr[77]:='M';xchr[78]:='N'; xchr[79]:='O';xchr[80]:='P';xchr[81]:='Q';xchr[82]:='R';xchr[83]:='S'; xchr[84]:='T';xchr[85]:='U';xchr[86]:='V';xchr[87]:='W';xchr[88]:='X'; xchr[89]:='Y';xchr[90]:='Z';xchr[91]:='[';xchr[92]:='\';xchr[93]:=']'; xchr[94]:='^';xchr[95]:='_';xchr[96]:='`';xchr[97]:='a';xchr[98]:='b'; xchr[99]:='c';xchr[100]:='d';xchr[101]:='e';xchr[102]:='f'; xchr[103]:='g';xchr[104]:='h';xchr[105]:='i';xchr[106]:='j'; xchr[107]:='k';xchr[108]:='l';xchr[109]:='m';xchr[110]:='n'; xchr[111]:='o';xchr[112]:='p';xchr[113]:='q';xchr[114]:='r'; xchr[115]:='s';xchr[116]:='t';xchr[117]:='u';xchr[118]:='v'; xchr[119]:='w';xchr[120]:='x';xchr[121]:='y';xchr[122]:='z'; xchr[123]:='{';xchr[124]:='|';xchr[125]:='}';xchr[126]:='~'; for i:=127 to 255 do xchr[i]:='?';{:12}{13:} for i:=0 to 127 do xord[chr(i)]:=32; for i:=32 to 126 do xord[xchr[i]]:=i;{:13}{51:}{:51}{58:}mminm:=999999; mminn:=999999;mmaxm:=-999999;mmaxn:=-999999; for i:=0 to 255 do charpointer[i]:=-1;{:58}end;{:4}{40:} procedure openpkfile;begin pkname:=cmdline(optind); pkfile:=kpseopenfile(cmdline(optind),kpsepkformat); if pkfile then begin curloc:=0;end;end;procedure opengffile; begin if optind+1=argc then begin gfname:=basenamechangesuffix(pkname, 'pk','gf');end else begin gfname:=cmdline(optind+1);end; rewritebin(gffile,gfname);gfloc:=0;end;{:40}{43:} function getbyte:integer;var b:eightbits; begin if eof(pkfile)then getbyte:=0 else begin read(pkfile,b); curloc:=curloc+1;getbyte:=b;end;end;function signedbyte:integer; var b:eightbits;begin read(pkfile,b);curloc:=curloc+1; if b<128 then signedbyte:=b else signedbyte:=b-256;end; function gettwobytes:integer;var a,b:eightbits;begin read(pkfile,a); read(pkfile,b);curloc:=curloc+2;gettwobytes:=a*256+b;end; function signedpair:integer;var a,b:eightbits;begin read(pkfile,a); read(pkfile,b);curloc:=curloc+2; if a<128 then signedpair:=a*256+b else signedpair:=(a-256)*256+b;end; {function getthreebytes:integer;var a,b,c:eightbits; begin read(pkfile,a);read(pkfile,b);read(pkfile,c);curloc:=curloc+3; getthreebytes:=(a*256+b)*256+c;end;function signedtrio:integer; var a,b,c:eightbits;begin read(pkfile,a);read(pkfile,b);read(pkfile,c); curloc:=curloc+3; if a<128 then signedtrio:=(a*256+b)*256+c else signedtrio:=((a-256)*256+ b)*256+c;end;}function signedquad:integer;var a,b,c,d:eightbits; begin read(pkfile,a);read(pkfile,b);read(pkfile,c);read(pkfile,d); curloc:=curloc+4; if a<128 then signedquad:=((a*256+b)*256+c)*256+d else signedquad:=(((a -256)*256+b)*256+c)*256+d;end;{:43}{46:}procedure gf16(i:integer); begin begin putbyte(i div 256,gffile);gfloc:=gfloc+1 end; begin putbyte(i mod 256,gffile);gfloc:=gfloc+1 end;end; procedure gf24(i:integer);begin begin putbyte(i div 65536,gffile); gfloc:=gfloc+1 end;gf16(i mod 65536);end;procedure gfquad(i:integer); begin if i>=0 then begin begin putbyte(i div 16777216,gffile); gfloc:=gfloc+1 end;end else begin i:=i+1073741824;i:=i+1073741824; begin putbyte(128+(i div 16777216),gffile);gfloc:=gfloc+1 end;end; gf24(i mod 16777216);end;{:46}{62:}function getnyb:integer; var temp:eightbits;begin if bitweight=0 then begin inputbyte:=getbyte; bitweight:=16;end;temp:=inputbyte div bitweight; inputbyte:=inputbyte-temp*bitweight;bitweight:=bitweight div 16; getnyb:=temp;end;function getbit:boolean;var temp:boolean; begin bitweight:=bitweight div 2; if bitweight=0 then begin inputbyte:=getbyte;bitweight:=128;end; temp:=inputbyte>=bitweight;if temp then inputbyte:=inputbyte-bitweight; getbit:=temp;end;{30:}function pkpackednum:integer;var i,j:integer; begin i:=getnyb;if i=0 then begin repeat j:=getnyb;i:=i+1;until j<>0; while i>0 do begin j:=j*16+getnyb;i:=i-1;end; pkpackednum:=j-15+(13-dynf)*16+dynf; end else if i<=dynf then pkpackednum:=i else if i<14 then pkpackednum:=( i-dynf-1)*16+getnyb+dynf+1 else begin if i=14 then repeatcount:= pkpackednum else repeatcount:=1;pkpackednum:=pkpackednum;end;end;{:30} {:62}{70:}procedure skipspecials;var i,j,k:integer; begin thischarptr:=gfloc;repeat flagbyte:=getbyte; if flagbyte>=240 then case flagbyte of 240,241,242,243:begin i:=0; begin putbyte(flagbyte-1,gffile);gfloc:=gfloc+1 end; for j:=240 to flagbyte do begin k:=getbyte;begin putbyte(k,gffile); gfloc:=gfloc+1 end;i:=256*i+k;end; for j:=1 to i do begin putbyte(getbyte,gffile);gfloc:=gfloc+1 end;end; 244:begin begin putbyte(243,gffile);gfloc:=gfloc+1 end; gfquad(signedquad);end;245:begin end;246:begin end; 247,248,249,250,251,252,253,254,255:begin verbose:=true; if verbose then writeln(output,'Unexpected ',flagbyte:1,'!');uexit(1); end;end;until(flagbyte<240)or(flagbyte=245);end;{:70}{73:} begin initialize;{44:}openpkfile;opengffile{:44};{49:} if getbyte<>247 then begin verbose:=true; if verbose then writeln(output,'Bad pk file! pre command missing.'); uexit(1);end;begin putbyte(247,gffile);gfloc:=gfloc+1 end; if getbyte<>89 then begin verbose:=true; if verbose then writeln(output,'Wrong version of packed file!.'); uexit(1);end;begin putbyte(131,gffile);gfloc:=gfloc+1 end;j:=getbyte; begin putbyte(j,gffile);gfloc:=gfloc+1 end; if verbose then write(output,'{');for i:=1 to j do begin hppp:=getbyte; begin putbyte(hppp,gffile);gfloc:=gfloc+1 end; if verbose then write(output,xchr[xord[hppp]]);end; if verbose then writeln(output,'}');designsize:=signedquad; checksum:=signedquad;hppp:=signedquad;vppp:=signedquad; if hppp<>vppp then if verbose then writeln(output, 'Warning: aspect ratio not 1:1!'); magnification:=round(hppp*72.27*5/65536);lasteoc:=gfloc{:49}; skipspecials;while flagbyte<>245 do begin{47:}dynf:=flagbyte div 16; flagbyte:=flagbyte mod 16;turnon:=flagbyte>=8; if turnon then flagbyte:=flagbyte-8;if flagbyte=7 then{52:} begin packetlength:=signedquad;car:=signedquad; endofpacket:=packetlength+curloc;tfmwidth:=signedquad; horesc:=signedquad;veresc:=signedquad;cwidth:=signedquad; cheight:=signedquad;wordwidth:=(cwidth+31)div 32;xoff:=signedquad; yoff:=signedquad;end{:52}else if flagbyte>3 then{53:} begin packetlength:=(flagbyte-4)*65536+gettwobytes;car:=getbyte; endofpacket:=packetlength+curloc;i:=getbyte; tfmwidth:=i*65536+gettwobytes;horesc:=gettwobytes*65536;veresc:=0; cwidth:=gettwobytes;cheight:=gettwobytes;wordwidth:=(cwidth+31)div 32; xoff:=signedpair;yoff:=signedpair;end{:53}else{54:} begin packetlength:=flagbyte*256+getbyte;car:=getbyte; endofpacket:=packetlength+curloc;i:=getbyte; tfmwidth:=i*65536+gettwobytes;horesc:=getbyte*65536;veresc:=0; cwidth:=getbyte;cheight:=getbyte;wordwidth:=(cwidth+31)div 32; xoff:=signedbyte;yoff:=signedbyte;end{:54};{56:} if(cheight=0)or(cwidth=0)then begin cheight:=0;cwidth:=0;xoff:=0; yoff:=0;end;minm:=-xoff;if minmmmaxm then mmaxm:=maxm;minn:=yoff-cheight+1; maxn:=yoff;if minn>maxn then minn:=maxn;if minnmmaxn then mmaxn:=maxn{:56};{60:}begin i:=car mod 256; if(charpointer[i]=-1)then begin sveresc[i]:=veresc;shoresc[i]:=horesc; stfmwidth[i]:=tfmwidth; end else begin if(sveresc[i]<>veresc)or(shoresc[i]<>horesc)or(stfmwidth[ i]<>tfmwidth)then if verbose then writeln(output,'Two characters mod ',i :1,' have mismatched parameters');end;end{:60};{59:} begin if(charpointer[car mod 256]=-1)and(car>=0)and(car<256)and(maxm>=0) and(maxm<256)and(maxn>=0)and(maxn<256)and(maxm>=minm)and(maxn>=minn)and( maxm0)and(cheight>0)then begin bitweight:=0; countdown:=cheight*cwidth-1;if dynf=14 then turnon:=getbit; repeatcount:=0;xtogo:=cwidth;ytogo:=cheight;curn:=cheight;count:=0; firston:=turnon;turnon:=not turnon;rcp:=0; while ytogo>0 do begin if count=0 then{64:}begin turnon:=not turnon; if dynf=14 then begin count:=1;done:=false; while not done do begin if countdown<=0 then done:=true else if(turnon= getbit)then count:=count+1 else done:=true;countdown:=countdown-1;end; end else count:=pkpackednum;end{:64};if rcp=0 then firston:=turnon; while count>=xtogo do begin rowcounts[rcp]:=xtogo;count:=count-xtogo; for i:=0 to repeatcount do begin{66:} if(rcp>0)or firston then begin j:=0;max:=rcp; if not turnon then max:=max-1; if curn-ytogo=1 then begin if firston then begin putbyte(74,gffile); gfloc:=gfloc+1 end else if rowcounts[0]<165 then begin begin putbyte(74+ rowcounts[0],gffile);gfloc:=gfloc+1 end;j:=j+1; end else begin putbyte(70,gffile);gfloc:=gfloc+1 end; end else if curn>ytogo then begin if curn-ytogo<257 then begin begin putbyte(71,gffile);gfloc:=gfloc+1 end; begin putbyte(curn-ytogo-1,gffile);gfloc:=gfloc+1 end; end else begin begin putbyte(72,gffile);gfloc:=gfloc+1 end; gf16(curn-ytogo-1);end;if firston then begin putbyte(0,gffile); gfloc:=gfloc+1 end;end else if firston then begin putbyte(0,gffile); gfloc:=gfloc+1 end;curn:=ytogo; while j<=max do begin if rowcounts[j]<64 then begin putbyte(0+rowcounts[ j],gffile); gfloc:=gfloc+1 end else if rowcounts[j]<256 then begin begin putbyte(64, gffile);gfloc:=gfloc+1 end;begin putbyte(rowcounts[j],gffile); gfloc:=gfloc+1 end;end else begin begin putbyte(65,gffile); gfloc:=gfloc+1 end;gf16(rowcounts[j]);end;j:=j+1;end;end{:66}; ytogo:=ytogo-1;end;repeatcount:=0;xtogo:=cwidth;rcp:=0; if(count>0)then firston:=turnon;end; if count>0 then begin rowcounts[rcp]:=count; if rcp=0 then firston:=turnon;rcp:=rcp+1; if rcp>maxcounts then begin verbose:=true; if verbose then writeln(output,'A character had too many run counts'); uexit(1);end;xtogo:=xtogo-count;count:=0;end;end;end{:65}; begin putbyte(69,gffile);gfloc:=gfloc+1 end;lasteoc:=gfloc; if endofpacket<>curloc then begin verbose:=true; if verbose then writeln(output,'Bad pk file! Bad packet length.'); uexit(1);end{:47};skipspecials;end;while not eof(pkfile)do i:=getbyte; {68:}j:=gfloc;begin putbyte(248,gffile);gfloc:=gfloc+1 end; gfquad(lasteoc);gfquad(designsize);gfquad(checksum);gfquad(hppp); gfquad(vppp);gfquad(mminm);gfquad(mmaxm);gfquad(mminn);gfquad(mmaxn); {61:} for i:=0 to 255 do if charpointer[i]<>-1 then begin if(sveresc[i]=0)and( shoresc[i]>=0)and(shoresc[i]<16777216)and(shoresc[i]mod 65536=0)then begin begin putbyte(246,gffile);gfloc:=gfloc+1 end; begin putbyte(i,gffile);gfloc:=gfloc+1 end; begin putbyte(shoresc[i]div 65536,gffile);gfloc:=gfloc+1 end; end else begin begin putbyte(245,gffile);gfloc:=gfloc+1 end; begin putbyte(i,gffile);gfloc:=gfloc+1 end;gfquad(shoresc[i]); gfquad(sveresc[i]);end;gfquad(stfmwidth[i]);gfquad(charpointer[i]); end{:61};begin putbyte(249,gffile);gfloc:=gfloc+1 end;gfquad(j); begin putbyte(131,gffile);gfloc:=gfloc+1 end; for i:=0 to 3 do begin putbyte(223,gffile);gfloc:=gfloc+1 end; while gfloc mod 4<>0 do begin putbyte(223,gffile); gfloc:=gfloc+1 end{:68}; if verbose then writeln(output,curloc:1,' bytes unpacked to ',gfloc:1, ' bytes.');end.{:73}