Introduce POLYGONHOLE_MODE for creating holes in polygons
[geda-pcb/gde.git] / doc / eps2png
blobc029991edbbdabd3341be523affb7c3ee259090d
1 #!/usr/bin/perl
3 my $RCS_Id = '$Id$ ';
5 # Author : Johan Vromans
6 # Created On : Tue Sep 15 15:59:04 1992
7 # Last Modified By: Johan Vromans
8 # Last Modified On: Sun Jun 24 17:07:29 2001
9 # Update Count : 155
10 # Status : Okay
12 ################ Common stuff ################
14 use strict;
15 use Getopt::Long 2.1;
17 my $my_package = "Sciurix";
18 my ($my_name, $my_version) = $RCS_Id =~ /: (.+).pl,v ([\d.]+)/;
19 $my_version .= '*' if length('$Locker$ ') > 12;
21 use vars qw($VERSION);
22 ( $VERSION ) = '$Revision$ ' =~ /\$Revision:\s+([^\s]+)/;
24 ################ Program parameters ################
26 ### CONFIG
27 # Some GhostScript programs can produce GIF directly.
28 # If not, we need the PBM package for the conversion.
29 my $use_pbm = 1; # GhostScript can not produce GIF
30 ### END CONFIG
32 my $res = 82; # default resolution
33 my $scale = 1; # default scaling
34 my $mono = 0; # produce BW images if non-zero
35 my $format; # output format
36 my $gs_format; # GS output type
37 my $output; # output, defaults to STDOUT
38 my $antialias = 4; # antialiasing
39 my $width; # desired widht
40 my $height; # desired height
42 my ($verbose,$trace,$test,$debug) = (0,0,0,0);
43 handle_options ();
44 unless ( defined $format ) {
45 if ( $0 =~ /2(gif|jpg|png)$/ ) {
46 set_out_type ($1);
48 else {
49 set_out_type ('png') unless defined $format;
52 print STDERR ("Producing $format ($gs_format) image.\n") if $verbose;
54 $trace |= $test | $debug;
55 $verbose |= $trace;
57 ################ Presets ################
59 ################ The Process ################
61 my $eps_file;
62 my $err = 0;
64 foreach $eps_file ( @ARGV ) {
66 unless ( open (EPS, $eps_file) ) {
67 print STDERR ("Cannot open $eps_file [$!], skipped\n");
68 $err++;
69 next;
72 my $line = <EPS>;
73 unless ( $line =~ /^%!PS-Adobe.*EPSF-/ ) {
74 print STDERR ("Not EPS file: $eps_file, skipped\n");
75 $err++;
76 next;
79 my $ps = ""; # PostScript input data
80 my $xscale;
81 my $yscale;
83 while ( $line = <EPS> ) {
85 # Search for BoundingBox.
86 if ( $line =~ /^%%BoundingBox:\s*(\S+)\s+(\S+)\s+(\S+)\s+(\S+)/i ) {
88 print STDERR ("$eps_file: x0=$1, y0=$2, w=", $3-$1, ", h=", $4-$2)
89 if $verbose;
91 if ( defined $width ) {
92 $res = 72;
93 $xscale = $width / ($3 - $1);
94 if ( defined $height ) {
95 $yscale = $height / ($4 - $2);
97 else {
98 $yscale = $xscale;
99 $height = ($4 - $2) * $yscale;
102 elsif ( defined $height ) {
103 $res = 72;
104 $yscale = $height / ($4 - $2);
105 if ( defined $width ) {
106 $xscale = $width / ($3 - $1);
108 else {
109 $xscale = $yscale;
110 $width = ($3 - $1) * $xscale;
113 unless ( defined $xscale ) {
114 $xscale = $yscale = $scale;
115 # Calculate actual width.
116 $width = $3 - $1;
117 $height = $4 - $2;
118 # Normal PostScript resolution is 72.
119 $width *= $res/72 * $xscale;
120 $height *= $res/72 * $yscale;
121 # Round up.
122 $width = int ($width + 0.5) + 1;
123 $height = int ($height + 0.5) + 1;
125 print STDERR (", width=$width, height=$height\n") if $verbose;
127 # Scale.
128 $ps .= "$xscale $yscale scale\n"
129 if $xscale != 1 || $yscale != 1;
131 # Create PostScript code to translate coordinates.
132 $ps .= (0-$1) . " " . (0-$2) . " translate\n"
133 unless $1 == 0 && $2 == 0;
135 # Include the image, show and quit.
136 $ps .= "($eps_file) run\n".
137 "showpage\n".
138 "quit\n";
140 last;
142 elsif ( $line =~ /^%%EndComments/i ) {
143 print STDERR ("No bounding box in $eps_file\n");
144 $err++;
145 last;
148 close (EPS);
150 my $out_file; # output file
151 my $pbm_file; # temporary file for PBM conversion
153 # Note the temporary PBM file is created where the output file is
154 # located, since that will guarantee accessibility (and a valid
155 # filename).
156 if ( defined $output ) {
157 $out_file = $output;
158 $pbm_file = $output.".ppm";
160 elsif ( $eps_file =~ /^(.+).epsf?$/i ) {
161 $out_file = "$1.$format";
162 $pbm_file = $1.".ppm";
164 else {
165 $out_file = $eps_file . ".$format";
166 $pbm_file = $eps_file . ".ppm";
168 print STDERR ("Creating $out_file\n") if $verbose;
170 my $gs0 = "gs -q -dNOPAUSE -r$res -g${width}x$height";
171 my $gs1 = "-";
172 $gs0 .= " -dTextAlphaBits=$antialias -dGraphicsAlphaBits=$antialias"
173 if $antialias;
174 if ( $format eq 'png' ) {
175 mysystem ("$gs0 -sDEVICE=". ($mono ? "pngmono" : $gs_format).
176 " -sOutputFile=$out_file $gs1", $ps);
178 elsif ( $format eq 'jpg' ) {
179 mysystem ("$gs0 -sDEVICE=". ($mono ? "jpeggray" : $gs_format).
180 " -sOutputFile=$out_file $gs1", $ps);
182 elsif ( $format eq 'gif' ) {
183 if ( $use_pbm ) {
184 # Convert to PPM and use some of the PBM converters.
185 mysystem ("$gs0 -sDEVICE=". ($mono ? "pbm" : "ppm").
186 " -sOutputFile=$pbm_file $gs1", $ps);
187 # mysystem ("pnmcrop $pbm_file | ppmtogif > $out_file");
188 mysystem ("ppmtogif $pbm_file > $out_file");
189 unlink ($pbm_file);
191 else {
192 # GhostScript has GIF drivers built-in.
193 mysystem ("$gs0 -sDEVICE=". ($mono ? "gifmono" : "gif8").
194 " -sOutputFile=$out_file $gs1", $ps);
197 else {
198 print STDERR ("ASSERT ERROR: Unhandled output type: $format\n");
199 exit (1);
202 unless ( -s $out_file ) {
203 print STDERR ("Problem creating $out_file for $eps_file\n");
204 $err++;
209 exit 1 if $err;
211 ################ Subroutines ################
213 sub mysystem {
214 my ($cmd, $data) = @_;
215 print STDERR ("+ $cmd\n") if $trace;
216 if ( $data ) {
217 if ( $trace ) {
218 my $dp = ">> " . $data;
219 $dp =~ s/\n(.)/\n>> $1/g;
220 print STDERR ("$dp");
222 open (CMD, "|$cmd") or die ("cmd: $!\n");
223 print CMD $data;
224 close CMD or die ("cmd close: $!\n");
226 else {
227 system ($cmd);
231 sub set_out_type {
232 my ($opt) = lc (shift (@_));
233 if ( $opt =~ /^png(mono|gray|16|256|16m)?$/ ) {
234 $format = 'png';
235 $gs_format = $format.(defined $1 ? $1 : '16m');
237 elsif ( $opt =~ /^gif(mono)?$/ ) {
238 $format = 'gif';
239 $gs_format = $format.(defined $1 ? $1 : '');
241 elsif ( $opt =~ /^(jpg|jpeg)(gray)?$/ ) {
242 $format = 'jpg';
243 $gs_format = 'jpeg'.(defined $2 ? $2 : '');
245 else {
246 print STDERR ("ASSERT ERROR: Invalid value to set_out_type: $opt\n");
247 exit (1);
251 sub handle_options {
252 my ($help) = 0; # handled locally
253 my ($ident) = 0; # handled locally
255 # Process options.
256 if ( @ARGV > 0 && $ARGV[0] =~ /^[-+]/ ) {
257 usage ()
258 unless GetOptions ('ident' => \$ident,
259 'verbose' => \$verbose,
260 'antialias|aa=i' => \$antialias,
261 'noantialias|noaa' => sub { $antialias = 0 },
262 'scale=f' => \$scale,
263 'width=i' => \$width,
264 'height=i' => \$height,
265 'output=s' => \$output,
266 'png' => \&set_out_type,
267 'pngmono' => \&set_out_type,
268 'pnggray' => \&set_out_type,
269 'png16' => \&set_out_type,
270 'png256' => \&set_out_type,
271 'png16m' => \&set_out_type,
272 'jpg' => \&set_out_type,
273 'jpggray' => \&set_out_type,
274 'jpeg' => \&set_out_type,
275 'jpeggray' => \&set_out_type,
276 'gif' => \&set_out_type,
277 'gifmono' => \&set_out_type,
278 'mono!' => \$mono,
279 'resolution=i' => \$res,
280 'pbm!' => \$use_pbm,
281 'trace' => \$trace,
282 'help' => \$help,
283 'debug' => \$debug)
284 && !$help;
286 print STDERR ("This is $my_package [$my_name $my_version]\n")
287 if $ident;
288 die ("Only one file argument is allowed when -output is used\n")
289 if @ARGV > 1 && defined $output;
290 die ("At least one input file name must be specified\n")
291 unless @ARGV;
292 die ("Antialias value must be 0, 1, 2, 4, or 8\n")
293 unless "$antialias" =~ /^[01248]$/;
296 sub usage {
297 print STDERR <<EndOfUsage;
298 This is $my_package [$my_name $my_version]
299 Usage: $0 [options] file [...]
301 -png -pngmono -pnggray -png16 -png256 -png16m
302 produce PNG image
303 -jpg -jpggray -jpeg -jpeggray
304 produce JPG image
305 -gif -gifmono produce GIF image
306 -[no]mono monochrome/colour rendition
307 -width XXX desired with
308 -height XXX desired height
309 -resolution XXX resolution (default = $res)
310 -scale XXX scaling factor
311 -antialias XX antialias factor (must be 0, 1, 2, 4 or 8; default: 4)
312 -noantialias no antialiasing (same as -antialias 0)
313 -[no]pbm GIF only: [do not] convert via pbm format
314 -output XXX output to this file (only one input file)
315 -help this message
316 -ident show identification
317 -verbose verbose information
318 EndOfUsage
319 exit 1;
322 # For install testing
325 __END__
327 =pod
329 =head1 NAME
331 epf2png - convert EPS files to PNG, JPG or GIF images
333 =head1 SYNOPSIS
335 eps2png [ options ] files ...
336 eps2gif [ options ] files ...
337 eps2jpg [ options ] files ...
339 =head1 DESCRIPTION
341 Converts files from EPS format (Encapsulated PostScript) to some
342 popular image formats.
344 If installed as C<eps2png> (the default), it produces PNG images by
345 default. Likewise, C<eps2gif> defaults to GIF images and C<eps2jpg>
346 defaults to JPG. Note that the normal installation procedure will
347 I<only> install C<eps2png>.
349 It uses GhostScript to produce the images. Since modern GhostScript
350 programs do not support GIF anymore, GIF images are produced via the
351 Portable PixMap converters (PBM-package). In this case, a temporary
352 file is created, named after the output file, with the extension
353 replaced by ".ppm". It is deleted upon completion.
355 =head1 ARGUMENTS
357 B<eps2png> always requires at least one argument: the name of the EPS
358 file to be converted. It is possible to specify more than one file
359 name. This will cause all named files to be converted into separate
360 files, e.g., "C<sample.eps>" will be converted to "C<sample.png>" and
361 so on.
363 =over 4
365 =item B<-png -pngmono -pnggray -png16 -png256 -png16m>
367 Each of these options will instruct Ghostscript to use the
368 corresponding bitmap generator, and supply a C<.png> default
369 extension for output files.
371 =item B<-jpg -jpggray -jpeg -jpeggray>
373 Same, but with a C<.jpg> default extension for output files.
375 =item B<-gif -gifmono>
377 Same, but with a C<.gif> default extension for output files.
379 Note: Since modern Ghostscript versions no longer support the GIF
380 format due to copyright restrictions, B<eps2png> will request
381 Ghostscript to produce a Portable Bitmap File (.ppm or .pbm) instead
382 and run the B<ppmtogif> converter to produce the actual GIF file.
384 =item B<-mono>
386 This option will select monochrome (BW or gray) output. It forces the
387 Ghostscript driver to C<pngmono>, C<jpeggray>, C<pbm>, or C<gifmono>.
389 =item B<-nomono>
391 Produces colour images. This is the default.
393 =item B<-width> I<NN>
395 The desired width of the output image.
397 If B<-height> is not specified, the image will be scaled proportionally.
399 =item B<-height> I<NN>
401 The desired height of the output image.
403 If B<-width> is not specified, the image will be scaled proportionally.
405 =item B<-resolution> I<NN>
407 Specifies the resolution for the output image. This is the width, in
408 pixels, of the bitmap image for an EPS image of one inch wide (72
409 PostScript points).
411 Note that for best results, use the B<-width> and B<-height> options
412 instead.
414 Default value is 82, which causes the converted image to be of more
415 or less the same size as the EPS image. On my screen, that is.
417 =item B<-scale> I<NN>
419 Specify a scaling factor. This may be a fractional number.
421 For a one-inch EPS image, the resultant bitmap image will be
422 I<scale> times I<resolution>.
424 Note that for best results, use the B<-width> and B<-height> options
425 instead.
427 =item B<-antialias> I<NN>
429 Sets the antialiasing depth. I<NN> must be 0 (no antialiasing), 1, 2,
430 4, or 8. Default value is 4.
432 =item B<-noantialias>
434 Sets the antialiasing depth to 0.
436 =item B<-pbm>
438 Forces GIF conversion through the PBM converters.
440 =item B<-nopbm>
442 Forces GIF conversion through Ghostscript.
444 =item B<-output> I<XXX>
446 Stores the output in this file. Only one input file may be supplied if
447 this option is specified.
449 =item B<-help>
451 Prints a help message and exits.
453 =item B<-ident>
455 Prints the program version before doing anything else.
457 =item B<-verbose>
459 Provides more verbose information.
461 =back
463 =head1 AUTHOR
465 Johan Vromans, <jvromans@squirrel.nl>.
467 =head1 BUGS
469 GhostScript and, if required, the PBM package, need to be installed and
470 accessible through the user's C<PATH>.
472 GhostScript is assumed to be capable of handling all the image types
473 listed above.
475 The EPS should be well-behaving.
477 =head1 COPYRIGHT AND DISCLAIMER
479 This program is Copyright 1994,2001 by Johan Vromans.
480 This program is free software; you can redistribute it and/or
481 modify it under the terms of the Perl Artistic License or the
482 GNU General Public License as published by the Free Software
483 Foundation; either version 2 of the License, or (at your option) any
484 later version.
486 This program is distributed in the hope that it will be useful,
487 but WITHOUT ANY WARRANTY; without even the implied warranty of
488 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
489 GNU General Public License for more details.
491 If you do not have a copy of the GNU General Public License write to
492 the Free Software Foundation, Inc., 675 Mass Ave, Cambridge,
493 MA 02139, USA.
495 =cut