Annotation of ratfiv/epstopdf.c, revision 1.1
1.1 ! brouard 1: /*
! 2: # epstopdf: written by Kong Hoon Lee konghoon@hyowon.cc.pusan.ac.kr<4/1/1999>
! 3: #
! 4: # It converts an EPS file to an encapsulated PDF File and
! 5: # coded with the perl script 'epstopdf' by Sebastian Rahtz on
! 6: # http://tug.org/applications/pdftex/epstopdf .
! 7: # It works like as the perl script without 'perl' for Windows 95
! 8: # but requires 'Ghostscript' for Windows.
! 9: #
! 10: */
! 11:
! 12: #include <stdio.h>
! 13: #include <stdlib.h>
! 14: #include <string.h>
! 15: #include <math.h>
! 16: #define MAX_IN 10000
! 17:
! 18:
! 19: #ifndef GSEXEC
! 20: #ifdef __WIN32__
! 21: #define GSEXEC "gswin32c"
! 22: #else
! 23: #define GSEXEC "gs"
! 24: #endif
! 25: #endif
! 26:
! 27:
! 28: #define BEGINDOC "%%BeginDocument"
! 29: #define ENDDOC "%%EndDocument"
! 30: #define PSSTART "%!"
! 31: #define PSEOF "%%EOF"
! 32:
! 33: #define TRUE 1
! 34: #define FALSE 0
! 35:
! 36:
! 37: static void usage(void)
! 38:
! 39: {
! 40: printf("epstopdf 2.2.9:\n");
! 41: printf("written by Kong Hoon Lee, konghoon@dreamwiz.com <1999-4-1>\n");
! 42: printf("changes by Juergen Bausa, Juergen.Bausa@T-Online.de <2000-10-6>\n");
! 43: printf("bugfix by Pascal Perichon, Pascal.Perichon@u-bourgogne.fr <2000-5-25>\n\n");
! 44: printf("It converts an EPS file to an encapsulated PDF File and is written\n");
! 45: printf("based on the perl script 'epstopdf' by Sebastian Rahtz on\n");
! 46: printf("http://tug.org/applications/pdftex/epstopdf .\n");
! 47: printf("It works like the perl script without 'perl' but requires 'Ghostscript'.\n");
! 48: printf("The accompanied Makefile can be used to automate the update of all eps/pdf\n");
! 49: printf("files in a directory. Just put it in the directory where your eps files\n");
! 50: printf("are and type 'make' from the command line (you will need a version of\n");
! 51: printf("GNU-make)\n\n");
! 52:
! 53: printf("This program invokes '%s' and the path including '%s'\n",GSEXEC,GSEXEC);
! 54: printf("should be included to the environment variable 'PATH'.\n");
! 55: printf("'%s' should know, where to find its initialization files\n",GSEXEC);
! 56: printf("and fonts, using an registry entry (Windows) or an environment variable.\n\n");
! 57:
! 58: printf("Using a different output device, it is also possible to convert eps\n");
! 59: printf("files to bitmaps (e.g. -sDEVICE=bmpmono).\n\n");
! 60:
! 61: printf("Usage: epstopdf [options] filename-of-an-eps-file\n");
! 62: printf("Options:\n");
! 63: printf(" --help: print usage\n");
! 64: printf(" --outfile=<file>: write result to <file>\n");
! 65: printf(" --tmpfile=<file>: use <file> as temporary file\n");
! 66: printf(" --(no)filter: read/writ standard input/output (default: false)\n");
! 67: printf(" --(no)gs: run ghostscript (default: true)\n");
! 68: printf(" --(no)compress: use compression (default: true)\n");
! 69: printf(" --(no)hires: scan HiresBoundingBox (default: false)\n");
! 70: printf(" --(no)exact: scan ExactBoundingBox (default: false)\n");
! 71: printf(" --(no)debug: debug informations (default: false)\n");
! 72: printf(" --(no)wait: wait for keystroke (default: false)\n");
! 73: printf(" --gsexec=<gs>: use <gs> to invoke ghostscript (default: %s)\n",GSEXEC);
! 74: printf(" --enlarge=<a>: enlarge BB by <a>/72 '' (default: 0.)\n");
! 75: printf(" -sDEVICE=<dev> : use <dev> as output device (default: pdfwrite)\n");
! 76: printf(" -r<a>: output resolution for gs (default: 600)\n");
! 77: printf(" --width=<a>: output width in pixels (default: none)\n");
! 78: printf(" --height=<a>: output height in pixels (default: none)\n");
! 79: printf(" --gsopt=<a>: add <a> to the gs command line (default: none)\n");
! 80: }
! 81:
! 82:
! 83: static int round(double a)
! 84:
! 85: {
! 86: return floor(a+0.5);
! 87: }
! 88:
! 89: static int isint(double a)
! 90:
! 91: {
! 92: if(fabs(a-round(a))<1e-6) return 1;
! 93: else return 0;
! 94: }
! 95:
! 96:
! 97: int main(int argc,char *argv[])
! 98:
! 99: {
! 100: FILE *in,*out;
! 101: char *infile=NULL,*outfile=NULL,*tmpfile=NULL,*copt,*ptr,*gsexec,buf[21];
! 102: char command[MAX_IN],ch[MAX_IN],*BBname,*device,ropt[20],*gsopt;
! 103: double bbllx,bblly,bburx,bbury,xoffset,yoffset,enlarge;
! 104: int width,height,res,xpix,ypix;
! 105: int i,count,status,BBCorrected,did_CR,debug,compress,usegs,wait,
! 106: BBhires,BBexact,found,depth,filter,ngsopt,in_ps;
! 107: fpos_t fpos;
! 108:
! 109:
! 110: #if defined (__EMX__)
! 111: _wildcard (&argc, &argv);
! 112: #endif
! 113:
! 114: /* default parameter */
! 115: status=0;
! 116: BBCorrected=0;
! 117: BBhires=0;
! 118: BBexact=0;
! 119: debug=0;
! 120: compress=1;
! 121: usegs=1;
! 122: gsexec=GSEXEC;
! 123: wait=0;
! 124: filter=0;
! 125: enlarge=0.;
! 126: res=600;
! 127: device="pdfwrite";
! 128: xpix=0;
! 129: ypix=0;
! 130: ngsopt=100;
! 131: gsopt=malloc(ngsopt);
! 132: gsopt[0]='\0';
! 133:
! 134:
! 135: /******************************************************************
! 136:
! 137: Process command line options
! 138:
! 139: ******************************************************************/
! 140:
! 141: for(i=1;i<argc;i++){
! 142:
! 143: /* printf("i=%d arg=>>%s<<\n",i,argv[i]); */
! 144:
! 145: if(!strcmp(argv[i],"--help") || !strcmp(argv[i],"-h")){
! 146: usage();
! 147: status=0;
! 148: goto EXIT;
! 149: }
! 150:
! 151: if(!strcmp(argv[i],"--debug") || !strcmp(argv[i],"-d")){
! 152: debug=1;
! 153: continue;
! 154: }
! 155:
! 156: if(!strcmp(argv[i],"--nodebug")){
! 157: debug=0;
! 158: continue;
! 159: }
! 160:
! 161: if(!strcmp(argv[i],"--compress") || !strcmp(argv[i],"-c")){
! 162: compress=1;
! 163: continue;
! 164: }
! 165:
! 166: if(!strcmp(argv[i],"--nocompress")){
! 167: compress=0;
! 168: continue;
! 169: }
! 170:
! 171: if(!strcmp(argv[i],"--nogs")){
! 172: usegs=0;
! 173: continue;
! 174: }
! 175:
! 176: if(!strcmp(argv[i],"--gs")){
! 177: usegs=1;
! 178: continue;
! 179: }
! 180:
! 181: if(!strcmp(argv[i],"--wait") || !strcmp(argv[i],"-w")){
! 182: wait=1;
! 183: continue;
! 184: }
! 185:
! 186: if(!strcmp(argv[i],"--nowait")){
! 187: wait=0;
! 188: continue;
! 189: }
! 190:
! 191: if(!strcmp(argv[i],"--filter")){
! 192: filter=1;
! 193: continue;
! 194: }
! 195:
! 196: if(!strcmp(argv[i],"--nofilter")){
! 197: filter=0;
! 198: continue;
! 199: }
! 200:
! 201: if(!strcmp(argv[i],"--hires")){
! 202: BBhires=1;
! 203: continue;
! 204: }
! 205:
! 206: if(!strcmp(argv[i],"--nohires")){
! 207: BBhires=0;
! 208: continue;
! 209: }
! 210:
! 211: if(!strcmp(argv[i],"--exact")){
! 212: BBexact=1;
! 213: continue;
! 214: }
! 215:
! 216: if(!strcmp(argv[i],"--noexact")){
! 217: BBexact=0;
! 218: continue;
! 219: }
! 220:
! 221: if(!strncmp(argv[i],"--outfile=",strlen("--outfile="))){
! 222: outfile=malloc(strlen(argv[i])-strlen("--outfile=")+1);
! 223: strcpy(outfile, argv[i]+strlen("--outfile="));
! 224: continue;
! 225: }
! 226:
! 227: if(!strncmp(argv[i],"--tmpfile=",strlen("--tmpfile="))){
! 228: tmpfile=malloc(strlen(argv[i])-strlen("--tmpfile=")+1);
! 229: strcpy(tmpfile, argv[i]+strlen("--tmpfile="));
! 230: continue;
! 231: }
! 232:
! 233: if(!strncmp(argv[i],"-r",strlen("-r"))){
! 234: sscanf(argv[i]+strlen("-r"),"%d",&res);
! 235: continue;
! 236: }
! 237:
! 238: if(!strncmp(argv[i],"--width=",strlen("--width="))){
! 239: sscanf(argv[i]+strlen("--width="),"%d",&xpix);
! 240: continue;
! 241: }
! 242:
! 243: if(!strncmp(argv[i],"--height=",strlen("--height="))){
! 244: sscanf(argv[i]+strlen("--height="),"%d",&ypix);
! 245: continue;
! 246: }
! 247:
! 248: if(!strncmp(argv[i],"--gsopt=",strlen("--gsopt="))){
! 249: char *opt=argv[i]+strlen("--gsopt=");
! 250: if(strlen(gsopt)+strlen(opt)+2 < ngsopt){
! 251: ngsopt+=100;
! 252: gsopt=realloc(gsopt,ngsopt);
! 253: }
! 254: strcat(gsopt," ");
! 255: strcat(gsopt,opt);
! 256: continue;
! 257: }
! 258:
! 259: if(!strncmp(argv[i],"-sDEVICE=",strlen("-sDEVICE="))){
! 260: device=argv[i]+strlen("-sDEVICE=");
! 261: continue;
! 262: }
! 263:
! 264: if(!strcmp(argv[i],"-o") && i+1<argc){
! 265: outfile=malloc(strlen(argv[i+1])+1);
! 266: strcpy(outfile, argv[i+1]);
! 267: i++;
! 268: continue;
! 269: }
! 270:
! 271: if(!strncmp(argv[i],"--gsexec=",strlen("--gsexec="))){
! 272: gsexec=argv[i]+strlen("--gsexec=");
! 273: continue;
! 274: }
! 275:
! 276:
! 277: if(argv[i][0]!='-'){
! 278: if(infile) printf("\nCan process only one input file\n");
! 279: else infile=argv[i];
! 280: continue;
! 281: }
! 282:
! 283: if(!strncmp(argv[i],"--enlarge=",strlen("--enlarge="))){
! 284: sscanf(argv[i]+strlen("--enlarge="),"%lf",&enlarge);
! 285: continue;
! 286: }
! 287:
! 288: usage();
! 289: fprintf(stderr,"\nunknown option >>%s<<\n",argv[i]);
! 290: status=1;
! 291: goto EXIT;
! 292: }
! 293:
! 294:
! 295:
! 296: /******************************************************************
! 297:
! 298: check arguments and files
! 299:
! 300: ******************************************************************/
! 301:
! 302:
! 303: if(filter) debug=0;
! 304: if(filter) wait =0;
! 305:
! 306: if(BBexact && BBhires){
! 307: fprintf(stderr,"\nOptions --hires and --exact cannot be used together\n");
! 308: status=1;
! 309: goto EXIT;
! 310: }
! 311:
! 312: if (BBexact) BBname="%%ExactBoundingBox:";
! 313: else if(BBhires) BBname="%%HiresBoundingBox:";
! 314: else BBname="%%BoundingBox:";
! 315:
! 316: if(!filter) {
! 317:
! 318: if(!infile) {
! 319: usage();
! 320: fprintf(stderr,"no input file specified!\n");
! 321: status=1;
! 322: goto EXIT;
! 323: }
! 324:
! 325: if((in=fopen(infile,"r")) == NULL) {
! 326: usage();
! 327: fprintf(stderr,"%s: File not found!\n",infile);
! 328: status=1;
! 329: goto EXIT;
! 330: }
! 331: fclose(in);
! 332:
! 333: }else{
! 334:
! 335: if(infile) {
! 336: fprintf(stderr,"Input file cannot be used with filter option!\n");
! 337: status=1;
! 338: goto EXIT;
! 339: }
! 340:
! 341: infile="epstopdf"; /* dummy input filename to generate tmp-filename */
! 342: }
! 343:
! 344:
! 345:
! 346: /* find a temporary filename that does not exist yet */
! 347: if(usegs && !tmpfile){
! 348: tmpfile=malloc(strlen(infile)+9);
! 349: count=0;
! 350: do{
! 351: if(count>99) {
! 352: fprintf(stderr,"No temporary file available! Try deleting *.tmp.\n\n");
! 353: status=1;
! 354: goto EXIT;
! 355: }
! 356: sprintf(tmpfile,"%s.%d.tmp",infile,count);
! 357: if(debug) printf("checking temporary filename >>%s<<\n",tmpfile);
! 358: out=fopen(tmpfile,"r");
! 359: if(out) fclose(out);
! 360: count++;
! 361: }while(out);
! 362: }
! 363:
! 364: if(!filter){
! 365: if(!outfile){
! 366: outfile=malloc(strlen(infile)+6);
! 367: strcpy(outfile,infile);
! 368: ptr=outfile;
! 369: while(strpbrk(ptr,"\\/")) ptr=strpbrk(ptr,"\\/")+1;
! 370: ptr=strrchr(ptr,'.');
! 371: if(ptr) *ptr='\0';
! 372: if(usegs) strcat(outfile,".pdf");
! 373: else strcat(outfile,"2.eps");
! 374: }
! 375: }else{
! 376: if(outfile) {
! 377: fprintf(stderr,"Output file cannot be used with filter option!\n");
! 378: status=1;
! 379: goto EXIT;
! 380: }
! 381: outfile=malloc(2);
! 382: strcpy(outfile,"-");
! 383: }
! 384:
! 385:
! 386:
! 387: if(!filter) printf("Converting %s to %s ..... ",infile,outfile);
! 388:
! 389:
! 390: /******************************************************************
! 391:
! 392: put the pagesize from the bounding box into the eps file
! 393:
! 394: ******************************************************************/
! 395:
! 396:
! 397: if(debug) printf("\nAdding correct pagesize to EPS ... searching for %s ...\n",BBname);
! 398:
! 399: if (!filter) in = fopen(infile, "r");
! 400: else in = stdin;
! 401: if (usegs) out = fopen(tmpfile,"w");
! 402: else if(!filter) out = fopen(outfile,"w");
! 403: else out = stdout;
! 404: if(!in || !out){
! 405: fprintf(stderr,"cannot open files\n");
! 406: status=1;
! 407: goto EXIT;
! 408: }
! 409:
! 410: depth=0;
! 411: in_ps=FALSE;
! 412: while (fgets(ch,MAX_IN,in)){
! 413: if(!in_ps) { /* throw away binary junk before %! */
! 414: if(!strncmp(ch,PSSTART,strlen(PSSTART))) in_ps=TRUE;
! 415: else continue;
! 416: }
! 417: if(!strncmp(ch,BEGINDOC,strlen(BEGINDOC))) depth++; /* count included documents */
! 418: if(!strncmp(ch,ENDDOC, strlen(ENDDOC) )) depth--;
! 419: if(!strncmp(ch,BBname, strlen(BBname)) && depth==0) { /* look for BB comment in main doc only */
! 420: sscanf(ch,"%*s %20s",buf);
! 421: if(!strcmp(buf,"(atend)")){ /* BB is atended */
! 422: if(filter){
! 423: fprintf(stderr,"Cannot look for BoundingBox in the trailer "
! 424: "with option --filter\n");
! 425: if(usegs) remove(tmpfile);
! 426: status=1;
! 427: goto EXIT;
! 428: }
! 429: if(debug) printf("\n (atend)! ...\n");
! 430: fgetpos(in, &fpos); /* store file position */
! 431: found=0;
! 432: while (fgets(ch,MAX_IN,in)){
! 433: if(!strncmp(ch,BEGINDOC,strlen(BEGINDOC))) depth++; /* count included documents */
! 434: if(!strncmp(ch,ENDDOC, strlen(ENDDOC) )) depth--;
! 435: if(!strncmp(ch,BBname,strlen(BBname)) && depth==0) { /* look for bounding box in main doc only */
! 436: found=1;
! 437: fsetpos(in, &fpos); /* rewind to (atend) comment */
! 438: break;
! 439: }
! 440: }
! 441: if(!found){
! 442: fprintf(stderr,"atended %s not found\n",BBname);
! 443: if(usegs && !debug) remove(tmpfile);
! 444: if(!usegs && !debug) remove(outfile);
! 445: status=1;
! 446: goto EXIT;
! 447: }
! 448: }
! 449:
! 450:
! 451: /* No Idea what ExactBoundingBox means. Hope it also works with this code */
! 452:
! 453: /* I thought Postscript says that the bounding box should be integer.
! 454: However, some applications (like Corel Draw) use floats and gs has no
! 455: problem with it. So I use floats for translate that will result in a
! 456: more exact box. Since gs seems not to be able to use floats in
! 457: setpagedevice, these values are converted to integer */
! 458:
! 459: if(!BBCorrected){ /* write Bounding box one time only! */
! 460: if(sscanf(ch,"%*s %lf %lf %lf %lf",&bbllx,&bblly,&bburx,&bbury)!=4){
! 461: fprintf(stderr,"incorrect %s \n",BBname);
! 462: if(usegs && !debug) remove(tmpfile);
! 463: status=1;
! 464: goto EXIT;
! 465: }
! 466: if(debug) printf("BoundingBox: %f %f %f %f\n",bbllx,bblly,bburx,bbury);
! 467: bblly -= enlarge;
! 468: bbllx -= enlarge;
! 469: bbury += enlarge;
! 470: bburx += enlarge;
! 471: width = ceil(bburx-bbllx); /* make papersize integer and enlarge it a little bit */
! 472: height = ceil(bbury-bblly);
! 473: xoffset =-bbllx;
! 474: yoffset =-bblly;
! 475: fprintf(out,"%s %d %d %d %d\n",BBname,0,0,width,height);
! 476: fprintf(out,"<< /PageSize [%d %d] >> setpagedevice \n",width,height);
! 477: if(isint(xoffset) && isint(yoffset)) fprintf(out,"gsave %d %d translate\n",round(xoffset),round(yoffset));
! 478: else fprintf(out,"gsave %f %f translate\n",xoffset,yoffset);
! 479: if(!filter) printf(" (%dx%d mm) ... ",(int)(25.4/72.*width),(int)(25.4/72.*height));
! 480: did_CR=1;
! 481: BBCorrected=1;
! 482: }
! 483: }else{
! 484: fputs(ch,out);
! 485: if(strpbrk(ch, "\n")) did_CR=1;
! 486: else did_CR=0;
! 487: if(!strncmp(ch,PSEOF,strlen(PSEOF)) && depth==0) break; /* end of file */
! 488: }
! 489: }
! 490: if(BBCorrected){
! 491: if(!did_CR) fprintf(out,"\ngrestore\n");
! 492: else fprintf(out, "grestore\n");
! 493: }
! 494: if(in !=stdin ) fclose(in);
! 495: if(out!=stdout) fclose(out);
! 496:
! 497: if(width && height){
! 498: if (xpix) res=(72*xpix)/width;
! 499: else if (ypix) res=(72*ypix)/height;
! 500: }
! 501:
! 502:
! 503: /******************************************************************
! 504:
! 505: do the conversion eps->pdf using gs
! 506:
! 507: ******************************************************************/
! 508:
! 509:
! 510: if(usegs){
! 511:
! 512: if(compress) copt="-dUseFlateCompression=true";
! 513: else copt="-dUseFlateCompression=false";
! 514:
! 515: if(res) sprintf(ropt,"-r%d",res);
! 516: else ropt[0]='\0';
! 517:
! 518: if(res && debug) printf(" (%d dpi) ... ",res);
! 519:
! 520: /* The shell 4nt has Problems with double quotes in the command line.
! 521: Thus use them only if it is really necessary (if there are space
! 522: characters in a filename)
! 523: */
! 524: if(strchr(outfile,' ') || strchr(tmpfile,' '))
! 525: sprintf(command,"%s -q -dNOPAUSE -dBATCH %s -sDEVICE=%s %s %s"
! 526: " \"-sOutputFile=%s\" -f \"%s\"",
! 527: gsexec,copt,device,ropt,gsopt,outfile,tmpfile);
! 528: else
! 529: sprintf(command,"%s -q -dNOPAUSE -dBATCH %s -sDEVICE=%s %s %s"
! 530: " -sOutputFile=%s -f %s",
! 531: gsexec,copt,device,ropt,gsopt,outfile,tmpfile);
! 532:
! 533:
! 534: if(debug) printf("running ghostscript ...\n");
! 535: if(debug) puts(command);
! 536: status=system(command);
! 537: if(!debug) remove(tmpfile);
! 538: else printf("keeping temporary file >>%s<<\n",tmpfile);
! 539: }
! 540:
! 541: if(!filter) printf("Done\n");
! 542:
! 543:
! 544:
! 545: EXIT:
! 546:
! 547: free(outfile);
! 548: free(tmpfile);
! 549: free(gsopt);
! 550:
! 551: if(wait){
! 552: printf("\n<Press a key> ");
! 553: getchar();
! 554: printf("\n");
! 555: }
! 556:
! 557: return status;
! 558: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>