EPS2 et dvips

Page principale

Répondre à ce message
Auteur: Edgar Bonet
Date:  
À: Liste Guilde
Sujet: EPS2 et dvips
Bonjour aux LaTeXperts, et aux autres !

J'ai rencontré une incompatibilité bizarre entre ImageMagick et dvips.
J'ai des images bitmap à mettre dans un document LaTeX destiné à une
sortie PostScript, il faut donc que je convertisse mes images en EPS. Si
je fais

    convert machin.png machin.eps


j'obtiens des EPS monstrueusement gros. Un peu partout de par le Web on
conseille d'utiliser l'EPS niveau 2, comme ça :

    convert machin.png eps2:machin.eps


ce qui donne des fichiers _beaucoup_ plus compacts et qui passent bien
sur gv. Le problème c'est que quand dvips inclut l'EPS dans le fichier
PostScript final, l'image est parfois (mais pas toujours) corrompue. Je
vous joins ici des fichiers de démonstration (minuscules,
rassurez-vous). Si je fais le test suivant :

    convert test.png eps2:test.eps
    latex test
    dvips -o test.ps test
    gv -scalebase 2 test.eps &
    gv -scalebase 2 test.ps &


je vois que test.eps est ok, mais test.ps est corrompu.

J'ai trouvé l'origine du problème : ImageMagick produit un fichier avec
une séquence binaire qui n'est pas annoncée par %%BeginBinary. dvips
n'aime pas et il vire tous les Control-D qu'il trouve dans la séquence
binaire. J'ai résolu le problème chez moi avec un bricolage Perl (fixeps
ci-joint) : je fais

    convert test.png eps2:- | fixeps > test.eps


et tout marche bien.

Alors si ça marche pourquoi faire tant d'histoires me direz-vous ? Outre
le fait que je me dis que mon bricolage pourrait profiter à d'autres, je
me pose deux questions :

  - Si on conseille partout « convert machin.png machin.eps » c'est que
    pour certains ça doit bien marcher. Peut-être que j'ai la mauvaise
    version de quelque chose ? Est-ce que vous pourriez me dire ce que
    donne mon petit test chez-vous ainsi que votre config ? Pour info
    chez moi c'est :
        Mandrake 8.1
        ImageMagick-5.3.8-10mdk
        tetex-dvips-1.0.7-31mdk


  - Je ne sais pas à qui jetter la pierre car ni ImageMagick ni dvips ne
    respectent vraiment les DSC. ImageMagick produit un commentaire
    %%BeginData incorrect. Quand à dvips, il ignore de toutes façons le
    %%BeginData et ne s'intéresse qu'à l'obsolète %%BeginBinary. Cf. mes
    commentaires dans fixeps. À qui envoyer le rapport de bogue ?


Merci et bonne soirée !

Edgar.

-- 
Edgar Bonet                         Tél    : 04 76 88 10 96
Laboratoire Louis Néel -- CNRS      Mobile : 06 77 19 79 39
25 av. des Martyrs, BP 166          Fax    : 04 76 88 11 91
38042 Grenoble cedex 9, France      e-mail : guilde@???


\documentclass{article}
\usepackage{graphics}
\begin{document}
\includegraphics{test.eps}
\end{document}
#!/usr/bin/perl

# Fix EPS files created by ImageMagick to make them dvips compatible.
#
# Author:
#   Edgar Bonet <guilde@???>.
#
# The problem:
#   When converting a raster image to EPS using ImageMagick, EPS level 2
#   (EPS2) should be preferred over plain EPS because of its far smaller
#   size. However, when asked for EPS2, ImageMagick produces files with
#   embedded binary data and no %%BeginBinary comment. dvips will then
#   strip any Control-D it finds in the file, thus corrupting the image.
#
# What ImageMagick outputs:
#   The actual image data appears in the EPS file as a binary stream,
#   preceded by "%%BeginData:\n" and followed by "%%EndData\n".
#
# What dvips expects:
#   Any binary stream should be preceded by
#   "%%BeginBinary: <byte-count>\n" and followed by "%%EndBinary\n".
#
# What the standards (DSC 3.0, p. 44-45) say:
#   %%BeginBinary is defined in the standard for backward compatibility
#   only. %%BeginData should be preferred. However, the minimal syntax
#   is "%%BeginData: <byte-count>\n" where the byte count is mandatory.
#
# Our fix:
#   Use both delimiters in order to be both DSC and dvips compliant. The
#   output file should look like
#       ...some PostScript code...
#       %%BeginData: <byte-count>
#       %%BeginBinary: <byte-count>
#       ...binary stream...
#       %%EndBinary
#       %%EndData
#       ...some more PostScript code...
#   Notice that the two byte counts are different and there is a '\n' at
#   the end of the binary stream.


# Read the whole file in one string
while (<>) { $eps .= $_; }

# Look for a non-compliant %%BeginData
if ($eps =~ /^\%\%BeginData:\n(.*?)^\%\%EndData\n/sm) {

    # Put the delimiters around the binary stream
    $binary = $1;
    $lg = length $binary;
    $binary = "\%\%BeginBinary: $lg\n$binary\%\%EndBinary\n";
    $lg = length $binary;
    $binary = "\%\%BeginData: $lg\n$binary\%\%EndData\n";


    # Replace in the EPS
    $eps =~ s/^\%\%BeginData:\n.*?^\%\%EndData\n/$binary/sm;
}


# Output the fixed file
print $eps;