Search:

Return to previous page

Contents of file 'epsbb/epsbb.c':



    1   /*-------------------------------------------------------------------------
    2   | File: epsbb.c [ANSI-C conforming source code]
    3   | Description: The epsbb program extracts the bounding box of files
    4   |              containing Encapsulated PostScript (EPS) images [1].
    5   |                 The output is a string of coordinates of the EPS bounding
    6   |              box, in the format "llx,lly,urx,ury", where (llx,lly) are
    7   |              the lower left coordinate and (urx,ury) the upper right
    8   |              coordinate, both given in pt (1/72 inch). The program
    9   |              is essentially just a self-consistent driver for the
   10   |              scan_for_boundingbox() routine that I wrote some years ago,
   11   |              and this is definitively one of the most compact and simple
   12   |              programs I have ever written. Nevertheless, I find it very
   13   |              useful in scripts and Makefiles, where I occasionally want
   14   |              to pipe the bounding box coordinate to other programs (such
   15   |              as MetaPost or TeX).
   16   |                 Notice that I have added the -w option, compared to the
   17   |              classical version of epsbb, in order to get a more readable
   18   |              output of the bounding box size in terms of millimetres.
   19   |              This option is nice to use when invoking epsbb from the command
   20   |              line (in order to conform to the classical behaviour, I have
   21   |              though kept the default output coordinates in pt whenever the
   22   |              program is invoked without any options).
   23   |
   24   | Created:     July 16, 2003
   25   | Last change: August 5, 2004 [Adding the -v option.]
   26   | Author: Fredrik Jonsson <hakkasberra@hotmail.com>
   27   |
   28   | Copyright (C) Fredrik Jonsson <hakkasberra@hotmail.com>
   29   |
   30   | Compile the source code using the following Makefile:
   31   |     ----------------------- CUT HERE -----------------------
   32   |     CC     = gcc
   33   |     CCOPTS = -O2 -Wall -ansi -pedantic
   34   |
   35   |     epsbb: epsbb.o
   36   |             $(CC) $(CCOPTS) -o epsbb epsbb.o
   37   |
   38   |     epsbb.o: epsbb.c
   39   |             $(CC) $(CCOPTS) -c epsbb.c
   40   |
   41   |     clean:
   42   |             -rm -Rf *~ *.o *.exe
   43   |     ----------------------- CUT HERE -----------------------
   44   |
   45   | [1] For information on the PostScript programming language,
   46   |     see for example the homepage of Adobe Systems Inc., at
   47   |     http://www.adobe.com/products/postscript/main.html,
   48   |     or "PostScript Language - Tutorial and Cookbook"
   49   |     (Addison-Wesley, Reading, Massachusetts, 1985), ISBN 0-201-10179-3.
   50   -------------------------------------------------------------------------*/
   51   #include <stdlib.h>
   52   #include <stdio.h>
   53   #include <string.h>
   54   #include <ctype.h>
   55   
   56   extern char *optarg;
   57   char *progname;
   58   
   59   /*-------------------------------------------------------------------------
   60   | The scan_for_boundingbox(infilename,llx,lly,urx,ury) routine takes the
   61   | name of a regular ASCII text file (infilename) containing Encapsulated
   62   | PostScript (EPS) as input, and returns the bounding box of the figure,
   63   | in terms of the corner coordinates given by llx, lly, urx, and ury.
   64   |
   65   | Input parameters:
   66   |    infilename  (type char[])  Filename of inut Encapsulated PostScript file
   67   |                               including possible path specification, and
   68   |                               not longer than 256 characters.
   69   |
   70   | Output parameters:
   71   |    llx         (type *int)    Lower left x-coordinate of bounding box.
   72   |    lly         (type *int)    Lower left y-coordinate of bounding box.
   73   |    urx         (type *int)    Upper right x-coordinate of bounding box.
   74   |    ury         (type *int)    Upper right y-coordinate of bounding box.
   75   |
   76   | Typical usage of this routine, in terms of a sample program for extraction
   77   | of bounding box, similar to the UNIX standard program psbb, is:
   78   |
   79   |     #include <stdlib.h>
   80   |     #include <stdio.h>
   81   |     #include <string.h>
   82   |
   83   |     extern char *optarg;
   84   |     char *progname;
   85   |
   86   |     void scan_for_boundingbox(char infilename[256],
   87   |        long int *llx,long int *lly,long int *urx,long int *ury)
   88   |     {
   89   |        ...
   90   |     }
   91   |
   92   |     int main(int argc,char *argv[])
   93   |     {
   94   |        char infilename[256];
   95   |        int no_arg;
   96   |        long int llx,lly,urx,ury;
   97   |
   98   |        progname=argv[0];
   99   |        no_arg=argc;
  100   |        if (argc<2) {
  101   |           fprintf(stderr,"%s: Error! Please specify input (EPS) filename.\n",
  102   |              progname);
  103   |           fprintf(stderr,"Usage: %s <filename>\n",progname);
  104   |           exit(1);
  105   |        }
  106   |        --argc;
  107   |        strcpy(infilename,argv[no_arg-argc]);
  108   |        scan_for_boundingbox(infilename,&llx,&lly,&urx,&ury);
  109   |        fprintf(stdout,"%ld %ld %ld %ld\n",llx,lly,urx,ury);
  110   |        exit(0);
  111   |     }
  112   |
  113   -------------------------------------------------------------------------*/
  114   void scan_for_boundingbox(char infilename[256],
  115      long int *llx,long int *lly,long int *urx,long int *ury)
  116   {
  117      short int done;
  118      char tmpstr[256];
  119      int tmpch;
  120      FILE *infile;
  121   
  122      if ((infile=fopen(infilename,"r"))==NULL) {
  123         fprintf(stderr,"%s: Error! Could not open file %s for reading.\n",
  124            progname,infilename);
  125         exit(1);
  126      }
  127      fseek(infile,0L,SEEK_SET);
  128      done=0;
  129      while (((tmpch=getc(infile))!=EOF)&&(!done)) {
  130         ungetc(tmpch,infile);
  131         fscanf(infile,"%s",tmpstr);
  132         if (!strcmp(tmpstr,"%%BoundingBox:")) {
  133            done=1;
  134            fscanf(infile,"%ld",llx);
  135            fscanf(infile,"%ld",lly);
  136            fscanf(infile,"%ld",urx);
  137            fscanf(infile,"%ld",ury);
  138         }
  139      }
  140      if (tmpch==EOF) {
  141         fprintf(stderr,"%s: Error! End of file reached without ",progname);
  142         fprintf(stderr,"finding any %%%%BoundingBox statement!\n");
  143         fprintf(stderr,"%s: (Does %s really contain ",progname,infilename);
  144         fprintf(stderr,"Encapsulated PostScript?)\n");
  145         exit(1);
  146      }
  147   }
  148   
  149   void showsomehelp(void) {
  150      fprintf(stdout,"Usage: %s <filename> [options]\n",progname);
  151      fprintf(stdout,"The %s program extracts the bounding box of the ",progname);
  152      fprintf(stdout,"Encapsulated PostScript\nfile <filename>, and writes ");
  153      fprintf(stdout,"the bounding box corners to standard terminal\n");
  154      fprintf(stdout,"output in of the form <llx> <lly> <urx> <ury> and in ");
  155      fprintf(stdout,"units of typographical\npoints. [1 pt = 1/72.27 in]\n");
  156      fprintf(stdout,"Options:\n");
  157      fprintf(stdout,"  -v      Toggle verbose mode. (default: off)\n");
  158      fprintf(stdout,"  -w      Print height and width of bounding box in\n");
  159      fprintf(stdout,"          millimetres, instead of just printing the\n");
  160      fprintf(stdout,"          coordinates of the corners in points.\n");
  161      fprintf(stdout,"Copyright (C) 2002-2005, Fredrik Jonsson ");
  162      fprintf(stdout,"<fj@physics.soton.ac.uk>\n");
  163   }
  164   
  165   /*---------------------------------------------------------------------
  166   | The pathcharacter() routine takes one character `ch` as argument,
  167   | and returns 1 ('true') if the character is valid character of a path
  168   | string, otherwise 0 ('false') is returned.
  169   ---------------------------------------------------------------------*/
  170   short pathcharacter(int ch) {
  171      return(isalnum(ch)||(ch=='.')||(ch=='/')||(ch=='\\')||(ch=='_')||
  172         (ch=='-')||(ch=='+'));
  173   }
  174   
  175   /*---------------------------------------------------------------------
  176   | The strip_away_path() routine takes a character string `filename` as
  177   | argument, and returns a pointer to the same string but without any
  178   | preceding path segments. This routine is, for example, useful for
  179   | removing paths from program names parsed from the command line.
  180   ---------------------------------------------------------------------*/
  181   char *strip_away_path(char filename[]) {
  182      int j,k=0;
  183      while (pathcharacter(filename[k])) k++;
  184      j=(--k); /* this is the uppermost index of the full path+file string */
  185      while (isalnum((int)(filename[j]))) j--;
  186      j++; /* this is the lowermost index of the stripped file name */
  187      return(&filename[j]);
  188   }
  189   
  190   int main(int argc,char *argv[])
  191   {
  192      char infilename[256];
  193      int no_arg;
  194      long int llx,lly,urx,ury;
  195      short view_width_height=0,verbose=0;
  196   
  197      /* Parse command line for input parameters */
  198      progname=strip_away_path(argv[0]); /* Strip from preceeding path string */
  199      no_arg=argc;
  200      if (argc<2) {
  201         fprintf(stderr,"%s: Please specify input (EPS) filename.\n",
  202            progname);
  203         showsomehelp();
  204         exit(1);
  205      }
  206      --argc;
  207      strcpy(infilename,argv[no_arg-argc]);
  208      while (--argc) {
  209         if(!strcmp(argv[no_arg-argc],"-w")) {
  210            view_width_height=(view_width_height?0:1);
  211         } else if(!strcmp(argv[no_arg-argc],"-v")) {
  212            verbose=(verbose?0:1);
  213         } else {
  214            fprintf(stderr,"%s: Invalid option %s.\n",progname,argv[no_arg-argc]);
  215            showsomehelp();
  216            exit(1);
  217         }
  218      }
  219   
  220      /* Scan the specified Encapsulated PostScript file for its bounding box */
  221      scan_for_boundingbox(infilename,&llx,&lly,&urx,&ury);
  222   
  223      /* Write the bounding box to standard terminal output */
  224      if (verbose) {
  225         fprintf(stdout,"Bounding box of Encapsulated PostScript image %s:\n",
  226   	      infilename);
  227      }
  228      if (view_width_height) {
  229         fprintf(stdout,"width=%-4.2f mm (%ld pt; %-4.2f in), ",
  230            (urx-llx)*(25.4/72.27),urx-llx,(urx-llx)*(1.0/72.27));
  231         fprintf(stdout,"height=%-4.2f mm (%ld pt; %-4.2f in)\n",
  232            (ury-lly)*(25.4/72.27),ury-lly,(ury-lly)*(1.0/72.27));
  233      } else {
  234         fprintf(stdout,"%ld %ld %ld %ld\n",llx,lly,urx,ury);
  235      }
  236      exit(0);
  237   }
  238   

Return to previous page

Generated by ::viewsrc::

Last modified Wednesday 15 Feb 2023