/[MITgcm]/manual/pstoimg
ViewVC logotype

Contents of /manual/pstoimg

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.1 - (show annotations) (download)
Fri Jul 15 13:07:23 2005 UTC (18 years, 9 months ago) by cnh
Branch: MAIN
More cunning tricks to get rid of black lines
 pnmcrop is junk!

1 #! /usr/bin/perl -w
2 ##############################################################################
3 # $Id: pstoimg.pin,v 1.16 2001/10/25 10:16:12 RRM Exp $
4 #
5 # pstoimg
6 #
7 # Accompanies LaTeX2HTML
8 #
9 # Script to convert an arbitrary PostScript image to a cropped GIF or PNG
10 # image suitable for incorporation into HTML documents as inlined images
11 # to be viewed with WWW browsers.
12 #
13 # This software is provided as is without any guarantee.
14 #
15 ##############################################################################
16 #
17 # $Log: pstoimg.pin,v $
18 # Revision 1.16 2001/10/25 10:16:12 RRM
19 # -- make sure that $PNMCROPOPT is declared before -sides
20 #
21 # Revision 1.15 2001/08/21 10:48:59 RRM
22 # -- corrects errors in implementing $PNMCROPOPT
23 #
24 # Revision 1.14 2001/08/20 08:51:20 RRM
25 # -- implement -sides for the arguments to $PNMCROP
26 # This is needed for v9.12+ of pnmcrop .
27 # -- when shaving fails, don't try to copy or rename
28 #
29 # Revision 1.13 2001/03/27 09:27:38 RRM
30 # -- inserted missing '$' for $edge .
31 #
32 # Revision 1.12 2001/03/25 02:05:14 RRM
33 # -- implement the temporary hack to pnmcrop, using -black to help detect
34 # the correct color for cropping-bars; only workd with black bars.
35 # A complete fix will be available with Netpbm v9.12 .
36 #
37 # Revision 1.11 1999/10/25 21:18:22 MRO
38 #
39 # -- added more configure options (Jens' suggestions)
40 # -- fixed bug in regexp range reported by Achim Haertel
41 # -- fixed old references in documentation (related to mail list/archive)
42 #
43 # Revision 1.10 1999/10/06 22:04:13 MRO
44 #
45 # -- texexpand: latex2html calls texexpand with the -out option instead of
46 # output redirection: this is safer on non-UNIX platforms
47 # -- pstoimg: now there's no default cropping (useful for standalone
48 # conversions). latex2html was changes appropriately
49 # -- minor cleanups in latex2html script and documentation
50 #
51 # Revision 1.9 1999/09/14 22:02:02 MRO
52 #
53 # -- numerous cleanups, no new features
54 #
55 # Revision 1.8 1999/07/19 09:51:00 RRM
56 # -- added -aaliastext switch, for easier way to specify anti-aliased
57 # font characters, without also anti-aliasing other graphics objects.
58 #
59 # Revision 1.7 1999/06/24 07:28:59 MRO
60 #
61 #
62 # -- removed L2HMODULE
63 # -- fixed processing of -info switch
64 # -- changed option order for dvips on win32 (thanks JCL)
65 # -- bumped version to 99.2a8
66 #
67 # Revision 1.6 1999/06/06 14:24:50 MRO
68 #
69 #
70 # -- many cleanups wrt. to TeXlive
71 # -- changed $* to /m as far as possible. $* is deprecated in perl5, all
72 # occurrences should be removed.
73 #
74 # Revision 1.5 1999/06/04 20:14:25 MRO
75 #
76 #
77 # -- Reworked option parsing completely. Should behave much the same as before,
78 # options with -no_* work just like before.
79 # -- Changed $NOFORK to $CAN_FORK and inverted the logic.
80 # -- Small debugging enhancement in pstoimg
81 #
82 # Revision 1.4 1999/06/04 15:30:15 MRO
83 #
84 #
85 # -- fixed errors introduced by cleaning up TMP*
86 # -- made pstoimg -quiet really quiet
87 # -- pstoimg -debug now saves intermediate result files
88 # -- several fixes for OS/2
89 #
90 # Revision 1.3 1999/06/01 06:55:35 MRO
91 #
92 #
93 # - fixed small bug in L2hos/*
94 # - added some test_mode related output to latex2html
95 # - improved documentation
96 # - fixed small bug in pstoimg wrt. OS2
97 #
98 # Revision 1.2 1999/05/17 21:30:59 MRO
99 #
100 #
101 # -- make texexpand warning-free and start making it use strict
102 # compliant
103 #
104 # Revision 1.1 1999/05/11 06:10:00 MRO
105 #
106 #
107 # - merged config stuff, did first tries on Linux. Simple document
108 # passes! More test required, have to ger rid of Warnings in texexpand
109 #
110 # Revision 1.18 1999/05/05 19:47:03 MRO
111 #
112 #
113 # - many cosmetic changes
114 # - final backup before merge
115 #
116 # Revision 1.17 1999/03/15 23:00:53 MRO
117 #
118 #
119 # - moved L2hos modules to top level directory, so that no dir-
120 # delimiter is necessary in the @INC-statement.
121 # - changed strategy for "shave": Do not rely on STDERR redirection any
122 # more (caused problems on at least Win32)
123 #
124 # Revision 1.16 1999/02/14 23:44:34 MRO
125 #
126 #
127 # -- first attempt to fix Win32 problems
128 #
129 # Revision 1.15 1999/02/11 00:18:29 MRO
130 #
131 #
132 # -- cleaned up warppers, TeXlive stuff and Makefile
133 #
134 # Revision 1.14 1999/02/10 01:37:12 MRO
135 #
136 #
137 # -- changed os-dependency structure again - now neat OO modules are
138 # used: portable, extensible, neat!
139 # -- some minor cleanups and bugfixes
140 #
141 # Revision 1.13 1998/12/07 23:19:58 MRO
142 #
143 #
144 # -- added POD documentation to pstoimg and did a general cleanup
145 # -- some finetuning of config procedure and modules
146 #
147 # Revision 1.12 1998/10/31 14:13:05 MRO
148 # -- changed OS-dependent module loading strategy: Modules are now located in
149 # different (OS-specific) directories nut have the same name: Easier to
150 # maintain and cleaner code
151 # -- Cleaned up config procedure
152 # -- Extended makefile functionality
153 #
154 # Revision 1.11 1998/08/09 20:45:20 MRO
155 # -- some cleanup
156 #
157 # Revision 1.10 1998/06/14 14:10:38 latex2html
158 # -- Started to implement TeXlive configuration and better OS specific
159 # handling (Batch files) (Marek)
160 #
161 # Revision 1.9 1998/06/07 22:35:24 latex2html
162 # -- included things I learned from the Win95 port to config procedure:
163 # GS_LIB, Win32 module calls, directory separator stuff, ... (Marek)
164 #
165 # Revision 1.8 1998/06/01 12:57:56 latex2html
166 # -- Cleanup and cosmetics.
167 #
168 # Revision 1.7 1998/05/14 22:27:37 latex2html
169 # -- more work on config procedure (Makefile, GS_LIB)
170 # -- tested pstoimg in 98.1 environment successfully on Linux
171 #
172 # Revision 1.6 1998/05/06 22:31:09 latex2html
173 # -- Enhancements to the config procedure: Added a "generic" target
174 # in the Makefile for the TeXlive CD (not perfect yet)
175 # -- included test for kpsewhich / Web2C
176 # -- included latest stuff from Override.pm into os_*.pm
177 #
178 # Revision 1.5 1998/04/28 22:18:11 latex2html
179 # - The platform specific stuff is now kept in a separate perl module. This
180 # does not introduce significant overhead and enhances maintainability.
181 #
182 # Revision 1.4 1998/03/19 23:38:06 latex2html
183 # -- made pstoimg plug-in compatible with old one (touchwood!)
184 # -- cleaned up, added some comments
185 # -- inserted version information output
186 # -- incorporated patches to make OS/2 run better (thanks Uli)
187 # -- updated Makefile: make, make test, make install should work now
188 #
189 # Revision 1.3 1998/03/11 23:44:00 latex2html
190 # -- cleaned up config.pl and reworked dvips checks
191 # -- got pstoimg.pin up to par with the regular pstoimg
192 # -- cosmetic changes
193 # -- runs now under Win95 with Fabrice Popineau's Win32 tools (gs, TeX,...)
194 #
195 # Revision 1.2 1998/03/02 23:38:40 latex2html
196 # Reworked configuration procedure substantially. Fixed some killing bugs.
197 # Should now run on Win32, too.
198 # The file prefs.pm contains user-configurable stuff for DOS platforms.
199 # UNIX users can override the settings with the configure utility (preferred).
200 #
201 # Revision 1.1 1998/02/14 19:31:55 latex2html
202 # Preliminary checkin of configuration procedure
203 #
204 # (end CVS log)
205 ###############################################################################
206
207 # This file has been automatically generated by build.pl from pstoimg.pin
208 # Do not edit this file as your changes will be lost when reconfiguring.
209 # If you want to supply patches, please apply them to pstoimg.pin and send
210 # the diff relative to the original pstoimg.pin. Thank you.
211
212 =head1 NAME
213
214 pstoimg - Convert a PostScript file to a bitmap image using
215 Ghostscript and the Netpbm utilities
216
217 =cut
218
219 use 5.003;
220 use strict;
221 #use diagnostics;
222 use vars qw(*SAVEERR $LATEX2HTMLDIR $SCRIPT);
223
224 # This variable points to the DIRECTORY where the latex2html files
225 # can be found.
226
227 use Getopt::Long;
228
229
230 # see below for a description of the environment
231
232 BEGIN {
233 # print "scanning for l2hdir\n";
234 if($ENV{LATEX2HTMLDIR}) {
235 $LATEX2HTMLDIR = $ENV{LATEX2HTMLDIR};
236 } else {
237 $ENV{LATEX2HTMLDIR} = $LATEX2HTMLDIR = '/usr/share/latex2html';
238 }
239
240 if(-d $LATEX2HTMLDIR) {
241 push(@INC,$LATEX2HTMLDIR);
242 } else {
243 die qq{Fatal: Directory "$LATEX2HTMLDIR" does not exist.\n};
244 }
245 }
246
247 use L2hos; # load OS-specific stuff
248
249 my $RELEASE = '2002-2-1';
250 my ($VERSION) = q$Revision: 1.16 $ =~ /:\s*(\S+)/;
251
252 $| = 1; # unbuffer STDOUT
253
254 my $dd = L2hos->dd; # Directory delimiter
255 my $prompt;
256 ($prompt = $0) =~ s|^.*[/\\]||;
257
258 # Configuration as determined by "configure"
259 #
260 # Ghostscript
261 my $GS = '/usr/bin/gs';
262 my $GSDEVICE = 'pnmraw';
263 my $GSALIASDEVICE = 'ppmraw';
264 # Supported format(s)
265 my @IMAGE_TYPES = qw(png gif);
266 # Netpbm
267 my $PNMCROP = '/home/cnh/downloads/netpbm-10.19bin/bin/pnmcrop -verbose';
268 # my $PNMCROP = '/bin/cat';
269 my $PNMCROPOPT = '';
270 # $PNMCROPOPT = '-sides';
271 # $PNMCROPOPT = '-white';
272 $PNMCROPOPT = '-black';
273 my $PPMQUANT = '/home/cnh/downloads/netpbm-10.19bin/bin/ppmquant';
274 my $PNMFLIP = '/home/cnh/downloads/netpbm-10.19bin/bin/pnmflip';
275 my $PNMCAT = '/home/cnh/downloads/netpbm-10.19bin/bin/pnmcat';
276 my $PNMFILE = '/home/cnh/downloads/netpbm-10.19bin/bin/pnmfile';
277 my $PBMMAKE = '/home/cnh/downloads/netpbm-10.19bin/bin/pbmmake';
278 # GIF support
279 my $PPMTOGIF = '/home/cnh/downloads/netpbm-10.19bin/bin/ppmtogif';
280 # PNG support
281 my $PNMTOPNG = '/home/cnh/downloads/netpbm-10.19bin/bin/pnmtopng';
282 # Temporary diskspace
283 my $def_tmp = '/tmp'; # Space for temporary files
284
285 # Some lengths used by dvips
286 # MRO: Is this true for all runs of dvips?
287
288 my $PAGE_HEIGHT = 841.889; # dvips page height, in pts.
289 my $PAGE_WIDTH = 595.275; # dvips page width, in pts.
290 my $PAGE_HMARGIN = 72; # dvips margin: 1 inch = 72pt
291 my $PAGE_VMARGIN = 72; # dvips margin: 1 inch = 72pt
292
293 # The color to be made transparent
294 # my $trans_color = '#ffffff';
295 my $trans_color = '#000000';
296
297 ###############################################################################
298 # Default settings
299 # Environment overrides defaults, command line options override everything
300
301 unless(@ARGV) {
302 print_help();
303 exit 0;
304 }
305
306 =head1 SYNOPSIS
307
308 B<pstoimg> B<-help> | B<-version>
309
310 B<pstoimg>
311 S<[ B<-antialias> ]>
312 S<[ B<-aaliastext> ]>
313 S<[ B<-center> I<num> ]>
314 S<[ B<-color> I<num> ]>
315 S<[ B<-crop> I<code> ]>
316 S<[ B<-debug> ]>
317 S<[ B<-density> I<num>]>
318 S<[ B<-depth> I<num> ]>
319 S<[ B<-discard> ]>
320 S<[ B<-flip> I<code> ]>
321 S<[ B<-geometry> I<X>xI<Y> ]>
322 S<[ B<-interlaced> ]>
323 S<[ B<-margins> I<X>,I<Y> ]>
324 S<[ B<-multipage> ]>
325 S<[ B<-out> I<file> ]>
326 S<[ B<-quiet> ]>
327 S<[ B<-rightjustify> I<num> ]>
328 S<[ B<-scale> I<num> ]>
329 S<[ B<-tmp> I<path> ]>
330 S<[ B<-topjustify> [B<x>]I<num> ]>
331 S<[ B<-transparent> ]>
332 S<[ B<-type> I<type> ]>
333 S<[ B<-shoreup> I<num>[B<d>] ]>
334 S<[ B<-white> ]>
335 I<file>
336 S<[ I<file2> ... ]>
337
338 =cut
339
340 my %opt = ();
341 unless(&GetOptions(\%opt, qw(-help -version -debug -discard -antialias -aaliastext
342 -multipage -type=s -gif -png -out=s -depth=i -color=i -flip=s -density=i
343 -scale=f -geometry=s -margins=s -crop=s -transparent -interlaced
344 -rightjustify=i -center=i -topjustify=s -shoreup=s -tmp=s -white -quiet))) {
345 print_usage("$prompt: Error: Invalid option(s) specified.");
346 exit 1;
347 }
348
349 =head1 OPTIONS
350
351 The command line options may be abbreviated to the shortest unique
352 prefix.
353
354 =over 4
355
356 =item B<-help>
357
358 Show this help page and exit.
359
360 =cut
361
362 if($opt{help}) {
363 print_help();
364 exit 0;
365 }
366
367 =item B<-version>
368
369 Show the release and version of pstoimg and exit.
370
371 =cut
372
373 if($opt{version}) {
374 print_version();
375 exit 0;
376 }
377
378 banner() unless($opt{quiet});
379
380 =item B<-antialias>
381
382 Use Ghostscript's anti-aliasing feature for rendering "softer" images.
383 This applies to lines and edges of polygonal and oval or circular shapes.
384 Only valid if Ghostscipt 4.03 or higher is installed.
385
386 =item B<-aaliastext>
387
388 Use Ghostscript's anti-aliasing feature for "smoother" font characters,
389 without the jagged edges. Similar to B<-antialias> for graphic components.
390 Only valid if Ghostscipt 4.03 or higher is installed.
391
392 =item B<-center> I<num>
393
394 Add the appropriate amount of whitespace to the left of the image so
395 that the image appears to be centered in a total width of I<num> pixels.
396
397 =cut
398
399 my $CENTER = 0; # No centering by default
400 if($opt{center}) {
401 $CENTER = $opt{center};
402 die <<"EOF" unless ($CENTER =~ /^\d+$/ && $CENTER > 0);
403 $prompt: Error: Illegal width for -center specified: "$CENTER"
404 Value must be a positive integer.
405 EOF
406 }
407
408 =item B<-crop> I<code>
409
410 Crop the bitmap from the given directions. I<code> may be a string of
411 several cropping instructions, which are executed strictly in the given
412 order. Possible values are: B<h> (horizontal, i.e. crop top and
413 bottom), B<v> (vertical), B<tblr> (top, bottom, left, right) and B<a> (all
414 directions). A special case is B<s>: "shave" the image at the bottom, but only
415 if a single line of whitespace exists.
416
417 =cut
418
419 my $EXTRA_CROP = '';
420 if($opt{crop}) {
421 $EXTRA_CROP = lc($opt{crop});
422 die <<"EOF" unless ( $EXTRA_CROP =~ /^([vhtblras]+)$/i );
423 $prompt: Error: Illegal crop specified: "$EXTRA_CROP"
424 Crop must be h, v, t, b, l, r, a, s or combination
425 EOF
426 }
427
428 =item B<-debug>
429
430 Turn on debugging output. This can get rather verbose. Any intermediate
431 files generated are not removed to help debugging.
432
433 =cut
434
435 if($ENV{DEBUG}) {
436 $opt{debug} = 1;
437 }
438
439 =item B<-density> I<num>
440
441 The density (resolution) in DPI in which to render the bitmap. The default
442 is 72.
443
444 =cut
445
446 my $DENSITY = 72;
447 if($opt{density}) {
448 $DENSITY = $opt{density};
449 }
450 elsif($ENV{DENSITY}) {
451 $DENSITY = $ENV{DENSITY};
452 }
453 die <<"EOF" unless $DENSITY =~ /^\d+$/;
454 $prompt: Error: Illegal density specified: "$DENSITY"
455 Density must be an integer value. Default is 72.
456 EOF
457
458 =item B<-depth> I<num> or B<-color> I<num>
459
460 Specify the color depth of the bitmap. Legal values are 1 (black & white),
461 8 (256 colors) and 24 (true color).
462
463 =cut
464
465 unless($opt{depth}) {
466 if($opt{color}) {
467 $opt{depth} = $opt{color};
468 }
469 elsif($ENV{DEPTH}) {
470 $opt{depth} = $ENV{DEPTH};
471 }
472 else {
473 $opt{depth} = 8;
474 }
475 }
476 die <<"EOF" unless $opt{depth} =~ /^(1|8|24)$/;
477 $prompt: Error: Illegal color depth specified: "$opt{depth}"
478 Depth must be either 1, 8 or 24.
479 EOF
480
481 =item B<-discard>
482
483 Delete the input postscript file if the conversion was successful. Setting
484 the environment DISCARD to a true value (as perl sees it) has the same
485 effect.
486
487 =cut
488
489 if($ENV{DISCARD}) {
490 $opt{discard} = 1;
491 }
492
493 =item B<-flip> I<code>
494
495 Flip all generated output bitmaps. The following codes are recognized:
496 lr (flip left-right), tb (flip top-bottom), xy (flip bottom/left-top/right),
497 r90 and ccw (rotate by 90 degrees counterclockwise), r270 and cw (rotate
498 90 degrees clockwise) and r180 (rotate 180 degrees).
499
500 =cut
501
502 if($opt{flip}) {
503 $opt{flip} = lc($opt{flip});
504 die <<"EOF" unless $opt{flip} =~ /^(lr|tb|xy|r90|ccw|r270|cw|r180)$/;
505 $prompt: Error: Illegal flip option specified: "$opt{flip}"
506 Flip must be one of: lr tb xy r90 ccw r270 cw r180
507 EOF
508 }
509
510 =item B<-geometry> I<X>xI<Y>
511
512 Render only this "window" of the PostScript file. If given, this option
513 can dramatically reduce memory requirements and speed up conversion. The
514 geometry is automatically detected in case of EPS files (Encapsulated
515 PostScript).
516
517 =cut
518
519 my $GEOMETRY = '';
520 if($opt{geometry}) {
521 $GEOMETRY = $opt{geometry};
522 if($GEOMETRY =~ s/-//o ) {
523 $EXTRA_CROP .= 'bl';
524 }
525 die <<"EOF" unless ($GEOMETRY =~ /^\d+x\d+$/i);
526 $prompt: Error: Illegal geometry specified: "$GEOMETRY"
527 Geometry must be <width>x<height>
528 EOF
529 }
530
531 =item B<-interlaced>
532
533 Generate an interlaced bitmap. Interlaced images build up from coarse to
534 fine as they are loaded. This option may not work on every installation
535 and/or bitmap type, depending of the capabilities of external programs.
536
537 =cut
538
539 my $INTERLACE = 0; # Do not make interlaced images by default
540 if($opt{interlaced}) {
541 $INTERLACE=1;
542 }
543
544 =item B<-margins> I<X>,I<Y>
545
546 The offset of the rectangle in the postscript file that is going to be
547 rendered from top/left. Can be used together with B<-geometry> to further
548 reduce the size of the intermediate bitmap file generated by Ghostscript.
549
550 =cut
551
552 if($opt{margins}) {
553 die <<"EOF" unless (($opt{margins} =~ /^(\d+),(\d+)$/));
554 $prompt: Error: Illegal margins specified: "$opt{margins}"
555 Margins must be <hmargin>,<vmargin>
556 EOF
557 $PAGE_HMARGIN = $1;
558 $PAGE_VMARGIN = $2;
559 }
560
561 =item B<-multipage>
562
563 Process a multi-page PostScript file, i.e. create an individual bitmap
564 for every page. The resulting files are numbered: The decimal number
565 (starting with 1) is appended to the basename of the PostScript input
566 file (or the basename of the filename specified with B<-out>), while
567 keeping the extension.
568
569 =item B<-out> I<file>
570
571 The file where to write the bitmap. If multiple PostScript files are
572 supplied on the command line, this option is ignored. The bitmap type
573 extension is appended automatically if I<file> does not contain a dot.
574 In connection with B<-multipage> I<file> is extended by the page number
575 as shown in this example:
576
577 -outfile foo.gif --------E<gt> foo1.gif, foo2.gif, ...
578
579 =cut
580
581 if(!$opt{out} && $ENV{OUTFILE}) {
582 $opt{out} = $ENV{OUTFILE};
583 }
584
585 =item B<-quiet>
586
587 Do not print anything except error messages.
588
589 =item B<-rightjustify> I<num>
590
591 Add the appropriate amount of whitespace to the left of the image so that
592 it appears to be aligned to the right in a total width of I<num> pixels.
593
594 =cut
595
596 my $RIGHT_JUSTIFY = 0; # No right justifying by default
597 if($opt{rightjustify}) {
598 $RIGHT_JUSTIFY = $opt{rightjustify};
599 die <<"EOF" unless ($RIGHT_JUSTIFY =~ /^\d+$/ && $RIGHT_JUSTIFY > 0);
600 $prompt: Error: Illegal width for -rightjustify specified: "$RIGHT_JUSTIFY"
601 Value must be a positive integer.
602 EOF
603 }
604
605 =item B<-scale> I<factor>
606
607 Scale the image by I<factor>. Valid choices are any numbers greater than
608 zero. Useful choices are numbers between 0.1 - 5.
609 Large numbers may generate very large intermediate files and will take
610 longer to process. If this option is omitted, the environment SCALE is
611 considered.
612
613 =cut
614
615 unless($opt{scale}) {
616 if($ENV{SCALE}) {
617 $opt{scale} = $ENV{SCALE};
618 }
619 else {
620 $opt{scale} = 1;
621 }
622 }
623 die <<"EOF" unless ($opt{scale} =~ /^[\d.e]+$/i && $opt{scale} > 0);
624 $prompt: Error: Illegal scale specified: "$opt{scale}"
625 Scale must be nonnegative float value.
626 EOF
627
628 =item B<-shoreup> I<num>[B<d>]
629
630 Make height and width of the bitmap(s) an exact multiple of I<num>. If
631 I<num> is followed by a "d", then half the extra vertical space is placed
632 underneath. This option is useful, if you want to have "blown-up" images
633 of high quality for print, but downscale them in HTML using
634 C<E<lt>IMG WIDTH=x HEIGHT=yE<gt>>. If the actual image is is not an
635 integer multiple of x,y then browsers tend to display distorted images.
636
637 =cut
638
639 my $SHORE_UP = 0; # No pixel alignment by default
640 if($opt{shoreup}) {
641 $SHORE_UP = $opt{shoreup};
642 die <<"EOF" unless $SHORE_UP =~ /^\d+d?$/i;
643 $prompt: Error: Illegal shore-up specified: "$SHORE_UP"
644 Value must be a positive integer, optionally followed by d
645 EOF
646 }
647
648 =item B<-tmp> I<path>
649
650 Use I<path> to store temporary files. Defaults to /tmp on this
651 installation. This parameter can be set by the environment B<TMP> or
652 B<TEMP>, too.
653
654 =cut
655
656 my $TMP = '';
657 if($opt{tmp}) {
658 $opt{tmp} =~ s|\Q$dd\E+$||; # remove trailing directory separator(s)
659 if(-d $opt{tmp} && -r _ && -w _) {
660 $TMP = $opt{tmp};
661 } else {
662 print "$prompt: Warning: Cannot use $opt{tmp} as temporary directory.\n";
663 }
664 }
665 if(!$TMP && ($ENV{TMP} || $ENV{TEMP})) {
666 ($opt{tmp} = $ENV{TMP} || $ENV{TEMP}) =~ s|\Q$dd\E+$||;
667 if(-d $opt{tmp} && -r _ && -w _) {
668 $TMP = $opt{tmp};
669 } else {
670 print "$prompt: Warning: Cannot use $opt{tmp} as temporary directory.\n";
671 }
672 }
673 if(!$TMP && -d $def_tmp && -r _ && -w _) {
674 $TMP = $def_tmp;
675 }
676 print "$prompt: Temporary directory is $TMP\n" if($opt{debug});
677
678 =item B<-topjustify> [B<x>]I<num>
679
680 Add padding whitespace to the image so that it gets a defined height.
681 If an integer value is given, it defines the total height. The whitespace
682 is added at the bottom. If the number is preceded by "x", then this
683 multiple of the image height is added as whitespace at the bottom.
684
685 =cut
686
687 my $TOP_JUSTIFY = 0; # No top justifying by default
688 if($opt{topjustify}) {
689 $TOP_JUSTIFY = $opt{topjustify};
690 die <<"EOF" unless $TOP_JUSTIFY =~ /^x?\d+[.]?\d*$/i;
691 $prompt: Error: Illegal align specified: "$TOP_JUSTIFY"
692 Value must be positive numeric, optionally preceded by x
693 EOF
694 }
695
696 =item B<-transparent>
697
698 Generate transparent bitmaps, i.e. the background color (white) is
699 transparent if viewed with certain viewers (e.g. browsers). This option
700 may not be available due to missing capabilities of external
701 programs.
702
703 =cut
704
705 my $TRANSPARENT = 0; # Do not make make images transparent by default
706 if($opt{transparent}) {
707 $TRANSPARENT = 1;
708 }
709
710 =item B<-type> I<type>
711
712 Instruct pstoimg to render the bitmap in I<type> format. Depending on
713 the local installation, pstoimg is capable of generating either GIF or
714 PNG bitmaps. This site features the following types: png gif
715
716 If omitted, the first type in this list is taken.
717
718 =cut
719
720 if($opt{type}) {
721 $opt{type} = lc($opt{type});
722 die <<"EOF" unless grep($_ eq $opt{type},@IMAGE_TYPES);
723 $prompt: Error: This version of pstoimg does not support
724 "$opt{type}" image format.
725 EOF
726 }
727 else {
728 ($opt{type}) = @IMAGE_TYPES; # default image type
729 }
730 # Support -gif and -png for a transition period
731 if($opt{gif}) {
732 print qq{$prompt: Warning: The -gif switch is deprecated. Use "-type gif" instead.\n};
733 if(grep($_ eq 'gif',@IMAGE_TYPES)) {
734 $opt{type} = 'gif';
735 }
736 else {
737 die <<"EOF";
738 $prompt: Error: This version of pstoimg does not support "gif" format.
739 EOF
740 }
741 }
742 if($opt{png}) {
743 print qq{$prompt: Warning: The -png switch is deprecated. Use "-type png" instead.\n};
744 if(grep($_ eq 'png',@IMAGE_TYPES)) {
745 $opt{type} = 'png';
746 }
747 else {
748 die <<"EOF";
749 $prompt: Error: This version of pstoimg does not support "png" format.
750 EOF
751 }
752 }
753
754 =item B<-white>
755
756 Remove TeX's page color information from the PostScript file before
757 converting so that a white background is used.
758
759 =back
760
761 =cut
762
763 # do some consistency checks on the options
764
765
766 die <<"EOF" if($RIGHT_JUSTIFY && $CENTER);
767 $prompt: Error: Conflicting options -center and -rightjustify.
768 EOF
769
770 # now setup some parameters
771
772 # calculate dpi resolution from density and scale
773 $DENSITY = int($opt{scale} * $DENSITY + .5) if($opt{scale} != 1);
774
775 my $reduce_color = '';
776 if($opt{depth} == 1) {
777 $reduce_color = "$PPMQUANT 2";
778 }
779 elsif ($opt{depth} == 8) {
780 $reduce_color = "$PPMQUANT 256";
781 }
782
783 my $gs_aalias = '';
784 if($opt{antialias}) {
785 $GSDEVICE = $GSALIASDEVICE;
786 if($opt{depth} == 1) {
787 $gs_aalias = '-dTextAlphaBits=4 ';
788 $reduce_color = "$PPMQUANT -floyd 256";
789 }
790 else {
791 $gs_aalias = '-dTextAlphaBits=4 -dGraphicsAlphaBits=4 ';
792 }
793 }
794 elsif ($opt{aaliastext}) {
795 $GSDEVICE = $GSALIASDEVICE;
796 $gs_aalias = '-dTextAlphaBits=4 ';
797 $reduce_color = "$PPMQUANT -floyd 256";
798 }
799 my $PAPERSIZE = $ENV{PAPERSIZE} || '';
800 # This rx matches float values in Bounding Box expressions
801 my $Brx = '-?\d+(?:\.\d*|)';
802
803 ##############################################################################
804 # Main program
805
806 =head1 DESCRIPTION
807
808 B<pstoimg> iterates over the given input files and runs them through
809 Ghostscipt. The resulting pnm (portable anymap files) are processed
810 with different Netpbm tools (cropping, color mapping, aligning, ...)
811 and finally converted into (currently) either GIF or PNG format. The
812 bitmaps can now be included e.g. in WWW pages.
813
814 The PostScript file is converted as is. If a valid bounding box is
815 found (EPS format), then only this area is converted. The image is
816 I<not> cropped by default.
817
818 =cut
819
820 die "$prompt: Error: No input file(s) specified\n"
821 unless(@ARGV);
822
823 # suppress diagnostics messages if possible
824 my $NULLFILE = '/dev/null';
825 open(STDERR, ">$NULLFILE") unless($opt{debug});
826
827 my $exit = 0;
828
829 $opt{out} = '' if(@ARGV > 1); # disable -out if multiple ps files given
830
831 my $psfile;
832 foreach $psfile (@ARGV) {
833 unless (-f $psfile) {
834 print qq{$prompt: Error: Cannot find file "$psfile": $!\n};
835 exit 1;
836 }
837 $exit += (&pstoimg($psfile) ? 0 : 1);
838 }
839
840 =head1 RETURN VALUE
841
842 =over 4
843
844 =item 0
845
846 if everything went all right
847
848 =item x
849
850 (x != 0) something went wrong. See the message output.
851
852 =back
853
854 =cut
855
856 exit $exit ? 1 : 0;
857
858 ##############################################################################
859 # Subroutines
860
861 sub pstoimg {
862 my ($psfile) = @_;
863
864 print "$prompt: Processing $psfile\n" unless($opt{quiet});
865 # remove a trailing suffix the same way a shell would do it
866 my $base = $psfile;
867 $base =~ s|[.][^.$dd$dd]*$||;
868
869 my $outfile;
870 if($opt{out}) {
871 $outfile = $opt{out};
872 # append the type unless -outfile has a "." in it
873 $outfile .= ".$opt{type}" unless($outfile =~ /[.]/);
874 }
875 else {
876 $outfile = "$base.$opt{type}";
877 }
878
879 # Invoke Ghostscript
880 my $pnmdir = $TMP ? "$TMP$dd" : ".$dd";
881 my $pnmbase = "p$$"; # keep it short for dos
882 my $pnmfile = $pnmdir .
883 ($opt{multipage} ? "%d_${pnmbase}.pnm" : "$pnmbase.pnm");
884
885 ps2pnm($psfile,$pnmfile) || return 0;
886
887 my $ok = 1;
888 if (-f $pnmfile) {
889 if(crop_scale_etc($pnmfile, $outfile)) {
890 L2hos->Unlink($pnmfile) unless($opt{debug});
891 }
892 else {
893 return 0;
894 }
895 }
896 elsif($opt{multipage}) {
897 unless(opendir(DIR,$pnmdir)) {
898 print qq{$prompt: Error: Could not open directory "$pnmdir": $!\n};
899 return 0;
900 }
901 my @list = grep(/^\d+_\w*\./,readdir(DIR));
902 closedir(DIR);
903 if(@list) {
904 my $i;
905 foreach $i (@list) {
906 my ($n) = $i =~ /^(\d+)_/;
907 my $j = $outfile;
908 $j =~ s|(\.[^/.]*)$|$n$1|;
909 if(crop_scale_etc("$pnmdir$i", $j)) {
910 L2hos->Unlink("$pnmdir$i") unless($opt{debug});
911 }
912 else {
913 $ok = 0;
914 }
915 }
916 }
917 else {
918 goto not_found;
919 }
920 }
921 else {
922 not_found:
923 print "$prompt: Error: Couldn't find pnm output of $psfile\n";
924 }
925 L2hos->Unlink($psfile) if($opt{discard} && !$opt{debug});
926 $ok;
927 }
928
929 sub ps2pnm {
930 my ($psfile,$pnmfile) = @_;
931 my $gs_size = $PAPERSIZE ? "-sPAPERSIZE=$PAPERSIZE" : '';
932 my $gs_density = ($DENSITY != 72) ? "-r$DENSITY" : '';
933
934 my ($bbx, $bby, $bbw, $bbh) = (0,0,0,0);
935 my $max_lines = 100;
936 my ($epsf,$have_geometry) = (0,0);
937
938 # Parse postscript file for information
939 unless(open(PS, "<$psfile")) {
940 print qq{$prompt: Error: Cannot read "$psfile": $!};
941 return 0;
942 }
943 $_ = <PS>; # read one line
944 if( /^%!.*EPSF/ ) {
945 # we're in a EPSF file
946 $epsf = 1;
947 }
948 if($GEOMETRY || $epsf) {
949 while (defined ($_ = <PS>)) {
950 # Look for bounding box comment
951 # MRO: add support of precise bounding boxes
952 if ($epsf && (
953 /^%+(?:HiRes|Exact)BoundingBox:\s+($Brx)\s+($Brx)\s+($Brx)\s+($Brx)/o ||
954 /^\%\%BoundingBox:\s+(-?\d+)\s+(-?\d+)\s+(-?\d+)\s+(-?\d+)/)) {
955 $bbx = 0 - $1; $bby = 0 - $2;
956 $bbw = $3 + $bbx; $bbh = $4 + $bby;
957 if(($bbw > 0) && ($bbh > 0)) { # we have a valid bounding box
958 print "$prompt: EPSF dimensions are ${bbw}x$bbh\n" if($opt{debug});
959 # this overrides the -geometry switch
960 if($DENSITY) { # scale the output
961 my $scale = $DENSITY / 72.0;
962 $bbw *= $scale;
963 $bbh *= $scale;
964 }
965 $bbw = int($bbw + 0.99);
966 $bbh = int($bbh + 0.99);
967 $GEOMETRY = "${bbw}x${bbh}";
968 $have_geometry = 1;
969 last;
970 }
971 }
972 # Look for page size information
973 elsif($GEOMETRY && /TeXDict\s+begin\s+(\d+)\s+(\d+)\s+/) {
974 $PAGE_WIDTH = int($1 / 65536 * 72 /72.27 +.5);
975 $PAGE_HEIGHT = int($2 / 65536 * 72 /72.27 +.5);
976 print "$prompt: Page dimensions are ${PAGE_WIDTH}x$PAGE_HEIGHT\n"
977 if($opt{debug});
978 # we don't have to look further for EPSF stuff at this point
979 last;
980 }
981 elsif(!$GEOMETRY && (/^\%\%EndComments/ || --$max_lines == 0)) {
982 # abort at a certain point to avoid scanning huge ps files
983 last;
984 }
985 }
986 }
987 close PS;
988 if($GEOMETRY && !$have_geometry) { # RRM: overrides $PAPERSIZE
989 # no geometry info found in the Postscript file
990 $bbx = $PAGE_HMARGIN;
991 $bby = $PAGE_HEIGHT - $PAGE_VMARGIN;
992 unless($GEOMETRY =~ /\s*(\d+)x(\d+)/i) {
993 print qq{$prompt: Illegal geometry "$GEOMETRY" specified.\n};
994 return 0;
995 }
996 $bbw = $1 + 10; # allow for the side-bars
997 $bbh = $2;
998 $bby = int(-$bby + $bbh + 8); # allow small margin for error
999 $bbx = int(-$bbx + 5); # allow small margin for error
1000 if($DENSITY) {
1001 my $scale = $DENSITY / 72.0;
1002 $bbw = int($scale * $bbw + .99);
1003 $bbh = int($scale * $bbh + .99);
1004 }
1005 $bbw += 10; # add a 5pt margin for safety
1006 $bbh += 40; # add a 20pt margin for safety
1007 $GEOMETRY = "${bbw}x$bbh";
1008 $have_geometry = 1;
1009 }
1010 if($have_geometry) {
1011 $gs_size = "-g$GEOMETRY ";
1012 }
1013
1014 my $ps_changed = 0;
1015 if($have_geometry || $opt{white}) {
1016 # Remove any Postscript commands concerning Papersize if -g switch is used
1017 # thanks to Axel Ramge for identifying the problem and for this code
1018 local($/) = undef;
1019 open(PS,"<$psfile");
1020 my $ps = <PS>;
1021 close(PS);
1022 my $had_papersize;
1023 if($have_geometry) {
1024 $had_papersize = ($ps =~ s/\n%%BeginPaperSize.*?%%EndPaperSize[^\n]*\n/\n/sg);
1025 }
1026 my $had_nonwhite;
1027 if($opt{white}) {
1028 $had_nonwhite = ($ps =~ s/(\n\d+ \d+ bop gsave) \d*\.\d+ (TeXcolorgray clippath fill grestore)/$1 1 $2/s);
1029 }
1030 $ps_changed = $had_papersize || $had_nonwhite;
1031 if($ps_changed) {
1032 my $tmppsfile = $pnmfile; # was "tmpps$$.ps"
1033 $tmppsfile =~ s/\.[^.]*$/.ps/;
1034 unless(open(PS,">$tmppsfile") && (print PS $ps) && (close PS)) {
1035 if($had_papersize) {
1036 print <<"EOF";
1037 $prompt: Warning: Could not write "$tmppsfile": $!
1038 "$psfile" contains %%Papersize comments.
1039 Any of these should be removed else GS will fail.
1040 EOF
1041 }
1042 if($had_nonwhite) {
1043 print <<"EOF";
1044 $prompt: Warning: Could not write "$tmppsfile": $!
1045 "$psfile" has a non-white background.
1046 This may cause ugly images.
1047 EOF
1048 }
1049 }
1050 $psfile = $tmppsfile;
1051 print qq{Debug: Papersize comment in "$psfile" deleted.\n}
1052 if($had_papersize && $opt{debug});
1053 print qq{Debug: Background switched to white in "$psfile".\n}
1054 if($had_nonwhite && $opt{debug});
1055 }
1056 }
1057
1058 my $gs_quiet = $opt{debug} ? '' : '-q -dNOPAUSE -dNO_PAUSE';
1059 my $out_redirect = $opt{debug} ? '' : "> $NULLFILE";
1060 my $gs_out = "-sOutputFile=$pnmfile";
1061 my $gsfile = $psfile;
1062 # Ghostscript understands only '/' as path delimiter!
1063 if($opt{debug}) {
1064 print "$prompt: Running $GS $gs_quiet -sDEVICE=$GSDEVICE $gs_size $gs_density $gs_aalias $gs_out $out_redirect\n";
1065 print "GS>$bbx $bby translate\n" if($have_geometry);
1066 print "GS>($gsfile) run\n";
1067 print "GS>showpage\n" if ($epsf);
1068 print "GS>quit\n";
1069 }
1070 open (GS, "|$GS $gs_quiet -sDEVICE=$GSDEVICE $gs_size $gs_density $gs_aalias $gs_out $out_redirect");
1071 print GS "$bbx $bby translate\n" if ($have_geometry);
1072 print GS "($gsfile) run\n";
1073 print GS "showpage\n" if ($epsf);
1074 print GS "quit\n";
1075 print "\n" if($opt{debug});
1076 unless(close(GS)) {
1077 print "$prompt: Error: Ghostscript returned error status ",$?>>8,"\n";
1078 }
1079 L2hos->Unlink($psfile) if($ps_changed && !$opt{debug});
1080 1;
1081 }
1082
1083
1084 # This sub post-processes the PNM images that come out of Ghostscript.
1085 # The image is cropped, flipped and finally converted to PNG or GIF.
1086
1087 sub crop_scale_etc {
1088 my ($in, $out) = @_;
1089
1090 # create temp filename; should be auto-incrementable
1091 my $tmp = $in;
1092 $tmp =~ s/(\.[^.]*)?$/.t00/;
1093 # save the original Ghostscript result
1094 if($opt{debug}) {
1095 L2hos->Copy($in,$tmp);
1096 &increment_name($tmp);
1097 }
1098 my ($cmd,$type,$width,$height,$just);
1099
1100 my $must_align = 0;
1101 #$EXTRA_CROP = "a$EXTRA_CROP" # hack to ensure first all-over cropping
1102 # unless($EXTRA_CROP =~ /^a/i);
1103
1104 # RRM: Remove justification bars
1105 $EXTRA_CROP =~ s/h/bt/gi; # crop horizontally
1106 $EXTRA_CROP =~ s/v/rl/gi; # crop vertically
1107 while ($EXTRA_CROP =~ /([atblrs])/gi) {
1108 my $edge = $1;
1109 my $croparg = ' ';
1110 if($edge =~ /b/i) {
1111 $croparg = "-bot $PNMCROPOPT ";
1112 } elsif($edge =~ /[tlr]/i) {
1113 $croparg = "-$edge $PNMCROPOPT ";
1114 } elsif($edge =~ /s/i) {
1115 #RRM: shave at most 1-2 rows of white from the bottom
1116 if($cmd) {
1117 # Terminate command pipe
1118 $cmd .= "| pnmcrop -white -bot -verbose | pamcut -bottom 200 -pad | pnmcrop -black -bot -verbose";
1119 &do_cmd($in,$tmp,$cmd) || return 0; # failure
1120 $cmd = '';
1121 }
1122 my ($type,$width,$height) = get_image_geometry($in);
1123 #CNH add begin
1124 ###CNH next
1125 #CNH add end
1126 next unless($type); # skip if no geometry
1127 if(&do_cmd_norename("$PNMCROP $PNMCROPOPT -bot < $in",$tmp)) {
1128 my ($type,$width,$height2) = get_image_geometry($tmp);
1129 if($type && ($height - $height2) < 30 ) {
1130 # command succeeded and shaved less than 3 rows
1131 if($opt{debug}&&(-f $tmp)) {
1132 L2hos->Copy($tmp,$in);
1133 &increment_name($tmp);
1134 } elsif (-f $tmp) {
1135 L2hos->Rename($tmp,$in);
1136 }
1137 next;
1138 }
1139 }
1140 # MRO: this shouldn't be necessary: L2hos->Unlink($tmp);
1141 next; # go to next crop argument
1142 } # end switch on crop codes
1143 if($cmd) {
1144 # Continue command pipe
1145 $cmd .= "| $PNMCROP $croparg";
1146 } else {
1147 # start new pipe
1148 $cmd = "$PNMCROP $croparg< $in ";
1149 }
1150 } # end cropping
1151
1152
1153 if($opt{flip}) {
1154 unless($cmd) {
1155 $cmd = "$PNMFLIP -$opt{flip} < $in";
1156 } else {
1157 $cmd .= "| $PNMFLIP -$opt{flip} ";
1158 }
1159 }
1160
1161 if($RIGHT_JUSTIFY || $TOP_JUSTIFY || $CENTER || $SHORE_UP) {
1162 if($cmd) {
1163 # empty command pipe, we need the image's geometry
1164 &do_cmd($in,$tmp,$cmd);
1165 $cmd='';
1166 }
1167
1168 # Get bitmap type and dimensions
1169 ($type,$width,$height) = &get_image_geometry($in);
1170 return 0 unless($type);
1171
1172 my ($white_left,$white_right,$white_top,$white_bottom) = (0,0,0,0);
1173
1174 if($RIGHT_JUSTIFY || $CENTER) {
1175 if($RIGHT_JUSTIFY) {
1176 $white_left = int($RIGHT_JUSTIFY-$width);
1177 } else { # CENTER
1178 $white_left = int(($CENTER-$width) / 2);
1179 }
1180 $white_left = 0 unless($white_left > 0);
1181
1182 $width += $white_left;
1183 }
1184
1185 if($TOP_JUSTIFY) {
1186 if($TOP_JUSTIFY =~ /^x([0-9.]+)/io) {
1187 $white_bottom = $1 * $height;
1188 } else {
1189 $white_bottom = $TOP_JUSTIFY - $height;
1190 }
1191 if($white_bottom > 0) {
1192 $white_bottom = int($white_bottom + 0.99); # round up
1193 $height += $white_bottom;
1194 } else {
1195 $white_bottom = 0;
1196 }
1197 }
1198
1199 if($SHORE_UP =~ /(\d+)(d?)/ && $1) {
1200 # RRM: make height and width an exact multiple of $SHORE_UP
1201 my ($shoreup,$depth) = ($1,$2);
1202 my $extra = $height % $shoreup;
1203 if($depth) { # image needs depth, place half the extra space underneath
1204 my $bextra = int($extra/2);
1205 $white_bottom += $bextra;
1206 $white_top += $extra - $bextra;
1207 } else {
1208 $white_top += $extra;
1209 }
1210
1211 $extra = $width % $shoreup;
1212 my $rextra = int($extra/2);
1213 $white_right += $rextra;
1214 $white_left += $extra - $rextra;
1215 $cmd = '';
1216 }
1217
1218
1219 if($white_left) {
1220 if($cmd) {
1221 &do_cmd($in,$tmp,$cmd) || return 0;
1222 }
1223 # Start new command pipe
1224 $cmd = "$PBMMAKE -white $white_left 1 | $PNMCAT -white -lr - $in ";
1225 }
1226
1227 if($white_right) {
1228 if($cmd) {
1229 &do_cmd($in,$tmp,$cmd) || return 0;
1230 }
1231 # Start new command pipe
1232 $cmd = "$PBMMAKE -white $white_right 1 | $PNMCAT -white -lr $in - ";
1233 }
1234
1235 if($white_top) {
1236 if($cmd) {
1237 &do_cmd($in,$tmp,$cmd) || return 0;
1238 }
1239 # Start new command pipe
1240 $cmd = "$PBMMAKE -white 1 $white_top | $PNMCAT -white -tb - $in ";
1241 }
1242
1243 if($white_bottom) {
1244 if($cmd) {
1245 &do_cmd($in,$tmp,$cmd) || return 0;
1246 }
1247 # Start new command pipe
1248 $cmd = "$PBMMAKE -white 1 $white_bottom | $PNMCAT -white -tb $in - ";
1249 }
1250 } # endif must_align
1251
1252 my $pnmtoimg;
1253 if($opt{type} eq 'gif') {
1254 $pnmtoimg = $PPMTOGIF;
1255 if($INTERLACE) {
1256 $pnmtoimg .= ' -interlace';
1257 }
1258 if($TRANSPARENT) {
1259 $pnmtoimg .= ' -trans ' . L2hos->quote($trans_color);
1260 }
1261 }
1262 if($opt{type} eq 'png') {
1263 $pnmtoimg = $PNMTOPNG;
1264 if($INTERLACE) {
1265 $pnmtoimg .= ' -interlace';
1266 }
1267 if($TRANSPARENT) {
1268 $pnmtoimg .= ' -trans ' . L2hos->quote($trans_color);
1269 }
1270 }
1271 unless($pnmtoimg) {
1272 print qq($prompt: Error: unknown image type "$opt{type}".\n);
1273 exit 2;
1274 }
1275
1276 unless($type) {
1277 ($type,$width,$height) = &get_image_geometry($in);
1278 return 0 unless($type);
1279 }
1280 # run ppmquant only on color/gray images
1281 if(!$type || $type =~ /(ppm|pgm)/i) {
1282 if($cmd) {
1283 $cmd .= "| $reduce_color "
1284 } else {
1285 $cmd = "$reduce_color < $in ";
1286 }
1287 }
1288
1289 if($cmd) {
1290 $cmd .= "| $pnmtoimg "
1291 } else {
1292 $cmd = "$pnmtoimg < $in ";
1293 }
1294 &do_cmd_norename($cmd,$out) || return 0;
1295 print qq{$prompt: Written $out\n} unless($opt{quiet});
1296
1297 1;
1298 }
1299
1300 sub banner {
1301 print "$prompt V$RELEASE (Revision $VERSION, Perl $])\n";
1302 }
1303
1304 sub print_version {
1305 my $formats = join(',',@IMAGE_TYPES);
1306 print <<"EOM";
1307 $prompt (Revision $VERSION, perl $]),
1308 part of LaTeX2HTML Release V$RELEASE.
1309
1310 Supported output image format(s): $formats
1311 EOM
1312 1;
1313 }
1314
1315 sub print_help {
1316 L2hos->perldoc($SCRIPT);
1317 1;
1318 }
1319
1320 sub print_usage {
1321 my $start = 0;
1322 my $usage = 'Usage: ';
1323 my $indent = '';
1324
1325 print (@_, "\n") if @_;
1326
1327 my $perldoc = '/usr/bin'.$dd."perldoc";
1328 my $script = $SCRIPT || $0;
1329 open(PIPE, "$perldoc -t $script |")
1330 || die "Fatal: can't open pipe: $!";
1331 while (<PIPE>)
1332 {
1333 if (/^\s*$/) {
1334 next;
1335 } elsif (/^SYNOPSIS/) {
1336 $start = 1;
1337 } elsif (/^\w/) {
1338 $start = 0;
1339 } elsif ($start == 1) {
1340 ($indent) = /^(\s*)/;
1341 s/^$indent/$usage/;
1342 $usage =~ s/./ /g;
1343 $start = 2;
1344 print $_;
1345 } elsif ($start == 2) {
1346 s/^$indent/$usage/;
1347 print $_;
1348 }
1349 }
1350 close PIPE;
1351 1;
1352 }
1353
1354 sub do_cmd {
1355 my ($in,$tmp,$cmd) = @_;
1356
1357 print qq{Running "$cmd > $tmp"\n} if($opt{debug});
1358 my $stat = system("$cmd > $tmp");
1359 if($stat) { # error
1360 print qq{$prompt: Error: "$cmd > $tmp" failed: $!\n};
1361 return 0; # failure
1362 }
1363 elsif(!-s $tmp) { # does not exist or zero size
1364 print qq{$prompt: Error: "$cmd > $tmp" produced empty file\n};
1365 L2hos->Unlink($tmp) if(-e $tmp);
1366 return 0; # failure
1367 }
1368 if($opt{debug}) {
1369 # increase the temporary filename by 1
1370 # this uses perl's magic autoincrement
1371 &increment_name($_[1]);
1372 return L2hos->Copy($tmp,$in);
1373 } elsif(!L2hos->Rename($tmp,$in)) {
1374 print qq{$prompt: Error: rename of "$tmp" to "$in" failed: $!\n};
1375 return 0; # failure
1376 }
1377 1;
1378 }
1379
1380 sub do_cmd_norename {
1381 my ($cmd,$out) = @_;
1382
1383 print qq{Running "$cmd > $out"\n} if($opt{debug});
1384 my $stat = system("$cmd > $out");
1385 if($stat) { # error
1386 print qq{$prompt: Error: "$cmd > $out" failed: $!\n};
1387 return 0; # failure
1388 }
1389 elsif(!-s $out) { # does not exist or zero size
1390 print qq{$prompt: Error: "$cmd > $out" produced empty file\n};
1391 L2hos->Unlink($out) if(-e $out);
1392 return 0; # failure
1393 }
1394 1;
1395 }
1396
1397 sub do_cmd_plain {
1398 my ($cmd) = @_;
1399
1400 print qq{Running "$cmd"\n} if($opt{debug});
1401 my $stat = system($cmd);
1402 if($stat) { # error
1403 print qq{$prompt: Error: "$cmd" failed: $!\n};
1404 return 0; # failure
1405 }
1406 1;
1407 }
1408
1409 sub get_image_geometry {
1410 my ($pnmfile) = @_;
1411
1412 my ($type,$width,$height);
1413 my $out = `$PNMFILE $pnmfile`;
1414 if($? || $out =~ /(P[BGP]M)[^0-9]*(\d+)\s*by\s*(\d+)/i) {
1415 $type = $1;
1416 $width = $2;
1417 $height = $3;
1418 print qq{Image "$pnmfile" is $type, ${width}x$height\n} if($opt{debug});
1419 } else {
1420 print "$prompt: Error: Could not determine image size: $out\n";
1421 return undef;
1422 }
1423 ($type,$width,$height);
1424 }
1425
1426 # push the number in the suffix up one notch
1427 sub increment_name {
1428 $_[0] =~ s/(\d+)$/$a=$1;++$a/e;
1429 }
1430
1431 __DATA__
1432
1433 =head1 EXAMPLES
1434
1435 =over 4
1436
1437 =item C<pstoimg foo.ps>
1438
1439 Convert the first page of foo.ps to the default bitmap type.
1440
1441 =item C<pstoimg -type png -crop a -trans -interlace foo.ps>
1442
1443 Same as above, but force png output and crop all the whitespace
1444 around the image and make the color white transparent and
1445 generate an interlaced bitmap.
1446
1447 =item C<pstoimg -multi -out bar -type gif -crop a foo.ps>
1448
1449 Consider foo.ps a multiple page PostScript file and create output
1450 files bar1.gif, bar2.gif, etc.
1451
1452 =back
1453
1454 =head1 ENVIRONMENT
1455
1456 =over 4
1457
1458 =item DENSITY, DEPTH, DEBUG, DISCARD
1459
1460 See B<-density>, B<-depth>, B<-debug>, B<-discard>, respectively.
1461
1462 =item GS_LIB
1463
1464 This variable is set to the path(s) where Ghostscript libraries have
1465 been found on this system during configuration, but only if the built-in
1466 paths are not correct. This fixes the problem of relocation that is quite
1467 common on Win32 installations. This behavior can be overridden by
1468 setting GS_LIB manually before starting pstoimg.
1469
1470 =item LATEX2HTMLDIR
1471
1472 The directory where the LaTeX2HTML library and perl modules are found.
1473 Defaults to "/usr/share/latex2html" on this installation.
1474
1475 =item OUTFILE
1476
1477 Setting this has the same effect as specifying B<-out>. Please do not rely
1478 on this feature any more, it will disappear from the next releases!
1479
1480 =item PAPERSIZE
1481
1482 The papersize to use by Ghostscript to render the image. pstoimg tries
1483 hard to optimize for rendering on the smallest possible bitmap size.
1484 Still this option is there to enable tuning by hand, although it is
1485 deprecated. If pstoimg finds a better setting, this parameter is ignored.
1486
1487 =item SCALE
1488
1489 See the discussion of B<-scale>.
1490
1491 =item TMP and TEMP
1492
1493 Unless overridden by B<-tmp>, these variables denote a directory where
1494 to store temporary files. TMP is considered first, then TEMP.
1495
1496 =back
1497
1498 =head1 SEE ALSO
1499
1500 gs, pnmcrop, pnmquant, pbmmake, pnmcat, pnmfile, pnmflip, ppmtogif,
1501 pnmtopng, giftool, giftrans.
1502
1503 =head1 NOTES
1504
1505 Several people have suggested to use ImageMagick's convert instead of
1506 pstoimg. A few comments on this: convert uses (of course) Ghostscript
1507 for conversion of PostScript to bitmap, so one still needs gs. And
1508 for the special requirements of LaTeX2HTML convert's features are not
1509 sufficient. The ImageMagick toolset has everything in place, but it
1510 has some overhead that can prove killing when processing some 100
1511 images. pstoimg only does what it really has to, so it should be
1512 quite efficient. Don't get me wrong - I like ImageMagick, but not in
1513 the context of LaTeX2HTML.
1514
1515 =head1 CAVEATS
1516
1517 This utility is automatically configured and built to work on the
1518 local setup. If this setup changes (e.g. some of the external commands
1519 are moved), the script has be be reconfigured.
1520
1521 Despite the portability of perl, a pstoimg configured on UNIX will
1522 probably not work on Win32 and vice versa.
1523
1524 =head1 BUGS
1525
1526 This is a major enhancement release, so there may be a few bugs. As
1527 the user inteface changed a bit, some of your tools that were using
1528 pstoimg may not work any more.
1529
1530 Please report bugs to latex2html@tug.org, stating the (debug) output
1531 of pstoimg, your perl version and the versions of the external tools.
1532 Best is to include the cfgcache.pm file from the configuration procedure.
1533
1534 =head1 AUTHOR
1535
1536 Marek Rouchal E<lt>marek@saftsack.fs.uni-bayreuth.deE<gt>
1537
1538 =head1 HISTORY
1539
1540 This script went through a long evolution, beginning with a modification
1541 of Doug Crabill's E<lt>dgc@cs.purdue.eduE<gt> ps2epsi script.
1542 The first perl version was done by Nikos Drakos <nikos@cbl.leeds.ac.uk>.
1543 It was gradually improved by numerous LaTeX2HTML developers:
1544 Ross Moore <ross@mpce.mq.edu.au>, Jens Lippmann
1545 <lippmann@rbg.informatik.tu-darmstadt.de> and others (sorry for not
1546 mentioning everyone and thanks for your contributions).
1547
1548 =cut

  ViewVC Help
Powered by ViewVC 1.1.22