Open5

PDFの仕様を読んで.NETのPDF Reader/Writer作りたい

meshimeshi

PDFファイルのsyntaxは以下の4つの部分として考えると良い。

  • オブジェクト(Objects)
    PDF ファイルは、基本的な種類のデータ オブジェクトの小さなセットから構成されるデータ構造。
  • ファイル構造(File structure)
    PDF ファイルの構造は、オブジェクトが PDF ファイルにどのように保存されるか、オブジェクトへのアクセス方法、およびオブジェクトの更新方法を決定します。 この構造は、オブジェクトのセマンティクスから独立しています。
  • ドキュメント構造(Document structure)
    PDFファイル構造は、PDFファイルの構成要素(ページ、フォント、注釈など)を表現するために、基本的なオブジェクトタイプがどのように使用されるかを指定します。
  • コンテンツストリーム(Content streams)
    PDF コンテンツ ストリームには、ページまたはその他のグラフィック エンティティの外観を記述する一連の命令が含まれています。 これらの命令は、オブジェクトとしても表されますが、文書構造を表すオブジェクトとは概念的に区別されており、個別に説明されます。
meshimeshi

Comment

% some comment

Objects

  • Boolean Objects
    true or false
  • Numeric objects
    実数または整数値
  • String objects
    ( ... )
    \で改行せず連続させる
(a \
b \
c)
(a b c)

<...> で16進数文字列を仕込める。主にバイナリデータ向けらしい。

\dddで8進数で文字コード指定

  • Name objects
    /...

  • Array objects
    [...]

  • Dictionary objects
    << ... >>
    /Key value
    valueは任意のオブジェクト
    慣例により、Typeエントリが存在する場合、そのDictionary objectsが記述するオブジェクトの型を識別する。
    /Typeおよび/SubType(省略して/S)のキーを持つことがあり、必ず値はName objectになる。

  • Stream objects
    dictionary
    stream
    ...Zero or more bytes...
    endstream

  • Null object
    null

  • Indirect object
    object number generation number obj
    endobj

    12 0 obj
    endobj
    

    オブジェクトを参照する
    12 0 R

meshimeshi

stream dictionary

Key Type Value
Length integer (必須) stream に続く行の先頭からendstreamの直前までのバイト数。
Filter name or array stream と endstream の間にあるデータの処理に適用されるフィルターの名前
DecodeParms dictionary or array Filter で指定されたフィルターによって使用される
F file specification
FFilter name or array
FDecodeParms dictionary or array
DL integer
meshimeshi

ファイル構造

header, body, cross-reference table, trallerの順で構成される。

  • header
    %PDF-1.nまたは%PDF-2.n
  • body
    一連のindirect objectsで構成される。1.5以降はobject streamも含めることが可能
  • cross-reference table
    xrefのキーワードから始まる。
    サブセクションはスペースで区切られた最初のオブジェクトの開始番号と、エントリ数から始まる
    28 5
    28~32のオブジェクトを含むサブセクションがある。
    この次にcross-reference entryが続く。長さは行末マーカー含め20バイトで以下の形式
    nnnnnnnnnn ggggg n eol
    nnnnnnnnnは10桁のバイトオフセット。
    gggggは5桁の世代番号
    nnまたはfでそのエントリが使用中(n)か未使用(f)を表す。
    eolは2文字の行末シーケンス(0x0D 0x0A)

テーブルの最初のエントリは000000000 65535 fとなる。

  • trailer
trailer
<<
key1 value1
key2 value2
...
keyn valuen
>>
startxref
Byte_offset_of_last_cross-reference_section
%%EOF

Dictionary

Key Type Value
Size int required, indirect referenceはNG。PDFファイルのcross-reference tableのエントリの総数。
Prev int optional, ファイルに複数のcross-reference sectionがある場合にのみ、ファイルの先頭から前のcross-reference sectionの先頭までのバイトオフセット。
Root dictionary required, indirect referenceでなくてはならない。catalog dictionaryを指す
Encrypt dictionary 暗号化時、required. PDFファイルの暗号化Dictionary
Info dictionary optional, PDFファイルの情報
ID array PDF2.0またはEncryptエントリ存在時 required. 識別子を構成する2つのバイト文字列の配列