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
Generated by ::viewsrc::