PDFのファイル仕様はおおまかに以下の形式になっています。
%PDF1.xxx //ファイルヘッダー xxx 0 obj //1つ目のオブジェクト開始 <<xxx>> //1つ目のオブジェクトの属性値 endobj //1つ目のオブジェクト終了 xxx 0 obj //2つ目のオブジェクト開始 <<xxx /Length xxx>> //2つ目のオブジェクトの属性値 stream //2つ目のオブジェクトのstreamの開始 xxx //2つ目のオブジェクトのstream内容(Lengthのバイト数分) endstream //2つ目のオブジェクトのstreamの終了 endobj //2つ目のオブジェクト終了 . . . xref //クロスリファレンスの開始 0 xxx //クロスリファレンスの数 0000000000 65535 f xxxxxxxxxx 00000 n //1つ目のオブジェクトの位置情報 xxxxxxxxxx 00000 n //2つ目のオブジェクトの位置情報 xxxxxxxxxx 00000 n //3つ目のオブジェクトの位置情報 xxxxxxxxxx 00000 n //4つ目のオブジェクトの位置情報 trailer //トレーラーの開始 <<xxx /Root xxx 0 R /Size xxx>> //トレーラーの属性値 startxref xxx //クロスリファレンスの位置情報 %%EOF //ファイルフッター
以下はおおまかな注意事項
・各情報の区切りには改行コード(「\r」、「\n」、「\r\n」の3種類どれか)が入る
・stream末尾(「endstream」の1~2バイト前)にも改行コードが入る
・オブジェクト情報がstreamとして格納されることもある
・stream情報は圧縮されることもある
・クロスリファレンス情報はstreamとしてどこかのオブジェクト内にバイナリ形式で格納されることもある(3.4.7 Cross-Reference Streams)
・クロスリファレンス情報はセクション分割されて表記されることもある(3.4.3 Cross-Reference Table example3.6)
・オブジェクト属性値の空白は省略や改行されることもある(例:「<</Type/Page>>」「<<\r/Type\r/Page\r>>」「<</Type /Page>>」)
・「%」から始まる行はコメント行(PDFヘッダー/フッターを除く)
・文字は「xyz」(そのまま書く)、「<78797A>」(16進数で文字コードを書く)、「\120\121\122」(10進数で文字コードを書く)のように複数の表現がある
・文字中の「(」「)」「\」はエスケープして「\(」「\)」「\\」のようにされるが、カッコはエスケープされないこともある
・文字中の改行コードの1バイト前に「\」がある場合は改行コードは無視する
簡単に要約すると「PDFの表記方法は複数あるため、PDFを読むのは大変」。
汎用的なPDF操作処理を行いたい場合は無理せずにAdobeのSDKやPDFのライブラリを使うのが無難です。
PDFの仕様書
Adobe Portable Document Format Version 1.7
https://www.adobe.com/content/dam/Adobe/en/devnet/acrobat/pdfs/pdf_reference_1-7.pdf