% % pts_bbox.sty -- open an image and read BoundingBox info % modified by pts@fazekas.hu at Sun Feb 2 17:07:43 CET 2003 % \expandafter\ifx\csname ifLaTeX\endcsname\relax\input laemu.sty\relax\fi% \NeedsTeXFormat{LaTeX2e} \ProvidesPackage{pts_bbox}[2003/02/02 v0.2 determine BoundingBox] \def\@@imgread@sPS{PS}% \def\@@imgread@sEPS{EPS}% \def\@@imgread@sMetaPost{MetaPost}% \def\@tempa{}% \def\@tempb{}% %** `\@@imgread@stripps FF..\\' set \@tempa to `FF' with `EPS.' and `PS.' %** stripped from the beginning. FF is a FileFormat such as `TIFF' or %** `EPS.MPS'. \def\@@imgread@stripps#1.#2.#3\\{% \def\@tempa{#1}% \def\@tempb{#2}% \ifx\@tempb\@empty\else% \ifx\@tempa\@@imgread@sPS \def\@tempa{#2}% \else\ifx\@tempa\@@imgread@sEPS \def\@tempa{#2}% \else \def\@tempa{#1.#2}\fi\fi% \fi% }% %%** `\@@imgread@strpqbp#\\' expands to `#' if `#' begins with `?'; else %%** it expands to `#bp' %\def\@@imgread@stripqbp#1#2\\{% % \if\noexpand#1?% % #1#2% % \else % #1#2bp% % \fi %}% %** Process output of external command `img_bbox.pl --tex'. Strips EPS.* %** -> * and PS.* -> *. %** Example: \graphicPmeta{f2cletter.pdf}{PDF}{3}{-10}{23}{20} \def\graphicPmeta#1#2#3#4#5#6{% %\message{meta{#1}{#2}{#3}{#4}{#5}{#6};}% \begingroup% \@@imgread@stripps#2..\\% returns \@tempa, ruins \@tempb \edef\@tempa{% \noexpand\def% \expandafter\noexpand\csname @@xb@#1\endcsname% %{{\@tempa}{\@@imgread@stripqbp#3\\}{\@@imgread@stripqbp#4\\}% % {\@@imgread@stripqbp#5\\}{\@@imgread@stripqbp#6\\}}% {{\@tempa}{#3}{#4}{#5}{#6}}% }% \expandafter\endgroup\@tempa% %\expandafter\edef\csname @@xb@#1\endcsname{{\@tempa}{#3bp}{#4bp}{#5bp}{#6bp}}% }% %\graphicPmeta{a}{PS.MPS}{3}{4}{5}{6}\message{<\@@xb@a>}\end %** Opens the external image file, reads the bounding box information, and %** calls #1{LLX}{LLY}{URX}{URY}. Failure is indicated by setting any of %** LLX, LLY, URX or URY to ?. %** @param #1 a \cs#1#2#3#4 that records the bounding box information %** @param #2 a filename \def\@@GetBBox#1#2{% % Imp: unset temporary variables (@@gp@xb) \edef\@@gp@xb{@@xb@#2}% \ @@xb@foo.eps \expandafter\ifx\csname\@@gp@xb\endcsname\relax% no cached value yet %\PackageError{pts_img}{BBox read unimplemented}\@ehc% \@@imgread@afile\graphicPmeta{#2}% \fi% \edef\@@gp@xc{\csname\@@gp@xb\endcsname}% full expansion of cached value %\message{;\@@gp@xc;}% %\expandafter\expandafter\expandafter#1\expandafter\@gobble\@@gp@xc% gobble FileFormat \expandafter#1\@@gp@xc% report FileFormat and bbox }% \expandafter\ifx\csname @tempcnta\endcsname\relax% \newcount\@tempcnta \fi %\def\@makeother#1{\catcode`#1=12\relax} %\chardef\@inputcheck0 % Dat: uses \newread\@inputcheck \newif\if@@imgread@ %\def\@latex@error{\errmessage{#1}} %\message{\@@imgread@BBox}% %*** The DOS EPSF header \edef\@@imgread@DOSEPSF{% % Imp: specify shorter \expandafter\@secondoftwo\string\^^c5% \expandafter\@secondoftwo\string\^^d0% \expandafter\@secondoftwo\string\^^d3% \expandafter\@secondoftwo\string\^^c6% }% %** A dot, and the first 3 bytes of a JPEG file \edef\@@imgread@JPEG{% % Imp: specify shorter .% \expandafter\@secondoftwo\string\^^ff% \expandafter\@secondoftwo\string\^^d8% \expandafter\@secondoftwo\string\^^ff% }% \edef\@@imgread@PNG{\expandafter\@secondoftwo\string\^^89PNG}% \edef\@@imgread@TIFFMM{MM..}% MSB first TIFF header is "MM\0*" \edef\@@imgread@TIFFII{II*.}% LSB first TIFF header is "II*\0" \def\@@imgread@atend{atend} \edef\@@imgread@PDF{\expandafter\@secondoftwo\string\%PDF} \edef\@@imgread@EPS{\expandafter\@secondoftwo\string\%!PS} %\def\@@img@sPDF{PDF}% %\def\@@img@sEPS{EPS}% %\def\@@img@sQ{?}% %** \@@imgread@setfour\cs...\\ \def's \cs to be the first four tokens of %** `...'. `...' must have at least 4 tokens \long\def\@@imgread@setfour#1#2#3#4#5#6\\{% \def#1{#2#3#4#5}% }% % vvv also defined in other files {\catcode`p=12\catcode`t=12\gdef\@@mkb#1pt{#1}}% no p,t in @@mkb %** Find and process %%BoundingBox ADSC comment in an EPS file, or the first %** occurence of `/Mediabox [' (at BOL) in a PDF file. The PDF case is not %** perfect, but cannot be, since TeX is unable to read binary files %** properly; preprocess the PDF file with pdfboxes.pl to make sure. %** @param #1 a \cs. calls #1{FileName}{Fileformat}{LLX}{LLY}{URX}{URY} %** @param #2 filename \def\@@imgread@afile#1#2{% % Dat: EPS with DOS-style binary preview is not supported \begingroup \@tempcnta0 % 0 Escape character (|\| in this manual) % 1 Beginning of group (|{| in this manual) % 2 End of group (|}| in this manual) % 3 Math shift (|$| in this manual) % 4 Alignment tab (| | in this manual) % 5 End of line (\ in this manual) % 6 Parameter (|#| in this manual) % 7 Superscript (|^| in this manual) % 8 Subscript (|_| in this manual) % 9 Ignored character (\ in this manual) %10 Space (\] in this manual) %11 Letter (|A|, \dots, |Z| and |a|, \dots, |z|) %12 Other character (none of the above or below) %13 Active character (|~| in this manual) %14 Comment character (|%| in this manual) %15 Invalid character (\ in this manual) % % (by pts@fazekas.hu at Sun Feb 2 18:27:56 CET 2003) % The TeX \read primitive works like this: low-level line separators are % "\012", "\015" and "\015\012". \read reads a single line, as ended by % a single low-level line-separator. Two extra separators are assumed to be % at EOF. Space tokens (10) at the beginning of the line are ignored. A % series of empty lines are read as \par + space. The first end-of-line (5) % token is converted to a space, and the rest is ignored. The first % command (14) character and the rest is ignored. % \ifeof is true between \openin and the first \read iff \open failed. % Thus, we set all unprintable characters to ignored (9). We set both % '\012' and '\015' to be comment (14), so no space would be appended at % EOLs. Space and tab will be set to space (10). Thus real spaces won't be % ignored at the beginning of the lines, and \par will never be read. % It is impossible to read the %!PS header of some DOS EPSF files, % because it might be before the first low-level line separator, but % ignored because of how we read the EPSF header. % \@tempcnta0 \loop\ifnum\@tempcnta<32 % \catcode\@tempcnta9 % ignored \advance\@tempcnta\@ne \repeat \@tempcnta127 \loop\ifnum\@tempcnta<256% \catcode\@tempcnta9 % ignored \advance\@tempcnta\@ne \repeat \catcode`\\12% other \catcode`\{12% other \catcode`\}12% other \catcode`\}12% other \catcode`\$12% other \catcode`\&12% other \catcode`\#12% other \catcode`\^12% other \catcode`\_12% other \catcode`\%12% other \catcode`\~12% other \catcode`\:12% other \catcode`\-12% other \catcode32=10% ' ': space, ignored at BOL \catcode9=10% '\t': space, ignored at BOL \catcode`\]10% ']': space, so we can parse /MediaBox correctly \catcode\endlinechar14% '\015': end-of-line \catcode10=14% \catcode13=14% \catcode0=14% important for tiff \catcode198=12% last byte of DOS EPSF header \catcode211=12% third byte of DOS EPSF header \catcode208=12% second byte of DOS EPSF header \catcode197=12% first byte of DOS EPSF header \catcode137=12% first byte of PNG header \catcode255=12% JPEG marker-header \catcode216=12% JPEG SOI marker %\endlinechar=-1% \immediate\openin\@inputcheck#2 % \def\@@imgread@fmt{?}% \def\@@imgread@bbox{}% not found yet \ifeof\@inputcheck %\@latex@error% \PackageError{bbox}{Image file `#2' not found}\@ehc \else \read\@inputcheck to\@tempa% first line \catcode137=9 % first byte of PNG header \catcode255=9 % JPEG marker-header \catcode216=9 % JPEG SOI marker \expandafter\@@imgread@setfour\expandafter\@tempb\@tempa....\\% \expandafter\@@imgread@setfour\expandafter\@tempa\expandafter.\@tempb\\% \@tempb == ABCD -> @tempa = .ABC % Now \@tempb contains the first 4 chars, and \@tempa is the first line %\message{[\@tempb]}% \let\@@imgread@test@end\@@imgread@test@yesend \ifx\@tempb\@@imgread@PNG% \def\@@imgread@fmt{PNG}% \@@imgread@pdftexgetwh{#2}% \else\ifx\@tempb\@@imgread@TIFFII% \def\@@imgread@fmt{TIFF}% \@@imgread@pdftexgetwh{#2}% \else\ifx\@tempb\@@imgread@TIFFMM% \def\@@imgread@fmt{TIFF}% \@@imgread@pdftexgetwh{#2}% \else\ifx\@tempb\@@imgread@DOSEPSF% % Emit a warning, since these DOS EPSF files cannot be embedded % properly by dvips, and even reading the bounding box is quite % unstable. \PackageWarning{pts_img}{DOS EPSF header in file `#2'\@gobble}% \let\@tempb\@@imgread@EPS% \let\@@imgread@test@end\@@imgread@test@noend \def\@@imgread@fmt{EPS}% or PS \else\ifx\@tempb\@@imgread@EPS% \else\ifx\@tempb\@@imgread@PDF% \else\ifx\@tempa\@@imgread@JPEG% \@tempa \def\@@imgread@fmt{JPEG}% \@@imgread@pdftexgetwh{#2}% %\else% unknown image format \fi\fi\fi\fi\fi\fi\fi% \ifx\@tempb\@@imgread@EPS% \def\@@imgread@fmt{EPS}% or PS \edef\@percentchar{\expandafter\@secondoftwo\string\%}% LaTeX has it \edef\@@imgread@BBox{\@percentchar\@percentchar BoundingBox}% \edef\@@imgread@BBoh{\@percentchar\@percentchar HiResBoundingBox}% \edef\@@imgread@BBoe{\@percentchar\@percentchar ExactBoundingBox}% \edef\@@imgread@BBoc{\@percentchar\@percentchar Creator}% \let\@@imgread@find@bb\@@imgread@find@eps% \@@imgread@lines% \else\ifx\@tempb\@@imgread@PDF% \def\@@imgread@fmt{PDF}% \edef\@@imgread@BBox{/MediaBox}% `/MediaBox [' or `/MediaBox[' \let\@@imgread@find@bb\@@imgread@find@pdf% \@@imgread@lines% \else% unknown \fi\fi% %\message{format:\@@imgread@fmt.}% \immediate\closein\@inputcheck% \fi% \ifeof\@inputcheck \edef\@tempa{\noexpand#1{#2}{\@@imgread@fmt}\@tempa}% \expandafter\endgroup\@tempa% end the group and call output command } %** Use pdfTeX to define \@tempa to be a bounding box of the image. %** @param #1 filename \def\@@imgread@pdftexgetwh#1{% !! Imp: use pdfTeX (if present) to get BBox \def\@tempa{{?}{?}{?}{?}}% not pdfTeX. Cannot read binary files. Give up. \expandafter\ifx\csname pdfoutput\endcsname\relax% \else\ifnum0<\pdftexversion% % Newer versions of pdfTeX can embed PNG, JPEG and TIFF images directly. % Just load the image into a \hbox, and measure its dimensions. \begingroup\setbox0=\hbox{% \expandafter\ifx\csname pdfximage\endcsname\relax \ifnum\pdftexversion<13% older, Debian Slink \pdfimage#1\noexpand\noexpand\noexpand\@empty \relax% #1 may start with `width' \else \pdfimage{#1}% \fi \else% quite new pdfTeX %\immediate\pdfximage would include the image file unnecessarily. % Without \immediate, only a single PDF xref entry is occupied per % image. This call to \pdfximage doesn't make the bug in % pdftex_bug.tex manifest. What a luck. \pdfximage{#1}% \pdfrefximage\pdflastximage \fi }% % Now \ht0 etc. have the width in bp. We convert it to pt first, and % then remove the `pt' unit. The orinal dimension (in bp) was an integer, % so we round to the nearest integer to compensate errors of fixed point % arithmetic. \dp0=-.99626400996264\dp0% *-72/72.27 \wd0=.99626400996264\wd0% \ht0=.99626400996264\ht0% \count0=\dp0\advance\count0 32768\divide\count0 65536% \count1=\wd0\advance\count1 32768\divide\count1 65536% \count2=\ht0\advance\count2 32768\divide\count2 65536% %\message{pdfbbox=(0,\the\count0,\the\count1,\the\count2)}% \edef\@tempa{\noexpand\def\noexpand\@tempa{{0}{\the\count0}{\the\count1}{\the\count2}}}% \expandafter\endgroup\@tempa \fi\fi% } %** Read the file line-by-line, stop at the first line containing BBox info. \def\@@imgread@lines{% \@@imgread@true \let\@tempb\@@imgread@false \loop %\endlinechar=65 \relax% doesn't work, a space will be appended %\catcode13=9 % doesn't work, a space will be appended \read\@inputcheck to\@tempa \ifeof\@inputcheck \@@imgread@false \else %\message{t(\@tempa)}% \expandafter\@@imgread@find@bb\@tempa:[.\\% \fi \if@@imgread@\repeat \ifx\@@imgread@bbox\@empty \def\@tempa{{?}{?}{?}{?}}% \else% found BBox -- maybe not syntactically correct %\message{///\@tempa***}% \expandafter\@@imgread@parse@bb\@@imgread@bbox\\% \fi% } \def\@@imgread@find@eps#1:#2#3\\{% \def\@tempa{#1}% %\message{find(\@tempa)}% \@@imgread@test@end#1.....\\% modifies \@tempa \ifx\@tempa\@@imgread@BBox% \@@imgread@test@atend#2#3()\\% \else\ifx\@tempa\@@imgread@BBoh% \@@imgread@test@atend#2#3()\\% \ifx\@@imgread@bbox\@empty\else% \def\@@imgread@BBox{:}% don't recognise subsequent %%BoundingBox after %%HiResBoundingBox \fi% \else\ifx\@tempa\@@imgread@BBoe% \@@imgread@test@atend#2#3()\\% \ifx\@@imgread@bbox\@empty\else% \def\@@imgread@BBox{:}% don't recognise subsequent %%BoundingBox after %%HiResBoundingBox \def\@@imgread@BBoh{:}% don't recognise subsequent %%HiResBoundingBox after %%ExactBoundingBox \fi% \else\ifx\@tempa\@@imgread@BBoc% \@@imgread@test@creator#2#3\\% \fi\fi\fi\fi% } %** In normal mode. Runs \@tempb if about to end %** @param #1..#5 single chararacter tokens \def\@@imgread@test@yesend#1#2#3#4#5#6\\{% %\message{end(#1#2#3#4#5)}% \if\noexpand#1\@percentchar% \if\noexpand#2\@percentchar% \if\noexpand#3E% \if\noexpand#4n% \if\noexpand#5d% \@tempb% \fi% \fi% \fi% \else% \@tempb% \fi% \else% \@tempb% \fi% }% %** In MetaPost mode. Runs \@tempb if about to end. %** The %%HiResBoundingBox comment emitted by ConTeXt is usually after %** %%EndProlog. So we stop at the first line not beginning with `%' %** @param #1..#5 single chararacter tokens \def\@@imgread@test@mpend#1#2#3#4#5#6\\{% \if\noexpand#1\@percentchar% \else% \@tempb% \fi% }% %** Used as \@@imgread@test@end when reading a DOS EPSF file \def\@@imgread@test@noend#1\\{}% \def\@@imgread@find@pdf#1[#2#3\\{% \def\@tempa{#1}% %\message{find(\@tempa)}% \ifx\@tempa\@@imgread@BBox \@@imgread@test@atend#2#3()\\\fi% } %** Recognise the ``%%Creator: MetaPost'' ADSC comment. Ruins @tempa \def\@@imgread@test@creator#1:#2\\{% %\message{cr(#1)}% \def\@tempa{#1}% \ifx\@tempa\@@imgread@sMetaPost% \def\@@imgread@fmt{MPS}% \let\@@imgread@test@end\@@imgread@test@mpend% find late %%HiresBoundingBox \fi% }% \def\@@imgread@test@atend#1(#2)#3\\{% %\message{atend(#2)}% \ifx\@tempb\relax\else% don't allow early ending for (atend) \let\@@imgread@test@end\@@imgread@test@yesend \fi% \def\@tempa{#2}% \ifx\@tempa\@@imgread@atend \@@imgread@true \let\@tempb\relax% read till EOF \else %\message{gotit(#1)}% \def\@@imgread@bbox{#1}% % Don't do \@@imgread@false, because better %%BoundingBox may come before %%End \fi% } %** Sets \@tempa to the BBox info, ruins \dimen[1234] \def\@@imgread@parse@bb#1 #2 #3 #4:#5\\{% \dimen1=#1pt \dimen2=#2pt \dimen3=#3pt \dimen4=#4pt% simplify and pre-round % ^^^ important to remove spaces after #4 \edef\@tempa{{\expandafter\@@mkb\the\dimen1}{\expandafter\@@mkb\the\dimen2}{\expandafter\@@mkb\the\dimen3}{\expandafter\@@mkb\the\dimen4}}% %\message{bbox(#1)(#2)(#3)(#4)[\@tempa]}% }%