/[MITgcm]/manual/pstoimg
ViewVC logotype

Contents of /manual/pstoimg

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


Revision 1.2 - (show annotations) (download)
Fri Jul 15 13:20:56 2005 UTC (18 years, 8 months ago) by cnh
Branch: MAIN
Changes since 1.1: +9 -4 lines
Slight change to the fix - plus relative path in .latex2html-init

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

  ViewVC Help
Powered by ViewVC 1.1.22