Open5
PDFの仕様を読んで.NETのPDF Reader/Writer作りたい
PDF 2.0の仕様書は昨年に無料で入手できるようになってた
PDF AssociationのGitHubもあってシンプルなサンプル群などもあって良さそう
PDFファイルのsyntaxは以下の4つの部分として考えると良い。
- オブジェクト(Objects)
PDF ファイルは、基本的な種類のデータ オブジェクトの小さなセットから構成されるデータ構造。 - ファイル構造(File structure)
PDF ファイルの構造は、オブジェクトが PDF ファイルにどのように保存されるか、オブジェクトへのアクセス方法、およびオブジェクトの更新方法を決定します。 この構造は、オブジェクトのセマンティクスから独立しています。 - ドキュメント構造(Document structure)
PDFファイル構造は、PDFファイルの構成要素(ページ、フォント、注釈など)を表現するために、基本的なオブジェクトタイプがどのように使用されるかを指定します。 - コンテンツストリーム(Content streams)
PDF コンテンツ ストリームには、ページまたはその他のグラフィック エンティティの外観を記述する一連の命令が含まれています。 これらの命令は、オブジェクトとしても表されますが、文書構造を表すオブジェクトとは概念的に区別されており、個別に説明されます。
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
endobj12 0 obj endobj
オブジェクトを参照する
12 0 R
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 |
ファイル構造
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桁の世代番号
n
はn
または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つのバイト文字列の配列 |