最近、他から回ってきたPDFファイルについて、 Adobe Readerでは読めないがChrome等のブラウザでは読むことができるという注意書きがついてきた。 しかし、Adobe ReaderはPDFの本家本元でであり、これで読めないのに他のブラウザ等で読めるというのはおかしな話である。 そこで、少し詳しく調べることにした。
内部資料であるためここにファイルを示すことはできないが、複数のグラフを貼り付けたとあるPDF資料について、 確かにAdobeReaderで閲覧すると、内容が欠けて表示されるとともに、エラーがある旨のダイアログも表示される。 その一方で、Chrome等で閲覧すると特に問題なく内容が表示される。
ファイルを見たところ、CreatorはMicrosoft(R) Excel(R) for Microsoft 365と書いてあった。
Linux機で、pdf2psに掛けるとエラー無くPostscriptファイルに変換され、 ps2pdfでPDFに戻すとそのPDFファイルはAdobe Readerで問題なく表示される。 一方で、pdftopsに掛けると、以下のようなエラーが出力される。
Syntax Error (1834932): Unknown operator 'E-06' Syntax Error (1834945): Too few (3) args to 're' operator Syntax Error (1834932): Unknown operator 'E-06' Syntax Error (1834945): Too few (3) args to 're' operator <以下略>
このE-06に相当する文字列は、目視で当該のPDFの中身を見たときには見当たらない。 そこで、Linux機のpdftkというツールを使って、圧縮された中身を見ることにした。
$ pdftk test.pdf output test2.pdf uncompress
そうして展開されたPDFファイルの中身を見ると、 「8.871E-06 0 595.32 841.92 re」のような、pdftopsのエラーメッセージに対応する文字列が存在した。
当該のファイルの最初には「%PDF-1.7」と書かれている。そして、PDF-1.7のリファレンスをみると、 3.3.2 Numeric Objectsの、Noteのところに、"PDFでは10進数以外の表現や指数表現をサポートしない"と書いてある。
指数表現とは、古い人にとっては関数電卓やプログラムでおなじみであり、最近の人にとってはExcelで見ることのできる数の表現で、 1.23E-03などと書くことで、1.23×10-3もしくは、0.00123を表現する方法である。つまり、先の8.871E-06という文字列は、PDF中では本来0.000008871と表現されるべきものではなかろうかという仮説が生まれる。
そこで、試しに展開されたPDFの指数表現を通常の小数の表現に手で書き換えてみることにした。 ただ、PDFファイルは、ファイル内の他の情報を先頭からのバイト数で指定してファイル内で参照したりしている。 そのため、ファイルの長さを変える場合は、そのあたりの参照も一緒に変えないとエラーになる。 そのような面倒を避けるため、"8.871E-06"に対して"0.0000089"のように、(微妙に値が違うとしても)文字数を変えない小数で置き換えた。
その結果、Adobe Readerでも表示されるべき内容がエラー無く表示されるようになった。
今回の件については、PDFファイル内で、小数が規格違反の指数表現で書かれていることが原因と思われる。 Adobe Readerは規格通りに解釈するため当該のPDFファイルはエラーとなるが、 ブラウザのPDFビューアーは指数表現の小数を読み込むことができるようになっているため、 エラー無く表示できてしまっているのだと思われる。
今のところ、手持ちのExcelで問題のあるPDFの生成を再現できていないため、 どのようなファイルからどのような操作で問題のあるPDFが作られるのかわかっていない。
(2025/3/22にメモとして書く)