PNG  IHDRQgAMA a cHRMz&u0`:pQ<bKGDgmIDATxwUﹻ& ^CX(J I@ "% (** BX +*i"]j(IH{~R)[~>h{}gy)I$Ij .I$I$ʊy@}x.: $I$Ii}VZPC)I$IF ^0ʐJ$I$Q^}{"r=OzI$gRZeC.IOvH eKX $IMpxsk.쒷/&r[޳<v| .I~)@$updYRa$I |M.e JaֶpSYR6j>h%IRز if&uJ)M$I vLi=H;7UJ,],X$I1AҒJ$ XY XzI@GNҥRT)E@;]K*Mw;#5_wOn~\ DC&$(A5 RRFkvIR}l!RytRl;~^ǷJj اy뷦BZJr&ӥ8Pjw~vnv X^(I;4R=P[3]J,]ȏ~:3?[ a&e)`e*P[4]T=Cq6R[ ~ޤrXR Հg(t_HZ-Hg M$ãmL5R uk*`%C-E6/%[t X.{8P9Z.vkXŐKjgKZHg(aK9ڦmKjѺm_ \#$5,)-  61eJ,5m| r'= &ڡd%-]J on Xm|{ RҞe $eڧY XYrԮ-a7RK6h>n$5AVڴi*ֆK)mѦtmr1p| q:흺,)Oi*ֺK)ܬ֦K-5r3>0ԔHjJئEZj,%re~/z%jVMڸmrt)3]J,T K֦OvԒgii*bKiNO~%PW0=dii2tJ9Jݕ{7"I P9JKTbu,%r"6RKU}Ij2HKZXJ,妝 XYrP ެ24c%i^IK|.H,%rb:XRl1X4Pe/`x&P8Pj28Mzsx2r\zRPz4J}yP[g=L) .Q[6RjWgp FIH*-`IMRaK9TXcq*I y[jE>cw%gLRԕiFCj-ďa`#e~I j,%r,)?[gp FI˨mnWX#>mʔ XA DZf9,nKҲzIZXJ,L#kiPz4JZF,I,`61%2s $,VOϚ2/UFJfy7K> X+6 STXIeJILzMfKm LRaK9%|4p9LwJI!`NsiazĔ)%- XMq>pk$-$Q2x#N ؎-QR}ᶦHZډ)J,l#i@yn3LN`;nڔ XuX5pF)m|^0(>BHF9(cզEerJI rg7 4I@z0\JIi䵙RR0s;$s6eJ,`n 䂦0a)S)A 1eJ,堌#635RIgpNHuTH_SԕqVe ` &S)>p;S$魁eKIuX`I4춒o}`m$1":PI<[v9^\pTJjriRŭ P{#{R2,`)e-`mgj~1ϣLKam7&U\j/3mJ,`F;M'䱀 .KR#)yhTq;pcK9(q!w?uRR,n.yw*UXj#\]ɱ(qv2=RqfB#iJmmL<]Y͙#$5 uTU7ӦXR+q,`I}qL'`6Kͷ6r,]0S$- [RKR3oiRE|nӦXR.(i:LDLTJjY%o:)6rxzҒqTJjh㞦I.$YR.ʼnGZ\ֿf:%55 I˼!6dKxm4E"mG_ s? .e*?LRfK9%q#uh$)i3ULRfK9yxm܌bj84$i1U^@Wbm4uJ,ҪA>_Ij?1v32[gLRD96oTaR׿N7%L2 NT,`)7&ƝL*꽙yp_$M2#AS,`)7$rkTA29_Iye"|/0t)$n XT2`YJ;6Jx".e<`$) PI$5V4]29SRI>~=@j]lp2`K9Jaai^" Ԋ29ORI%:XV5]JmN9]H;1UC39NI%Xe78t)a;Oi Ҙ>Xt"~G>_mn:%|~ޅ_+]$o)@ǀ{hgN;IK6G&rp)T2i୦KJuv*T=TOSV>(~D>dm,I*Ɛ:R#ۙNI%D>G.n$o;+#RR!.eU˽TRI28t)1LWϚ>IJa3oFbu&:tJ*(F7y0ZR ^p'Ii L24x| XRI%ۄ>S1]Jy[zL$adB7.eh4%%누>WETf+3IR:I3Xה)3אOۦSRO'ٺ)S}"qOr[B7ϙ.edG)^ETR"RtRݜh0}LFVӦDB^k_JDj\=LS(Iv─aTeZ%eUAM-0;~˃@i|l @S4y72>sX-vA}ϛBI!ݎߨWl*)3{'Y|iSlEڻ(5KtSI$Uv02,~ԩ~x;P4ցCrO%tyn425:KMlD ^4JRxSهF_}شJTS6uj+ﷸk$eZO%G*^V2u3EMj3k%)okI]dT)URKDS 7~m@TJR~荪fT"֛L \sM -0T KfJz+nإKr L&j()[E&I ߴ>e FW_kJR|!O:5/2跌3T-'|zX ryp0JS ~^F>-2< `*%ZFP)bSn"L :)+pʷf(pO3TMW$~>@~ū:TAIsV1}S2<%ޟM?@iT ,Eūoz%i~g|`wS(]oȤ8)$ ntu`өe`6yPl IzMI{ʣzʨ )IZ2= ld:5+請M$-ї;U>_gsY$ÁN5WzWfIZ)-yuXIfp~S*IZdt;t>KūKR|$#LcԀ+2\;kJ`]YǔM1B)UbG"IRߊ<xܾӔJ0Z='Y嵤 Leveg)$znV-º^3Ւof#0Tfk^Zs[*I꯳3{)ˬW4Ւ4 OdpbZRS|*I 55#"&-IvT&/윚Ye:i$ 9{LkuRe[I~_\ؠ%>GL$iY8 9ܕ"S`kS.IlC;Ҏ4x&>u_0JLr<J2(^$5L s=MgV ~,Iju> 7r2)^=G$1:3G< `J3~&IR% 6Tx/rIj3O< ʔ&#f_yXJiގNSz; Tx(i8%#4 ~AS+IjerIUrIj362v885+IjAhK__5X%nV%Iͳ-y|7XV2v4fzo_68"S/I-qbf; LkF)KSM$ Ms>K WNV}^`-큧32ŒVؙGdu,^^m%6~Nn&͓3ŒVZMsRpfEW%IwdǀLm[7W&bIRL@Q|)* i ImsIMmKmyV`i$G+R 0tV'!V)֏28vU7͒vHꦼtxꗞT ;S}7Mf+fIRHNZUkUx5SAJㄌ9MqμAIRi|j5)o*^'<$TwI1hEU^c_j?Е$%d`z cyf,XO IJnTgA UXRD }{H}^S,P5V2\Xx`pZ|Yk:$e ~ @nWL.j+ϝYb퇪bZ BVu)u/IJ_ 1[p.p60bC >|X91P:N\!5qUB}5a5ja `ubcVxYt1N0Zzl4]7­gKj]?4ϻ *[bg$)+À*x쳀ogO$~,5 زUS9 lq3+5mgw@np1sso Ӻ=|N6 /g(Wv7U;zωM=wk,0uTg_`_P`uz?2yI!b`kĸSo+Qx%!\οe|އԁKS-s6pu_(ֿ$i++T8=eY; צP+phxWQv*|p1. ά. XRkIQYP,drZ | B%wP|S5`~́@i޾ E;Չaw{o'Q?%iL{u D?N1BD!owPHReFZ* k_-~{E9b-~P`fE{AܶBJAFO wx6Rox5 K5=WwehS8 (JClJ~ p+Fi;ŗo+:bD#g(C"wA^ r.F8L;dzdIHUX݆ϞXg )IFqem%I4dj&ppT{'{HOx( Rk6^C٫O.)3:s(۳(Z?~ٻ89zmT"PLtw䥈5&b<8GZ-Y&K?e8,`I6e(֍xb83 `rzXj)F=l($Ij 2*(F?h(/9ik:I`m#p3MgLaKjc/U#n5S# m(^)=y=đx8ŬI[U]~SцA4p$-F i(R,7Cx;X=cI>{Km\ o(Tv2vx2qiiDJN,Ҏ!1f 5quBj1!8 rDFd(!WQl,gSkL1Bxg''՞^ǘ;pQ P(c_ IRujg(Wz bs#P­rz> k c&nB=q+ؔXn#r5)co*Ũ+G?7< |PQӣ'G`uOd>%Mctz# Ԫڞ&7CaQ~N'-P.W`Oedp03C!IZcIAMPUۀ5J<\u~+{9(FbbyAeBhOSܳ1 bÈT#ŠyDžs,`5}DC-`̞%r&ڙa87QWWp6e7 Rϫ/oY ꇅ Nܶըtc!LA T7V4Jsū I-0Pxz7QNF_iZgúWkG83 0eWr9 X]㾮݁#Jˢ C}0=3ݱtBi]_ &{{[/o[~ \q鯜00٩|cD3=4B_b RYb$óBRsf&lLX#M*C_L܄:gx)WΘsGSbuL rF$9';\4Ɍq'n[%p.Q`u hNb`eCQyQ|l_C>Lb꟟3hSb #xNxSs^ 88|Mz)}:](vbۢamŖ࿥ 0)Q7@0=?^k(*J}3ibkFn HjB׻NO z x}7p 0tfDX.lwgȔhԾŲ }6g E |LkLZteu+=q\Iv0쮑)QٵpH8/2?Σo>Jvppho~f>%bMM}\//":PTc(v9v!gոQ )UfVG+! 35{=x\2+ki,y$~A1iC6#)vC5^>+gǵ@1Hy٪7u;p psϰu/S <aʸGu'tD1ԝI<pg|6j'p:tպhX{o(7v],*}6a_ wXRk,O]Lܳ~Vo45rp"N5k;m{rZbΦ${#)`(Ŵg,;j%6j.pyYT?}-kBDc3qA`NWQū20/^AZW%NQ MI.X#P#,^Ebc&?XR tAV|Y.1!؅⨉ccww>ivl(JT~ u`ٵDm q)+Ri x/x8cyFO!/*!/&,7<.N,YDŽ&ܑQF1Bz)FPʛ?5d 6`kQձ λc؎%582Y&nD_$Je4>a?! ͨ|ȎWZSsv8 j(I&yj Jb5m?HWp=g}G3#|I,5v珿] H~R3@B[☉9Ox~oMy=J;xUVoj bUsl_35t-(ՃɼRB7U!qc+x4H_Qo֮$[GO<4`&č\GOc[.[*Af%mG/ ňM/r W/Nw~B1U3J?P&Y )`ѓZ1p]^l“W#)lWZilUQu`-m|xĐ,_ƪ|9i:_{*(3Gѧ}UoD+>m_?VPۅ15&}2|/pIOʵ> GZ9cmíتmnz)yߐbD >e}:) r|@R5qVSA10C%E_'^8cR7O;6[eKePGϦX7jb}OTGO^jn*媓7nGMC t,k31Rb (vyܴʭ!iTh8~ZYZp(qsRL ?b}cŨʊGO^!rPJO15MJ[c&~Z`"ѓޔH1C&^|Ш|rʼ,AwĴ?b5)tLU)F| &g٣O]oqSUjy(x<Ϳ3 .FSkoYg2 \_#wj{u'rQ>o;%n|F*O_L"e9umDds?.fuuQbIWz |4\0 sb;OvxOSs; G%T4gFRurj(֍ڑb uԖKDu1MK{1^ q; C=6\8FR艇!%\YÔU| 88m)֓NcLve C6z;o&X x59:q61Z(T7>C?gcļxѐ Z oo-08jہ x,`' ҔOcRlf~`jj".Nv+sM_]Zk g( UOPyεx%pUh2(@il0ݽQXxppx-NS( WO+轾 nFߢ3M<;z)FBZjciu/QoF 7R¥ ZFLF~#ȣߨ^<쩡ݛкvџ))ME>ώx4m#!-m!L;vv#~Y[đKmx9.[,UFS CVkZ +ߟrY٧IZd/ioi$%͝ب_ֶX3ܫhNU ZZgk=]=bbJS[wjU()*I =ώ:}-蹞lUj:1}MWm=̛ _ ¾,8{__m{_PVK^n3esw5ӫh#$-q=A̟> ,^I}P^J$qY~Q[ Xq9{#&T.^GVj__RKpn,b=`żY@^՝;z{paVKkQXj/)y TIc&F;FBG7wg ZZDG!x r_tƢ!}i/V=M/#nB8 XxЫ ^@CR<{䤭YCN)eKOSƟa $&g[i3.C6xrOc8TI;o hH6P&L{@q6[ Gzp^71j(l`J}]e6X☉#͕ ׈$AB1Vjh㭦IRsqFBjwQ_7Xk>y"N=MB0 ,C #o6MRc0|$)ف"1!ixY<B9mx `,tA>)5ػQ?jQ?cn>YZe Tisvh# GMމȇp:ԴVuږ8ɼH]C.5C!UV;F`mbBk LTMvPʍϤj?ԯ/Qr1NB`9s"s TYsz &9S%U԰> {<ؿSMxB|H\3@!U| k']$U+> |HHMLޢ?V9iD!-@x TIî%6Z*9X@HMW#?nN ,oe6?tQwڱ.]-y':mW0#!J82qFjH -`ѓ&M0u Uγmxϵ^-_\])@0Rt.8/?ٰCY]x}=sD3ojަЫNuS%U}ԤwHH>ڗjܷ_3gN q7[q2la*ArǓԖ+p8/RGM ]jacd(JhWko6ڎbj]i5Bj3+3!\j1UZLsLTv8HHmup<>gKMJj0@H%,W΃7R) ">c, xixј^ aܖ>H[i.UIHc U1=yW\=S*GR~)AF=`&2h`DzT󑓶J+?W+}C%P:|0H܆}-<;OC[~o.$~i}~HQ TvXΈr=b}$vizL4:ȰT|4~*!oXQR6Lk+#t/g lԁߖ[Jڶ_N$k*". xsxX7jRVbAAʯKҎU3)zSNN _'s?f)6X!%ssAkʱ>qƷb hg %n ~p1REGMHH=BJiy[<5 ǁJҖgKR*倳e~HUy)Ag,K)`Vw6bRR:qL#\rclK/$sh*$ 6덤 KԖc 3Z9=Ɣ=o>X Ώ"1 )a`SJJ6k(<c e{%kϊP+SL'TcMJWRm ŏ"w)qc ef꒵i?b7b('"2r%~HUS1\<(`1Wx9=8HY9m:X18bgD1u ~|H;K-Uep,, C1 RV.MR5άh,tWO8WC$ XRVsQS]3GJ|12 [vM :k#~tH30Rf-HYݺ-`I9%lIDTm\ S{]9gOڒMNCV\G*2JRŨ;Rҏ^ڽ̱mq1Eu?To3I)y^#jJw^Ńj^vvlB_⋌P4x>0$c>K†Aļ9s_VjTt0l#m>E-,,x,-W)سo&96RE XR.6bXw+)GAEvL)͞K4$p=Ũi_ѱOjb HY/+@θH9޼]Nԥ%n{ &zjT? Ty) s^ULlb,PiTf^<À] 62R^V7)S!nllS6~͝V}-=%* ʻ>G DnK<y&>LPy7'r=Hj 9V`[c"*^8HpcO8bnU`4JȪAƋ#1_\ XϘHPRgik(~G~0DAA_2p|J묭a2\NCr]M_0 ^T%e#vD^%xy-n}-E\3aS%yN!r_{ )sAw ڼp1pEAk~v<:`'ӭ^5 ArXOI驻T (dk)_\ PuA*BY]yB"l\ey hH*tbK)3 IKZ򹞋XjN n *n>k]X_d!ryBH ]*R 0(#'7 %es9??ښFC,ՁQPjARJ\Ρw K#jahgw;2$l*) %Xq5!U᢯6Re] |0[__64ch&_}iL8KEgҎ7 M/\`|.p,~`a=BR?xܐrQ8K XR2M8f ?`sgWS%" Ԉ 7R%$ N}?QL1|-эټwIZ%pvL3Hk>,ImgW7{E xPHx73RA @RS CC !\ȟ5IXR^ZxHл$Q[ŝ40 (>+ _C >BRt<,TrT {O/H+˟Pl6 I B)/VC<6a2~(XwV4gnXR ϱ5ǀHٻ?tw똤Eyxp{#WK qG%5],(0ӈH HZ])ג=K1j&G(FbM@)%I` XRg ʔ KZG(vP,<`[ Kn^ SJRsAʠ5xՅF`0&RbV tx:EaUE/{fi2;.IAwW8/tTxAGOoN?G}l L(n`Zv?pB8K_gI+ܗ #i?ޙ.) p$utc ~DžfՈEo3l/)I-U?aԅ^jxArA ΧX}DmZ@QLےbTXGd.^|xKHR{|ΕW_h] IJ`[G9{).y) 0X YA1]qp?p_k+J*Y@HI>^?gt.06Rn ,` ?);p pSF9ZXLBJPWjgQ|&)7! HjQt<| ؅W5 x W HIzYoVMGP Hjn`+\(dNW)F+IrS[|/a`K|ͻ0Hj{R,Q=\ (F}\WR)AgSG`IsnAR=|8$}G(vC$)s FBJ?]_u XRvύ6z ŨG[36-T9HzpW̞ú Xg큽=7CufzI$)ki^qk-) 0H*N` QZkk]/tnnsI^Gu't=7$ Z;{8^jB% IItRQS7[ϭ3 $_OQJ`7!]W"W,)Iy W AJA;KWG`IY{8k$I$^%9.^(`N|LJ%@$I}ֽp=FB*xN=gI?Q{٥4B)mw $Igc~dZ@G9K X?7)aK%݅K$IZ-`IpC U6$I\0>!9k} Xa IIS0H$I H ?1R.Чj:4~Rw@p$IrA*u}WjWFPJ$I➓/6#! LӾ+ X36x8J |+L;v$Io4301R20M I$-E}@,pS^ޟR[/s¹'0H$IKyfŸfVOπFT*a$I>He~VY/3R/)>d$I>28`Cjw,n@FU*9ttf$I~<;=/4RD~@ X-ѕzἱI$: ԍR a@b X{+Qxuq$IЛzo /~3\8ڒ4BN7$IҀj V]n18H$IYFBj3̵̚ja pp $Is/3R Ӻ-Yj+L;.0ŔI$Av? #!5"aʄj}UKmɽH$IjCYs?h$IDl843.v}m7UiI=&=0Lg0$I4: embe` eQbm0u? $IT!Sƍ'-sv)s#C0:XB2a w I$zbww{."pPzO =Ɔ\[ o($Iaw]`E).Kvi:L*#gР7[$IyGPI=@R 4yR~̮´cg I$I/<tPͽ hDgo 94Z^k盇΄8I56^W$I^0̜N?4*H`237}g+hxoq)SJ@p|` $I%>-hO0eO>\ԣNߌZD6R=K ~n($I$y3D>o4b#px2$yڪtzW~a $I~?x'BwwpH$IZݑnC㧄Pc_9sO gwJ=l1:mKB>Ab<4Lp$Ib o1ZQ@85b̍ S'F,Fe,^I$IjEdù{l4 8Ys_s Z8.x m"+{~?q,Z D!I$ϻ'|XhB)=…']M>5 rgotԎ 獽PH$IjIPhh)n#cÔqA'ug5qwU&rF|1E%I$%]!'3AFD/;Ck_`9 v!ٴtPV;x`'*bQa w I$Ix5 FC3D_~A_#O݆DvV?<qw+I$I{=Z8".#RIYyjǪ=fDl9%M,a8$I$Ywi[7ݍFe$s1ՋBVA?`]#!oz4zjLJo8$I$%@3jAa4(o ;p,,dya=F9ً[LSPH$IJYЉ+3> 5"39aZ<ñh!{TpBGkj}Sp $IlvF.F$I z< '\K*qq.f<2Y!S"-\I$IYwčjF$ w9 \ߪB.1v!Ʊ?+r:^!I$BϹB H"B;L'G[ 4U#5>੐)|#o0aڱ$I>}k&1`U#V?YsV x>{t1[I~D&(I$I/{H0fw"q"y%4 IXyE~M3 8XψL}qE$I[> nD?~sf ]o΁ cT6"?'_Ἣ $I>~.f|'!N?⟩0G KkXZE]ޡ;/&?k OۘH$IRۀwXӨ<7@PnS04aӶp.:@\IWQJ6sS%I$e5ڑv`3:x';wq_vpgHyXZ 3gЂ7{{EuԹn±}$I$8t;b|591nءQ"P6O5i }iR̈́%Q̄p!I䮢]O{H$IRϻ9s֧ a=`- aB\X0"+5"C1Hb?߮3x3&gşggl_hZ^,`5?ߎvĸ%̀M!OZC2#0x LJ0 Gw$I$I}<{Eb+y;iI,`ܚF:5ܛA8-O-|8K7s|#Z8a&><a&/VtbtLʌI$I$I$I$I$I$IRjDD%tEXtdate:create2022-05-31T04:40:26+00:00!Î%tEXtdate:modify2022-05-31T04:40:26+00:00|{2IENDB`Mini Shell

HOME


Mini Shell 1.0
DIR:/bin/
Upload File :
Current File : //bin/thumbpdf
eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' && eval 'exec perl -S $0 $argv:q'
  if 0;
use strict;
$^W=1; # turn warning on
#
# thumbpdf.pl
#
# Copyright (C) 1999-2012 Heiko Oberdiek.
#
# This work may be distributed and/or modified under the
# conditions of the LaTeX Project Public License, either version 1.3
# of this license or (at your option) any later version.
# The latest version of this license is in
#   http://www.latex-project.org/lppl.txt
# and version 1.3 or later is part of all distributions of LaTeX
# version 2003/12/01 or later.
#
# This work has the LPPL maintenance status "maintained".
#
# This Current Maintainer of this work is Heiko Oberdiek.
#
# See file "readme.txt" for a list of files that belong to this project.
#
# This file "thumbpdf.pl" may be renamed to "thumbpdf"
# for installation purposes.
#
my $file        = "thumbpdf.pl";
my $program     = uc($&) if $file =~ /^\w+/;
my $prj         = 'thumbpdf';
my $version     = "3.15";
my $date        = "2012/04/18";
my $author      = "Heiko Oberdiek";
my $copyright   = "Copyright (c) 1999-2012 by $author.";
#
# Reqirements: Perl5, Ghostscript
# History:
#   1999/02/14 v1.0: First release.
#   1999/02/23 v1.1:
#    * Looking for the media box to calculate the resolution
#      for Ghostscript
#    * new option --resolution
#   1999/03/01 v1.2:
#    * optimization: indirect objects for length values removed.
#    * "first line" from epstopdf
#   1999/03/12 v1.3:
#    * Copyright: LPPL
#   1999/05/05 v1.4:
#    * Detecting of cygwin32 environment.
#    * Minor corrections of output of error messages.
#    * Sharing RGB objects.
#   1999/06/13 v1.5:
#    * gs detection extended.
#   1999/07/27 v1.6
#   1999/08/08 v1.7:
#    * \immediate before \pdfobj (pdfTeX 0.14a)
#   1999/09/09 v1.8
#   1999/09/06 v1.9:
#    * Check for direct /Length values (for jpg images)
#   2000/01/11 v1.10:
#    * Bug fix: /Length (direct) as last entry.
#    * Direct /Length in RGB objects supported.
#   2000/01/19 v1.11:
#    * "for (my $j=0;...;...)"  replaced by "my $j; for($j=0;...;...)",
#      because there exist perl versions that have problems with.
#   2000/02/11 v1.12:
#    * Option `clean' added.
#    * The name of thumbnail data file: jobname.tnd,
#      if thumbpdf is called: thumbpdf jobname[.pdf] [options]
#   2000/02/22 v2.0:
#    * pdfmark support for dvips/ps2pdf route added.
#    * <jobname>.tpt replaces thumbdta.tex (for pdfTeX)
#      <jobname>.tpm (for pdfmark)
#      <jobname>.top replaces thumbopt.tex
#    * Options `useps', `modes' added,
#      `makedef' renamed to `makedata'.
#   2000/02/28 v2.1:
#    * Environment variable `THUMBPDF' supported.
#   2000/03/07 v2.2:
#    * Support for Distiller 3 and 4, the streams are uncompressed.
#    * Call of gs is changed in order to show the currently processed
#      page number of the pdf file.
#    * Option --printgscmd creates the command line file `thumbpdf.gs'
#      for the Ghostscript call.
#   2000/03/22 v2.3:
#    * Bug fix: --useps now works.
#   2000/04/10 v2.4:
#    * Fix for ActiveState Perl 5.6.0: uc line changed, fork removed.
#      (Thanks to Andreas Buehmann <andreas.buehmann@gmx.de>.)
#    * Version test for thumbpdf.tex added for users that
#      mix versions, sigh.
#   2000/07/29 v2.5:
#    * `save' trick in call of ghostscript.
#    * Undocumented option --gspages added.
#   2000/09/27 v2.6
#   2000/10/27 v2.7:
#    * -dFIXEDMEDIA=0 added in gs call
#   2001/01/12 v2.8:
#    * Bug fix in dvips mode and active option `level2':
#      pack parameter corrected for little-endian machines.
#    * /Rotate in pdf pages:
#      ghostscript versions around 6.01 have added a hack
#      in /pdfshowpage_setpage, that ignores the /Rotate entry.
#      A patch is added to disable the hack.
#    * Ghostscript uses the MediaBox for calculating the
#      page size. For version 6.50 a patch is added to use
#      the /CropBox instead.
#   2001/03/29 v2.9:
#    * Option --password added.
#   2001/04/02 v2.10
#   2001/04/26 v2.11
#    * Option --antialias added (suggestion of Juergen Bausa).
#   2002/01/11 v3.0
#    * Syntax of option --antialias changed (see readme.txt).
#    * Support for VTeX's PS mode added.
#    * Greek mode added (see readme.txt).
#    * Signal handlers added for cleanup.
#   2002/05/26 v3.1
#    * SIG_HUP unkown in Windows.
#    * Bug fix: The signal function for __DIE__ "cleanup" aborts
#      before the error message of "die" is printed.
#      Replaced by "clean" that does not contain "exit 1".
#    * Small bug fix in mode detection and mode "vtex"
#      removed from list. "vtexpdfmark" was detected,
#      "vtex" did not work and perhaps it will be used
#      later for VTeX in PDF mode.
#   2002/05/26 v3.2
#    * Fix: "MacOS/X: darwin" is now not interpreted as
#      Windows.
#   2003/03/19 v3.3
#    * Fix for gs 8.00 in mode dvips:
#      THB_DistillerPatch also applied to ghostscript >= 8.00.
#   2003/06/06 v3.4
#    * Bug fix, two forgotten "pop"s added for Distiller case.
#   2004/10/24 v3.5
#    * Revert Cygwin detection: is unix (request by Jan Nieuwenhuizen).
#    * LPPL 1.3.
#   2004/11/19 v3.6
#    * Bug fix for dvips mode and gs < 8.00 (/stackunderflow in pop).
#   2004/11/19 v3.7:
#    * For easier debugging, the special thumbpdf objects of
#      thumbpdf.pdf are now valid PDF objects (dictionaries).
#    * Remove of extra '\n' before "endstream" that is added
#      by pdfTeX 1.20a.
#   2005/07/06 v3.8:
#    * Fix because of pdfTeX 1.30.
#   2007/11/07 v3.9:
#    * Deprecation warning of perl 5.8.8 fixed.
#   2008/04/16 v3.10
#   2010/07/07 v3.11
#    * \input is used with file name extension for "thumbpdf.tex".
#   2011/08/10 v3.13
#    * Use gswin64c in Windows with 64 bits.
#   2012/04/09 v3.14
#   2012/04/18 v3.15
#    * Option --version added.
#

### program identification
my $title = "$program $version, $date - $copyright\n";

### error strings
my $Error = "!!! Error:"; # error prefix

### string constants for Ghostscript run
# get Ghostscript command name
my $GS = "gs";
$GS = "gs386"    if $^O =~ /dos/i;
$GS = "gsos2"    if $^O =~ /os2/i;
if ($^O =~ /mswin32c/i) {
    # http://perldoc.perl.org/perlport.html#DOS-and-Derivatives
    use Config;
    $GS = "gswin32c";
    $GS = "gswin64c" if $Config{'archname'} =~ /mswin32-x64/i;
}

# Windows detection (no SIGHUP)
my $Win = 0;
$Win = 1 if $^O =~ /mswin32/i;

my $gspages = 1;
$gspages = 0 if $^O =~ /dos/i;

### variables
my $jobname      = "";
my $jobfile      = "";
my $pdftexfile   = "";
my $pdfmarkfile  = "";
my $psext        = ".ps";
my $pdfext       = ".pdf";
my $pdftexext    = ".tpt";
my $pdfmarkext   = ".tpm";
my $thumbprefix  = "thb";
my $envvar       = "THUMBPDF";
my $pdffile      = "thumbpdf.pdf";
my $logfile      = "thumbpdf.log";
my $texfile      = "thumbpdf.tex";
my $package      = "thumbpdf.sty";
my $readme       = "readme.txt";
my $gscnffile    = "thumbpdf.gs";
my $gssection    = "section I. `Known Problems'";
my @cleanlist    = ();
my $resolution   = 9;
my $mode_pdftex  = 0;
my $mode_pdfmark = 0;
my $antialias_default = "4";
my @arglist      = @ARGV;
my $gskidrunning = 0;

### option variables
my @bool = ("false", "true");
$::opt_device     = "png16m";
$::opt_compress   = "10";
$::opt_resolution = "";
$::opt_modes      = "pdftex";
$::opt_gscmd      = "";
$::opt_level2     = 0;
$::opt_help       = 0;
$::opt_version    = 0;
$::opt_quiet      = 0;
$::opt_debug      = 0;
$::opt_verbose    = 0;
$::opt_useps      = 0;
$::opt_printgscmd = 0;
$::opt_gspages    = $gspages; # undocumented
$::opt_makepng    = 1;
$::opt_makepdf    = 1;
$::opt_makedata   = 1;
$::opt_clean      = 1;
$::opt_password   = "";
$::opt_antialias  = $antialias_default;
$::opt_greek      = 0;

my $usage = <<"END_OF_USAGE";
${title}Syntax:   \L$program\E [options] <jobname[.pdf|.ps]>
Function: Support of thumbnails for pdfTeX or dvips/ps2pdf (pdfmark).
          Thumbnails are generated by Ghostscript and the result is
          written to data files for package `$package':
          `<jobname>$pdftexext' (pdfTeX), `<jobname>$pdfmarkext' (pdfmark)
Options:                                                         (defaults:)
  --help          print usage
  --version       print version number
  --(no)quiet     suppress messages                              ($bool[$::opt_quiet])
  --(no)verbose   verbose printing                               ($bool[$::opt_verbose])
  --(no)debug     debug informations                             ($bool[$::opt_debug])
  --(no)makepng   make thumbnails `$thumbprefix*.png'                     ($bool[$::opt_makepng])
  --(no)makepdf   make `$pdffile' with thumbnails as images  ($bool[$::opt_makepdf])
  --(no)makedata  make data file(s) for package `$package'   ($bool[$::opt_makedata])
  --(no)clean     clear temp files                               ($bool[$::opt_clean])
  --(no)useps     `makepng' uses `.ps' instead of `.pdf' file    ($bool[$::opt_useps])
  --(no)level2    `<jobname>.tpm' with ps level 2 features       ($bool[$::opt_level2])
  --(no)greek     text in greek style (experimental)             ($bool[$::opt_greek])
  --gscmd <name>  call of ghostscript                            ($GS)
  --antialias <num1>[num2] anti-aliasing, 0 = disable, 4 = max   ($::opt_antialias)
  --device|png [png]<dev>  Ghostscript device for thumbnails,
                           dev = mono, gray, 16, 256, 16m        ($::opt_device)
  --resolution <res>       thumbnail resolution for makepng      ($resolution)
  --compress <n>           thumbnail compress level, n = 0..10   ($::opt_compress)
  --modes <mode>[,mode]    mode=pdftex|pdfmark|dvips|ps2pdf|
                                vtexpdfmark|all                  ($::opt_modes)
  --password <password>    for an encrypted pdf file             ($::opt_password)
END_OF_USAGE

### environment variable THUMBPDF
if ($ENV{$envvar}) {
  unshift(@ARGV, split(/\s+/, $ENV{$envvar}));
}

### process options
my @OrgArgv = @ARGV;
use Getopt::Long;
GetOptions(
  "help!",
  "version!",
  "quiet!",
  "debug!",
  "verbose!",
  "device|png=s",
  "gscmd=s",
  "level2!",
  "compress=i",
  "resolution=f",
  "modes=s",
  "useps!",
  "printgscmd!",
  "gspages!",
  "makepng!",
  "makepdf!",
  "makedata!",
  "clean!",
  "password=s",
  "antialias=s",
  "greek!"
) or die $usage;
!$::opt_help or die $usage;
if ($::opt_version) {
    print "$prj $date v$version\n";
    exit(0);
}
@ARGV < 2 or die "$usage$Error Too many files!\n";
@ARGV == 1 or die "$usage$Error Missing jobname!\n";

$::opt_device = "png$::opt_device" unless $::opt_device =~ /^png/;
$::opt_quiet = 0 if $::opt_verbose;
$::opt_clean = 0 if $::opt_debug or !$::opt_makepdf or !$::opt_makedata;

$::opt_compress = 0 if $::opt_compress < 0;
$::opt_compress = 10 if $::opt_compress > 10;
my $J = "^^J";
$J = "" if $::opt_compress == 10;

$::opt_antialias = $antialias_default if $::opt_antialias eq "";
$::opt_antialias =~ /^[0124][0124]?$/ or
  die "$usage$Error Wrong value for option --antialias!\n";
$::opt_antialias .= $::opt_antialias if length($::opt_antialias) < 2;
my $AntiAliasText     = substr($::opt_antialias, 0, 1);
my $AntiAliasGraphics = substr($::opt_antialias, 1, 1);
$AntiAliasText     = "1" if $AntiAliasText     eq "0";
$AntiAliasGraphics = "1" if $AntiAliasGraphics eq "0";

$GS = $::opt_gscmd if $::opt_gscmd;
$gspages = $::opt_gspages;

### get modes
$::opt_modes = "\L$::opt_modes\E";
$::opt_modes =~ s/dvips/pdfmark/g;
$::opt_modes =~ s/ps2pdf/pdfmark/g;
$::opt_modes =~ s/vtexpdfmark/pdfmark/g;
$::opt_modes =~ s/vtexpdfmark/pdfmark/g;
if ($::opt_modes =~ /pdftex/)
{
  $mode_pdftex = 1;
  $::opt_modes =~ s/pdftex//g;
}
if ($::opt_modes =~ /pdfmark/)
{
  $mode_pdfmark = 1;
  $::opt_modes =~ s/pdfmark//g;
}
if ($::opt_modes =~ /all/)
{
  $mode_pdftex = 1;
  $mode_pdfmark = 1;
  $::opt_modes =~ s/all//g;
}
$::opt_modes =~ s/\s+//g;
$::opt_modes =~ s/,+/,/g;
$::opt_modes =~ s/^,//;
$::opt_modes =~ s/,$//;
if ($::opt_modes ne "")
{
  die "$usage$Error Unknown mode(s): `$::opt_modes'\n";
}
if ($::opt_makedata)
{
  $mode_pdftex or $mode_pdfmark or
    die "$usage$Error Missing mode!\n";
}

### get jobname
$jobname = $ARGV[0];
if ($::opt_useps)
{
  $jobname =~ s/\.ps$//i;
  $jobname =~ s/\\/\//g;
  $jobfile = $jobname . $psext;
}
else
{
  $jobname =~ s/\.pdf$//i;
  $jobname =~ s/\\/\//g;
  $jobfile = $jobname . $pdfext;
}
$pdftexfile  = $jobname . $pdftexext;
$pdfmarkfile = $jobname . $pdfmarkext;

print $title unless $::opt_quiet;

print "* jobname: `$jobname'\n" if $::opt_verbose;

if ($::opt_debug) {
  print <<"END_DEB";
* OSNAME: $^O
* PERL_VERSION: $]
* ARGV: @OrgArgv
END_DEB
}

### set signals
$SIG{__DIE__} = \&clean;
setsignals(\&cleanup);

my $MaxThumb = 0;

###
### make thumbnails
###
if ($::opt_makepng)
{
  print "*** make png files / run Ghostscript ***\n"
      unless $::opt_quiet or $::opt_printgscmd;
  if ($::opt_useps)
  {
    print "* ps file: $jobfile\n" if $::opt_verbose;
  }
  else
  {
    print "* pdf file: $jobfile\n" if $::opt_verbose;
  }
  print "* Ghostscript command: `$GS'\n" .
        "* Ghostscript png device: `$::opt_device'\n" if $::opt_verbose;

  if ($::opt_resolution)
  {
    $resolution = $::opt_resolution
  }
  else
  {
    # looking for MediaBox

    my $max_x = 0;
    my $max_y = 0;
    {
      my $MB = $jobfile;
      open(MB, $MB) or die "$Error Cannot open `$MB'!\n";
      binmode(MB);
      my $xy_patt = '[\-\.\d]';
      while (<MB>)
      {
        if (/\/MediaBox\s*\[\s*($xy_patt+)\s+($xy_patt+)\s+($xy_patt+)\s+($xy_patt+)\s*\]/)
        {
          my $x = $3 - $1;
          my $y = $4 - $2;
          $max_x = $x if $x > $max_x;
          $max_y = $y if $y > $max_y;
        }
      }
      close(MB);
    }
    if ($max_x <= 0 || $max_y <= 0)
    {
      print "!!! Warning: MediaBox not found, " .
            "using default resolution: $resolution DPI\n";
    }
    else
    {
      print "* Max. Size of MediaBox: $max_x x $max_y\n" if $::opt_verbose;

      my $rx = 106 * 72 / $max_x;
      my $ry = 106 * 72 / $max_y;
      $resolution = $rx;
      $resolution = $ry if $ry < $rx;
      print "* Resolution: $resolution DPI\n" if $::opt_verbose;
    }
  }

# Ghostscript's pdfshowpage_setpage is patched for solving
# some problems:
# * gs6.0* includes a hack that ignores the /Rotate entry
#   in the PDF page, if OutputFile is set.
#   gs6.50 does not need a fix and it is not applied,
#   because pdfshowpage_setpage does not contain /OutputFile.
# * If /CropBox is set, then it should be used instead
#   of the /MediaBox entry. Because the CropBox area should
#   be part of the MediaBox, the MediaBox is overwritten
#   with the CropBox values for generating the thumbnails.
# The fixes are only applied for versions >= 6.0, because
# gs5.50 gets a /PageSize problem with this fix.
#
  my $SetPageHack = <<'SET_PAGE_HACK';
currentglobal true setglobal
false
/product where {
  pop
  product (Ghostscript) search {
    pop pop pop
    revision 600 ge {
      pop true
    } if
  }{pop} ifelse
} if
{ /pdfdict where {
    pop
    pdfdict begin
      /pdfshowpage_setpage
      [ pdfdict /pdfshowpage_setpage get
        { dup type /nametype eq
          { dup /OutputFile eq
            { pop /AntiRotationHack
            }{
              dup /MediaBox eq revision 650 ge and
              { /THB.CropHack {
                  1 index /CropBox pget
                  { 2 index exch /MediaBox exch put
                  } if
                } def
                /THB.CropHack cvx
              } if
            } ifelse
          } if
        } forall
      ] cvx def
    end
  } if
} if
setglobal
SET_PAGE_HACK

  my $Greek = "";
  $Greek = <<'END_GREEK' if $::opt_greek;
currentglobal true setglobal
userdict begin
  % * Patch for `show'
  /THB_ORG_show {show} bind def
  /THB_greekstring
  /.charboxpath where
  {
    pop
    {
      currentpoint newpath moveto
      true .charboxpath closepath fill
    } bind def
  }{
    {
      {
        1 string dup 0 4 -1 roll put
        dup stringwidth pop exch
        true charpath flattenpath pathbbox
        2 index sub exch 3 index sub exch rectfill
        0 rmoveto
      } forall
    } bind def
  } ifelse
  /show {
    currentfont /FontType get 1 eq
    {
      dup
      gsave
        % assuming white background
        [ currentrgbcolor ]
        { 1 add 2 div } forall
        setrgbcolor
        THB_greekstring
      grestore
      stringwidth pop 0 rmoveto
    }{
      THB_ORG_show
    } ifelse
  } bind def

  % * Patch for the PDF case
  userdict /GS_PDF_ProcSet known
  {
    % GS_PDF_ProcSet is readonly, so it will be copied first
    GS_PDF_ProcSet length 10 add dict dup
    GS_PDF_ProcSet {
      put dup
    } forall
    /GS_PDF_ProcSet exch def
    dup
    begin
      % `setshowstate' contains the use of `show', so it has to
      % be overwritten, because it was defined with `bind'.
      % The definition is taken from `pdf_ops.ps'.
      revision 710 lt
      { % 5.50, 6.51, 7.00, 7.02

/setshowstate
 { WordSpacing 0 eq TextSpacing 0 eq and
    { TextRenderingMode 0 eq
       { { setfillstate show } }
       { { false charpath textrenderingprocs TextRenderingMode get exec } }
      ifelse
    }
    { TextRenderingMode 0 eq
       { WordSpacing 0 eq
          { { setfillstate TextSpacing exch 0 exch ashow } }
          { TextSpacing 0 eq
             { { setfillstate WordSpacing exch 0 exch 32 exch widthshow } }
             { { setfillstate WordSpacing exch TextSpacing exch 0 32 4 2 roll 0 exch awidthshow } }
            ifelse
          }
         ifelse
       }
       { { WordSpacing TextSpacing
                        % Implement the combination of t3 and false charpath.
                        % Note that we must use cshow for this, because we
                        % can't parse multi-byte strings any other way.
                        % Stack: string xword xchar
            { pop pop (x) dup 0 3 index put false charpath
                        % Stack: xword xchar ccode
              3 copy 32 eq { add } { exch pop } ifelse 0 rmoveto pop
            }
           4 -1 roll cshow pop pop
           textrenderingprocs TextRenderingMode get exec
         }
       }
      ifelse
    }
   ifelse /Show gput
 } bdef

      }{ % 7.10

/setshowstate
 { WordSpacing 0 eq TextSpacing 0 eq and
    { TextRenderingMode 0 eq
       { { setfillstate show } }
       { { false charpath textrenderingprocs TextRenderingMode get exec } }
      ifelse
    }
    { TextRenderingMode 0 eq
       { WordSpacing 0 eq
          { { setfillstate TextSpacing 0 Vexch 3 -1 roll ashow } }
          { TextSpacing 0 eq
            { { setfillstate WordSpacing 0 Vexch 32 4 -1 roll widthshow } }
            { { setfillstate WordSpacing 0 Vexch 32
                 TextSpacing 0 Vexch 6 -1 roll awidthshow } }
            ifelse
          }
         ifelse
       }
       { { WordSpacing TextSpacing
                        % Implement the combination of t3 and false charpath.
                        % Note that we must use cshow for this, because we
                        % can't parse multi-byte strings any other way.
                        % Stack: string xword xchar
            { pop pop (x) dup 0 3 index put false charpath
                        % Stack: xword xchar ccode
             3 copy 32 eq { add } { exch pop } ifelse 0 Vexch rmoveto pop
            }
           4 -1 roll cshow pop pop
           textrenderingprocs TextRenderingMode get exec
         }
       }
      ifelse
    }
   ifelse /Show gput
 } bdef

      } ifelse
    end
    readonly pop
  } if
end
setglobal
END_GREEK

  my $SetPassword = "";
  $SetPassword = "/PDFPassword($::opt_password)def" if $::opt_password;

  my $PSHeader = "save pop $SetPassword $SetPageHack $Greek";
  $PSHeader =~ s/%\s.*\n/ /g;
  $PSHeader =~ s/\s+/ /g;
  $PSHeader =~ s/\s+([\(\/\[\]\{\}])/$1/g;
  $PSHeader =~ s/([\)\[\]\{\}])\s+/$1/g;
  $PSHeader =~ s/\s+$//;

  my $AntiAlias = "";
  $AntiAlias = "\n-dTextAlphaBits=$AntiAliasText\n" .
               "-dGraphicsAlphaBits=$AntiAliasGraphics"
    if $::opt_antialias;

  my $gs_cmd = <<"GS_CMD_END";
$GS$AntiAlias
-dNOPAUSE
-dBATCH
-sDEVICE=$::opt_device
-r$resolution
-sOutputFile=$thumbprefix%d.png
-c "$PSHeader"
-f $jobfile
GS_CMD_END
  # The trick with `save' comes from `ps2pdf':
  # Doing an initial `save' helps keep fonts from being flushed
  # between pages.

  if ($::opt_printgscmd)
  {
    open(GSCNF, ">$gscnffile") or die "$Error Cannot open `$gscnffile'!\n";
    $gs_cmd =~ s/^[^\r\n]+[\r\n]+//;
    print GSCNF $gs_cmd;
    close(GSCNF);
    my $options = "@arglist";
    $options =~ s/\s*--?pr[intgscmd]*\s*/ /i;
    $options =~ s/^\s+//;
    $options =~ s/\s+$//;
    print <<"END_PERL" if $::opt_verbose;
* Perl interpreter: $^X
* Perl script: $0
END_PERL
    print <<"END_GS";
1. Run `Ghostscript' manually:
   ==> $GS \@$gscnffile
2. Call `thumbpdf' again with the additional option `--nomakepng':
   ==> thumbpdf --nomakepng $options
END_GS
    exit(0);
  }

  chomp($gs_cmd);
  $gs_cmd =~ s/\n/ /mg;
  print "> $gs_cmd\n" if $::opt_verbose;

  if ($::opt_debug)
  {
    if ($gspages)
    {
      print "* Ghostscript with page numbers\n";
    }
    else
    {
      print "* Ghostscript without page numbers\n";
    }
  }

  setsignals(\&gscleanup);
  my $capture = "";
  if ($gspages)
  {
    my $newline = 0;
    open(KID, "$gs_cmd|") or die "$Error Cannot open Ghostscript ($!)!\n";
    *::GSKID = *KID;
    $gskidrunning = 1;
    my $orgbar = $|;
    $|=1;
    while (<KID>)
    {
      $capture .= $_;
      if ($::opt_verbose)
      {
        print;
      }
      else
      {
        if (!$::opt_quiet)
        {
          print if /^Processing pages/;
          if (/^Page\s+(\d+)/)
          {
            print " " if $newline;
            $newline = 1;
            print "[$1]";
          }
        }
      }
    }
    $gskidrunning =0;
    if (!close(KID))
    {
      if ($!)
      {
        die "$Error Closing Ghostscript ($!)!\n";
      }
      else
      {
        my $exitvalue = $? >> 8;
        die "$Error Closing Ghostscript (exit status: $exitvalue)!\n";
      }
    }
    print "\n" if $newline;
    $| = $orgbar;
  }
  else # without pages
  {
    $capture = `$gs_cmd`;
    if (!defined($capture))
    {
      die "$Error Cannot execute Ghostscript!\n";
    }
    print $capture if $::opt_verbose;
  }

  if ($capture =~ /Error:\s*(.*)\n/)
  {
    die <<"END_DIE";
$Error `$1' (Ghostscript)!
See `$readme', $gssection, for further information.
END_DIE
  }
  if ($capture =~ /Unknown device:\s*(.*)\n/)
  {
    die "$Error Unknown device `$1' (Ghostscript)!\n";
  }
  if ($?)
  {
    my $exitvalue = $?;
    if ($exitvalue > 255)
    {
      $exitvalue >>= 8;
      die "$Error Closing Ghostscript (exit status: $exitvalue)!\n";
    }
    die "$Error Closing Ghostscript ($exitvalue)!\n";
  }
  if ($capture =~ /Processing pages \d+ through (\d+)./)
  {
    $MaxThumb = $1;
  }
  print "* max. page: $MaxThumb\n" if $::opt_debug;
  setsignals(\&cleanup);
}

###
### make thumbpdf.pdf file
###
if ($::opt_makepdf)
{
  print "*** make `$pdffile' / run pdfTeX ***\n" unless $::opt_quiet;

  if ($MaxThumb > 0)
  {
    my $i;
    for ($i=1; $i<=$MaxThumb; $i++)
    {
      push(@cleanlist, "$thumbprefix$i.png");
    }
  }
  else
  {
    # get max thumb number to speed up the pdfTeX run
    $MaxThumb = 0;
    foreach (glob("$thumbprefix*.png"))
    {
      next unless /$thumbprefix(\d+).png/;
      $MaxThumb = $1 if $1 > $MaxThumb;
      push(@cleanlist, $_);
    }
  }

  push(@cleanlist, $logfile);
  push(@cleanlist, $pdffile);

  my $compress = $::opt_compress;
  $compress = 9 if $::opt_compress == 10;
  my $cmd = "pdftex \"" .
            "\\nonstopmode" .
            "\\pdfcompresslevel$compress" .
            "\\def\\thumbjob{$jobname}" .
            "\\def\\thumbmax{$MaxThumb}" .
            "\\input $texfile" .
            "\"";
  print "> $cmd\n" if $::opt_verbose;
  my @capture = `$cmd`;
  if (!@capture)
  {
    die "$Error Cannot execute pdfTeX!\n";
  }
  if ($::opt_verbose)
  {
    print @capture;
  }
  else
  {
    foreach (@capture)
    {
      print if /^!\s/;
    }
  }
  if ($?)
  {
    my $exitvalue = $?;
    if ($exitvalue > 255)
    {
      $exitvalue >>= 8;
      die "$Error Closing pdfTeX (exit status: $exitvalue)!\n";
    }
    die "$Error Closing pdfTeX ($exitvalue)!\n";
  }
  # test version
  my $versionfound = 0;
  foreach (@capture)
  {
    if (/File:.*thumbpdf.*(\d\d\d\d\/\d\d\/\d\d)\s+v(\d+\.\d+)/)
    {
      $versionfound = 1;
      if ($1 ne $date or $2 ne $version) {
        print <<"END_WARN";
!!! Warning: Version of `thumbpdf.tex' does not match with perl script!
    Current `thumbpdf.tex': $1 v$2
    Please install version: $date v$version
END_WARN
      }
    }
  }
  print "!!! Warning: Version of `thumbpdf.tex' not found!\n"
    if !$versionfound;

  $_ = pop(@cleanlist);
}

###
### parse thumbpdf.pdf
###

if ($::opt_makedata)
{
  push(@cleanlist, $pdffile);

  print "*** parse `$pdffile' ***\n" unless $::opt_quiet;

### reading file and parse obj structure

  my @objno = (); # obj number
  my @objdict = (); # boolean, object is dict
  my @objtext = (); # text of object
  my @objstream = (); # stream of object if any
  my $maxobj = 0;

  my @getobjindex = (); # $getobj[obj number] ==> index for $obj...[index]

  # open file
  my $PDF = $pdffile;
  open(PDF, $PDF) or die "$Error Cannot open `$PDF'!\n";
  binmode(PDF);
  my $lineno = 0;

  # read header
  $_ = <PDF>; $lineno++;
  $_ or die "$Error Cannot read header of `$PDF' or file is empty!\n";
  /^%PDF/ or die "$Error No PDF specification found!\n";
  print "* pdf header: $_" if ($::opt_debug);

  # read body objects
  my $count = 0;
  while (<PDF>)
  {
    $lineno++;

    # continue, if comment line (2nd line of PDF output by pdfTeX 1.30)
    next if /^%/;

    # stop at xref
    last if /^xref$/;

    # scan first obj line
    /^(\d+)\s+0\s+obj\s*(<<)?$/ or
      die "$Error `obj' expected on line $lineno!\n";
    $objno[$count] = $1;
    $getobjindex[$1] = $count;
    $objdict[$count] = ($2); # boolean (if $2 exists)
    my $stream = 0;
    print "* obj $objno[$count]" .
      (($objdict[$count]) ? " (dict)" : "") .
      "\n" if $::opt_debug;

    # get obj
    $objtext[$count] = "";
    while (<PDF>)
    {
      $lineno++;

      if ($objdict[$count])
      {
        if (/^>>/)
        {
          last if /^>>\s+endobj$/; # obj without stream

          # get stream
          $_ = <PDF>; $lineno++;
          /^stream$/ or die "$Error `stream' expected on line $lineno!\n";

          print "* stream\n" if $::opt_debug;
          $objstream[$count] = "";
          while (<PDF>)
          {
            $lineno++;

            if (/(.*)endstream$/)
            {
              $objstream[$count] .= $1;
              last;
            }
            $objstream[$count] .= $_;
          }

          $_ = <PDF>; $lineno++;
          /^endobj$/ or die "$Error `endobj' expected on line $lineno!\n";
          last;
        }
      }
      else # no dict
      {
        last if /^endobj$/;
      }
      $objtext[$count] .= $_;
    }
    $count++;
  }
  close(PDF);
  $maxobj = $count;
  print "* $maxobj objects found.\n" if $::opt_debug;

### get thumbnail page numbers
  my @thumbpageno = ();
  my $found = 0;
  foreach (@objtext)
  {
    if (/^<<\/ListThumbs\s+(.+)>>$/)
    {
      $_ = $1;
      chomp;
      @thumbpageno = split / /; # split(/ /, $_);
      print "* ListThumbs: @thumbpageno\n" if $::opt_debug;
      $found = 1;
      last;
    }
  }
  $found or die "$Error `/ListThumbs' not found!\n";
  {
    my $j;
    for ($j=0; $j<@thumbpageno; $j++)
    {
      $thumbpageno[$j] = $1 if $thumbpageno[$j] =~ /^{(.+)}$/;
    }
  }

### identify thumb objects

  my @thumbobj = ();    # index for @obj... with image stream
  my @thumblength = (); # stream length values
  my @thumbrgbobj = (); # index for @obj... with rgb stream
  my @thumbrgblength = (); # rgb stream length values
  my $maxthumb = 0;

  $count = 0;
  my $i;
  for ($i=0; $i<$maxobj; $i++)
  {
    if ($objtext[$i] =~
        /^\/Type\s+\/XObject\n\/Subtype\s+\/Image\n/m)
    {
      $thumbobj[$count] = $i;
      $_ = $';
      $objtext[$i] = $_;

      # check width and height
      /\/Width\s+(\d+)\n\/Height\s+(\d+)/m or
        die "$Error width/height of thumbnail not found!\n";
      print "* Size: $1x$2\n" if $::opt_debug;
      print "==> Width ($1) " .
            "of thumbnail `$thumbpageno[$count]' " .
            "is larger than recommended (106).\n"
        if $1 > 106;
      print "==> Height ($2) " .
            "of thumbnail `$thumbpageno[$count]' " .
            "is larger than recommended (106).\n"
        if $2 > 106;

      # get stream length
      if (/\/Length\s+(\d+)\s+([\/\>]|$)/m)
      {
        $thumblength[$count] = $1;
        print "* Length (direct): $1\n" if $::opt_debug;
        # remove whitespace after length obj
        $objtext[$i] =~ s/(\/Length\s+\d+)\s+\n/$1\n/;
      }
      else # looking for indirect reference
      {
        /\/Length\s+(\d+)\s+0\s+R/m or
          die "$Error `/Length' entry not found!\n";
        # save obj text for later correction
        my $objpre = $`;
        my $objpost = $';
        # look for length obj
        $getobjindex[$1] or die "$Error Length obj not found!\n";
        $objtext[$getobjindex[$1]] =~ /^(\d+)$/m or
          die "$Error length value not found!\n";
        $thumblength[$count] = $1;
        print "* Length (indirect): $1\n" if $::opt_debug;
        # insert obj length directly:
        $objtext[$i] = $objpre . "/Length $1" . $objpost;
      }

      # remove \n from end of stream
      if ($thumblength[$count] < length($objstream[$i])) {
        chop($objstream[$i]);
      }

      # check /Indexed /DeviceRGB
      if ($objtext[$i] =~
        /\/ColorSpace\s+\[\/Indexed\s+\/DeviceRGB\s+(\d+)\s+(\d+)\s+0\s+R\]/m)
      {
        # correct thumb object text
        $objtext[$i] =
          "$`/ColorSpace [/Indexed /DeviceRGB $1 \\the\\pdflastobj\\ 0 R]$'";
        # get RGB obj number
        $getobjindex[$2] or die "$Error RGB object not found!\n";
        $_ = $getobjindex[$2];
        $thumbrgbobj[$count] = $_;
        # get stream length
        if ($objtext[$_] =~ /\/Length\s+(\d+)\s+([\/\>]|$)/m)
        {
          $thumbrgblength[$count] = $1;
          print "* RGB length (direct): $1\n" if $::opt_debug;
          $objtext[$_] =~ s/(\/Length\s+\d+)\s+\n/$1\n/;
        }
        else # looking for indirect reference
        {
          $objtext[$_] =~ /\/Length\s+(\d+)\s+0\s+R/m or
            die "$Error Length entry of rgb object not found\n";
          # save obj text for later correction
          my $objrgbpre = $`;
          my $objrgbpost = $';
          # get rgb stream length
          $getobjindex[$1] or die "$Error RGB length object not found!\n";
          $objtext[$getobjindex[$1]] =~ /^(\d+)$/m or
            die "$Error length value not found!\n";
          $thumbrgblength[$count] = $1;
          print "* RGB length (indirect): $1\n" if $::opt_debug;
          # insert RGB object length directly:
          $objtext[$_] = $objrgbpre . "/Length $1" . $objrgbpost;
        }
      }

      $count++;
    }
  }
  $maxthumb = $count;

  if ($maxthumb != @thumbpageno)
  {
    my $pagecount = @thumbpageno;
    die "$Error $maxthumb thumbnails found, but there should be $pagecount!\n";
  }
  print "* $maxthumb thumbnails found.\n" if $::opt_verbose;


###
### write data files
###

  my $timestamp;
  {
    my ($sec, $min, $hour, $mday, $mon, $year) = localtime();
    $mon++;
    $year += 1900;
    $timestamp = sprintf("%04d/%02d/%02d %02d:%02d:%02d",
      $year, $mon, $mday, $hour, $min, $sec);
  }
  if ($mode_pdftex)
  {
    print "*** write `$pdftexfile' (pdfTeX thumbnail data) ***\n"
      unless $::opt_quiet;
    my $DTA_PT = $pdftexfile;
    open(DTA_PT, ">$DTA_PT") or die "$Error Cannot open `$DTA_PT'!\n";
    binmode(DTA_PT);
    print DTA_PT <<"END_DTA";
% File: $DTA_PT
% Producer: $program $version
% Mode: pdftex
% Date: $timestamp
END_DTA
  }
  my $maxpagethumb;
  my $dictbegin;
  if ($mode_pdfmark)
  {
    print "*** write `$pdfmarkfile' (pdfmark thumbnail data) ***\n"
      unless $::opt_quiet;
    my $DTA_PM = $pdfmarkfile;
    open(DTA_PM, ">$DTA_PM") or die "$Error Cannot open `$DTA_PM'!\n";
    binmode(DTA_PM);

    # write tex part
    print DTA_PM <<"END_DTA";
% \\iffalse
% File: $DTA_PM
% Producer: $program $version
% Mode: pdfmark
% Date: $timestamp
% \\fi
END_DTA

    # looking for max. number of regular thumbnails
    $maxpagethumb = $maxthumb;
    for ($i=0; $i<$maxobj; $i++)
    {
      if ($objtext[$i] =~ /<<\/MaxThumbNumber\s+(\d+)>>/)
      {
        $maxpagethumb = $1;
        last;
      }
    }

    # write TeX part
    for ($i=$maxpagethumb; $i<$maxthumb; $i++)
    {
      print DTA_PM "% \\DefThisThumb{$thumbpageno[$i]}\n";
    }

    # write PostScript header
    my $dictstart = <<'END_DICT';
  4 dict begin
  /enddict {
    counttomark 2 idiv dup dict begin {def} repeat pop
    currentdict end
  } bind def
END_DICT
    chomp($dictstart);
    $dictbegin = "[";
    my $dictend = "enddict";
    my $filter = "";
    my $read = "readhexstring";
    if ($::opt_level2)
    {
      $dictstart = "  3 dict begin";
      $dictbegin = "<<";
      $dictend = ">>";
      $filter = " /ASCII85Decode filter";
      $read = "readstring";
    }

    print DTA_PM <<"END_DTA";
% \\endinput
% TeX part ends here

% PostScript definitions
END_DTA

    my $PS_Header = <<"END_HEAD";
%
% Default definition of pdfmark
/pdfmark where {pop} {userdict /pdfmark /cleartomark load put} ifelse
%
% Check the version of Ghostscript. If it is below 6.0,
% the commands, that produce the thumbnails, are defined
% to be dummies.
%
true
/product where {
  pop
  product (Ghostscript) search {
    pop pop pop
    revision 600 lt {
      (!!! Warning (thumbpdf): Ghostscript 6.0 required for thumbnails!\\n)
      print pop false
    } if
  }{pop} ifelse
} if
{
% Syntax: <thumb object> thisTHB -
% thisTHB is used globally, so it is defined in the current
% dictionary (perhaps userdict should explicitly be set).
  /thisTHB {[ exch /Thumb exch /PAGE pdfmark} bind def
$dictstart
% Syntax: <page object> <thumb object> pagethumb -
  /pagethumb {
    [ 3 1 roll $dictbegin exch /Thumb exch $dictend /PUT pdfmark
  } bind def
% Syntax: <thumb object> <stream length>
%         <mark> <key value pairs> streamobj -
%
% Distiller ignores the compression of previously compressed
% streams and uses its own settings. Therefore for Distiller
% the streams are uncompressed.
% Now ghostscript versions greater than 8 behave in the same way
% as Distiller. Therefore detection for this versions is added.
% The detection and patch for distiller require features of level 2
% and the filter /FlateDecode (level 3), that is used by pdfTeX's
% compression.
  /THB_DistillerPatch false def
  /languagelevel where {
    pop
    languagelevel 2 ge {
      product (Distiller) search {pop pop pop true}{pop false} ifelse
      product (Ghostscript) search {
        pop pop pop
        revision 800 ge
      }{pop false} ifelse
      or
      {
        (FlateDecode) {
          pop
% Syntax: <dict> THB_DistillerPatch <dict> false
%         <dict> THB_DistillerPatch <dict> <filter>
          /THB_DistillerPatch {
            dup /Filter known {
              dup dup /Filter get exch /Filter undef
            }{false} ifelse
          } bind def
        } (FlateDecode) /Filter resourceforall
      } if
    } if
  } if
  /streamobj {
    $dictend exch
% Stack: <thumb> <dict> <length>
    3 -1 roll dup
% Stack: <dict> <length> <thumb> <thumb>
    [ /_objdef 3 -1 roll /type /stream /OBJ pdfmark
% Stack: <dict> <length> <thumb>
    dup dup 5 -1 roll
% Stack: <length> <thumb> <thumb> <thumb> <dict>
    THB_DistillerPatch
% Stack: <length> <thumb> <thumb> <thumb> <dict> <filter/false>
    [ 4 -2 roll /PUT pdfmark
% Stack: <length> <thumb> <thumb> <filter/false>
    [ 3 1 roll currentfile${filter}
% Stack: <length> <thumb> [ <thumb> <filter/false> <file>
      6 -1 roll string $read pop
% Stack: <thumb> [ <thumb> <filter/false> <string>
      exch dup type /booleantype ne {true} if {filter} if
% Stack: <thumb> [ <thumb> <file>
      /PUT pdfmark
% Stack: <thumb>
    [ exch /CLOSE pdfmark
  } bind def
}{
% Syntax: <thumb object> thisTHB -
  /thisTHB {pop} bind def
  2 dict begin
% Syntax: <page object> <thumb object> pagethumb -
  /pagethumb {pop pop} bind def
% Syntax: <thumb object> <stream length>
%         <mark> <key value pairs> streamobj -
  /streamobj {
    cleartomark exch pop
    string currentfile${filter}
    exch $read pop pop
  } bind def
} ifelse
END_HEAD
    $PS_Header =~ s/%[^\r\n]*[\r\n]+//gm;
    print DTA_PM $PS_Header;
    print DTA_PM <<"END_DTA";

% adding thumbnails to pages
END_DTA

    for ($i=0; $i<$maxpagethumb; $i++)
    {
      print DTA_PM <<"END_DTA";
{Page$thumbpageno[$i]} {THB$thumbpageno[$i]} pagethumb
END_DTA
    }
    print DTA_PM "\n% thumbnail data\n";
  }

  for ($i=0; $i<$maxthumb; $i++)
  {
    # rgb object
    if ($thumbrgbobj[$i])
    {
      # find the same rgb object
      my $j;
      for ($j=0; $j<$i; $j++)
      {
        next unless $thumbrgbobj[$j];
        next unless $objtext[$thumbrgbobj[$j]] eq
                    $objtext[$thumbrgbobj[$i]];
        next unless $objstream[$thumbrgbobj[$j]] eq
                    $objstream[$thumbrgbobj[$i]];
        last;
      }
      if ($j==$i) # not found
      {
        if ($mode_pdftex)
        {
          {
            my $rgbstream = pdftexstream($objstream[$thumbrgbobj[$i]]);
            my $dict = $objtext[$thumbrgbobj[$i]];
            if ($::opt_compress == 10)
            {
              chomp($dict);
              $dict =~ s/\n([^\/])/^^J\n$1/mg;
              $dict =~ s/[ ]+\//\//mg;
            }
            else
            {
              $dict =~ s/\n/^^J\n/mg;
            }
            print DTA_PT <<"END_DTA";
\\immediate\\pdfobj{<<$J
$dict>>$J
stream^^J
$rgbstream
endstream}
\\DefRGB{$i}
END_DTA
          }
        }
        if ($mode_pdfmark)
        {
          {
            my $rgbstream = pdfmarkstream($objstream[$thumbrgbobj[$i]]);
            my $rgblength = $thumbrgblength[$i];
            my $dict = $objtext[$thumbrgbobj[$i]];
            $dict =~ s/\/Length\s+\d+\s*//;
            $dict =~ s/^\s+//;
            $dict =~ s/\s+$//;
            print DTA_PM <<"END_DTA";
{RGB_$i} $rgblength $dictbegin
$dict
streamobj
$rgbstream
END_DTA
          }
        }
      }
      else # $j with same rgb obj
      {
        $objtext[$thumbobj[$i]] =~
          s/\\the\\pdflastobj/\\UseRGB{$j}/;
        print "* Reuses RGB object $j for $i\n" if $::opt_debug;
      }
    }

    # thumb object
    if ($mode_pdftex)
    {
      {
        my $dict = $objtext[$thumbobj[$i]];
        if ($::opt_compress == 10)
        {
          chomp($dict);
          $dict =~ s/\n([^\/])/^^J\n$1/mg;
          $dict =~ s/[ ]+\//\//mg;
          $dict =~ s/[ ]+\[/\[/mg;
        }
        else
        {
          $dict =~ s/\n/^^J\n/mg;
        }
        my $stream = pdftexstream($objstream[$thumbobj[$i]]);
        print DTA_PT <<"END_DTA";
\\immediate\\pdfobj{<<$J
$dict>>$J
stream^^J
$stream
endstream}
\\DefThumb{$thumbpageno[$i]}
END_DTA
      }
    }
    if ($mode_pdfmark)
    {
      {
        my $stream = pdfmarkstream($objstream[$thumbobj[$i]]);
        my $length = $thumblength[$i];
        my $dict = $objtext[$thumbobj[$i]];
        $dict =~ s/\\the\\pdflastobj\\\s*\d+\s*R/{RGB_$i}/;
        $dict =~ s/\\UseRGB{(\d+)}\\\s*\d+\s*R/{RGB_$1}/;
        $dict =~ s/\/Length\s+\d+\s*//;
        $dict =~ s/^\s+//;
        $dict =~ s/\s+$//;
        my $thismarker = "";
        $thismarker = "_", if $i >= $maxpagethumb;
        print DTA_PM <<"END_DTA";
{THB$thismarker$thumbpageno[$i]} $length $dictbegin
$dict
streamobj
$stream
END_DTA
      }
    }
  }

  if ($mode_pdftex)
  {
    print DTA_PT "\\endinput\n";
    close(DTA_PT);
  }
  if ($mode_pdfmark)
  {
    print DTA_PM <<"END_DTA";
end
% end of thumbnail data file
END_DTA
    close(DTA_PM);
  }
}

sub pdftexstream
{
  my $str = "";
  my $mod = 0;
  foreach (split(//, $_[0]))
  {
    my $num = ord($_);
    if    ($num == 13)  { $str .= '\\/'; }
    elsif ($num < 32)   { $str .= '^^' . chr($num + 64); }
    elsif ($num == 32)  { $str .= '\\~'; } # space
    elsif ($num == 37)  { $str .= '\\%'; } # percent
    elsif ($num == 92)  { $str .= '\\\\'; } # backslash
    elsif ($num == 94)  { $str .= '\\+'; } # caret
    elsif ($num == 123) { $str .= '\\{'; } # curly brace left
    elsif ($num == 125) { $str .= '\\}'; } # curly brace right
    else  { $str .= $_; }
    $mod++;
    if ($mod == 26)
    {
      $mod = 0;
      $str .= "\n";
    }
  }
  chomp $str;
  return $str;
}

sub pdfmarkstream
{
  my $str;
  if ($::opt_level2)
  {
    my $s = $_[0];
    my $len = length($s);
    $str = "";
    my $i;
    for ($i=0; $i<$len-4; $i+=4)
    {
      $_ = ASCII85Encode(substr($s, $i, 4));
      s/!!!!!/z/;
      $str .= $_;
    }
    my $r = $len % 4;
    if ($r)
    {
      $_ = substr($s, $i, $r) . "\000\000\000";
      $_ = ASCII85Encode(substr($_, 0, 4));
      $str .= substr($_, 0, $r+1);
    }
    $str =~ s/(.{60})/$1\n/g;
    chomp($str);
    $str .= "~>";
  }
  else
  {
    $str = uc(unpack('H*', $_[0]));
    $str =~ s/(.{60})/$1\n/g;
    chomp($str);
  }
  return $str;
}

sub ASCII85Encode
{
  my $val = unpack("N", $_[0]);
  my @c;
  $c[4] = $val % 85 + 33;
  $val = int($val/85);
  $c[3] = $val % 85 + 33;
  $val = int($val/85);
  $c[2] = $val % 85 + 33;
  $val = int($val/85);
  $c[1] = $val % 85 + 33;
  $c[0] = int($val/85) + 33;
  return pack("C*", @c);
}

sub setsignals {
  my $func = $_[0];
  $SIG{'HUP'}   = $func unless $Win;
  $SIG{'INT'}   = $func;
  $SIG{'QUIT'}  = $func;
  $SIG{'TERM'}  = $func;
}

sub clean {
  if ($::opt_clean) {
    print "*** clear temp files ***\n" unless $::opt_quiet;
    foreach (@cleanlist) {
      unlink;
    }
  }
}

sub cleanup {
  print "\n" unless $::opt_quiet;
  clean();
  exit 1;
}

sub gscleanup {
  print "\n" unless $::opt_quiet;
  clean();
  close(::GSKID) if $gskidrunning;
  foreach (glob("$thumbprefix*.png")) {
    unlink;
  }
  exit 1;
}

clean();

print "*** ready. ***\n" unless $::opt_quiet;

__END__