File:  [Local Repository] / ratfiv / epstopdf.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Fri Jun 15 16:14:55 2001 UTC (23 years ago) by brouard
Branches: ratfiv, MAIN
CVS tags: ratfiv-103, HEAD
Created Directory Structure

    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>