| 1 |
cnh |
1.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 |
| 1549 |
|
|
|