Anatomi sebuah berkas PDF
Sekilas pandang
Bagian berjudul “Sekilas pandang”Buka PDF mana pun di sebuah editor teks biasa dan hal pertama yang Anda lihat
menenangkan: sebuah header %PDF-1.x atau %PDF-2.0. Hal terakhir yang Anda lihat
adalah %%EOF. Semua yang berada di antara dua baris itu adalah mesin mungil yang
rapi untuk menemukan objek berdasarkan nomor. Halaman ini adalah pembedahan. Kita
membuka berkasnya, menamai setiap organnya, dan menunjukkan bagaimana mereka
terhubung.
Ia adalah pendamping struktural bagi dua tetangga. Apa sebenarnya sebuah PDF memperlakukan berkas sebagai graf objek; pembaruan inkremental membahas bagaimana ia tumbuh seiring waktu. Halaman ini tetap dekat dengan byte-nya — region fisik yang dilewati sebuah parser, dalam urutan yang mereka tempati di disk.
Mengapa ini penting
Bagian berjudul “Mengapa ini penting”Anda hampir tidak pernah membutuhkan ini untuk menggunakan sebuah PDF. Anda membutuhkannya pada hari salah satunya bermasalah. Sebuah berkas terbuka di satu penampil dan tidak di penampil lain; sebuah validator melaporkan “tabel referensi silang rusak”; sebuah dokumen yang ditandatangani tiba-tiba gagal diverifikasi. Tidak ada satu pun dari itu yang menjadi misteri begitu Anda dapat membaca anatominya. Itu adalah sebuah angka yang tidak lagi cocok dengan sebuah posisi, sebuah region di tempat yang salah, atau sebuah ekor yang menunjuk ke ketiadaan.
Mengetahui tata letaknya mengubah “PDF-nya korup” menjadi sebuah diagnosis yang dapat Anda tindaklanjuti. Itu adalah perbedaan antara mengangkat bahu di hadapan kotak hitam dan menunjuk ke byte persis yang berbohong.
Versi singkatnya
Bagian berjudul “Versi singkatnya”Sebuah PDF yang konform memiliki empat bagian fisik, dalam urutan berkas ini (Spec: ISO 32000-2, §7.5.1ISO 32000-2 §7.5.1):
- Sebuah header — satu baris,
%PDF-2.0, menamai versinya. - Sebuah body — bagian terbesar berkas: serangkaian objek tak langsung bernomor.
- Sebuah cross-reference section — indeks dari nomor objek ke offset byte tempat objek itu berada. PDF klasik memakai tabel teks; PDF 2.0 memakai xref stream terkompresi.
- Sebuah trailer — sebuah kamus kecil yang menamai titik masuknya, diikuti oleh
startxref, sebuah offset, dan%%EOF.
Kejutannya: pembaca tidak memulai dari atas. Ia memulai dari bawah, membaca
startxref untuk menemukan indeksnya, dan menggunakan indeks itu untuk menjangkau
objek apa pun secara langsung. Berkasnya ditulis dari depan ke belakang tapi dibaca
dari belakang ke depan.
Bagaimana NextPDF menanganinya
Bagian berjudul “Bagaimana NextPDF menanganinya”Mari kita susuri keempat region itu secara berurutan, dengan byte-nya di hadapan kita.
Header adalah satu baris. NextPDF menulis %PDF-2.0, dan secara konvensi sebuah
baris komentar kedua berisi byte ber-bit-tinggi sehingga alat transfer yang naif
memperlakukan berkasnya sebagai biner, bukan teks. Baris kedua itulah sebabnya
sebuah PDF yang dibuka sebagai teks biasa menampilkan sedikit kekacauan tepat
setelah versinya.
Body adalah tempat dokumen berada. Setiap objek tak langsung adalah sebuah
nomor, sebuah generasi, kata kunci obj, sebuah nilai, dan endobj
(Spec: ISO 32000-2, §7.3.10ISO 32000-2 §7.3.10). Nilainya adalah salah satu dari
beberapa bentuk — tetapi dua di antaranya menanggung hampir seluruh bebannya:
- Sebuah dictionary,
<< /Key value … >>, adalah peta nama ke nilai. Pohon halaman, katalog, deskriptor font: semuanya dictionary. - Sebuah stream adalah dictionary yang diikuti oleh
stream, sebuah blok byte sembarang, danendstream. Konten halaman, font tersemat, dan gambar adalah stream, hampir selalu terkompresi. (Filternya adalah cerita tersendiri, dikisahkan di streams dan filters.)
Objek saling menunjuk melalui indirect reference — 2 0 R berarti “objek 2,
generasi 0.” Itulah pengkabelan yang mengubah daftar objek yang datar menjadi
sebuah graf.
Cross-reference section adalah bagian yang paling tidak dibayangkan dengan benar
oleh kebanyakan orang. Dalam bentuk klasik ia berupa teks biasa: kata kunci xref,
lalu subbagian berupa baris 20-byte berlebar tetap (Spec: ISO 32000-2, §7.5.4ISO 32000-2 §7.5.4). Setiap baris adalah offset byte sepuluh digit, generasi lima
digit, dan satu flag — n untuk in-use, f untuk free — yang dipadkan hingga
tepat dua puluh byte sehingga pembaca dapat melompat ke entri mana pun hanya dengan
aritmetika. PDF 2.0 menggantinya dengan cross-reference stream: indeks yang
sama, tetapi biner dan terkompresi di dalam objek stream yang ditandai
/Type /XRef (Spec: ISO 32000-2, §7.5.8ISO 32000-2 §7.5.8). Lebih kecil, dan
mampu mendeskripsikan objek yang dikemas di dalam object stream.
Trailer adalah daftar isi berkasnya (Spec: ISO 32000-2, §7.5.5ISO 32000-2 §7.5.5). Ia menamai /Root — katalog dokumen, satu-satunya objek tempat
segala sesuatu lainnya bergantung — dan /Size, jumlah objeknya. Lalu datang jabat
tangan yang memungkinkan pembacaan mundur: startxref, sebuah offset byte di
barisnya sendiri, dan %%EOF. Pembaca melompat ke akhir, membaca offset itu,
melesat langsung ke cross-reference section, dan mulai bekerja.
- HeaderOne line, %PDF-2.0, naming the version. A binary-marker comment usually follows.
- BodyNumbered indirect objects — dictionaries and streams — referenced by N G R.
- Cross-reference sectionA text table of 20-byte entries, or a compressed /Type /XRef stream in PDF 2.0.
- TrailerNames /Root and /Size, then startxref + offset + %%EOF.
- Read orderA reader starts at %%EOF, follows startxref to the index, then reaches each object directly.
Ada region kelima yang ditumbuhkan oleh berkas berumur panjang: sebuah pembaruan
inkremental. Sebuah perubahan tidak ditulis di tempat. Objek yang berubah, sebuah
cross-reference section yang baru, dan sebuah trailer baru ditambahkan setelah
%%EOF pertama, dan trailer baru itu membawa /Prev — offset dari cross-reference
section sebelumnya (Spec: ISO 32000-2, §7.5.6ISO 32000-2 §7.5.6). Section-section
itu membentuk rantai mundur; untuk nomor objek apa pun, entri terbaru yang menang.
Karena byte aslinya tidak pernah bergerak, pemeriksaan kriptografis atas rentang
byte yang sebenarnya dicakup sebuah tanda tangan tetap berlaku setelah sebuah
pembaruan. Pembaruan inkremental berikutnya masih dapat mengubah apa yang dilaporkan
validator tentang dokumen secara keseluruhan — apakah perubahan pasca-tanda tangan
diizinkan, dan apa yang dianggap disertifikasi oleh tanda tangan itu — tetapi ia
tidak dapat mengubah byte yang ditandatangani itu sendiri. Properti itu adalah
seluruh pokok bahasan pembaruan inkremental.
Contoh praktis
Bagian berjudul “Contoh praktis”Inilah seluruh anatomi dalam satu berkas minimal. Angka-angka di bawah xref
adalah offset byte, dan angka itu harus persis — tunjuk satu karakter melewati
tempat sebuah objek dimulai dan pembaca yang ketat menyerah.
%PDF-2.01 0 obj<< /Type /Catalog /Pages 2 0 R >>endobj2 0 obj<< /Type /Pages /Kids [3 0 R] /Count 1 >>endobj3 0 obj<< /Type /Page /Parent 2 0 R /MediaBox [0 0 612 792] >>endobjxref0 40000000000 65535 f0000000009 00000 n0000000058 00000 n0000000115 00000 ntrailer<< /Size 4 /Root 1 0 R >>startxref186%%EOFBacalah seperti yang dilakukan sebuah parser. Baris terakhir: %%EOF. Di atasnya:
startxref 186, jadi lompat ke byte 186, tempat xref dimulai. Tabelnya
mengatakan objek 1 berada di byte 9. /Root 1 0 R milik trailer menunjuk ke sana —
katalognya — dan dari katalog itu Anda menyusuri /Pages ke pohon halaman dan
menemukan satu-satunya halaman. Objek 0 selalu menjadi kepala daftar-bebas dengan
generasi 65535, sebuah fosil dari desain pertama format ini yang masih diharapkan
ada oleh setiap pembaca.
Kesalahpahaman umum
Bagian berjudul “Kesalahpahaman umum”Jebakannya adalah membaca sebuah PDF seperti sebuah cerita — dari atas ke bawah,
secara berurutan. Ia bukan cerita; ia adalah indeks dengan penunjuk mundur. Nomor
objek tidak harus berurutan dalam berkas, objek dapat muncul dalam urutan fisik apa
pun, dan pembaca tidak pernah bergantung pada posisinya. Peta yang otoritatif
satu-satunya adalah cross-reference section, dan satu-satunya cara menemukan peta
itu adalah offset startxref di paling akhir.
Konsekuensinya mengejutkan orang. Sebuah PDF dengan body sempurna dan satu digit
salah pada startxref tidak dapat dibaca — pembaca tidak dapat menemukan indeksnya.
Sebuah PDF dengan objeknya dalam urutan teracak tetapi dengan cross-reference
section yang benar baik-baik saja. Posisi fisik tidak membawa makna. Posisi yang
tercatat-lah yang membawa semuanya.
Batas dan batasan
Bagian berjudul “Batas dan batasan”Halaman ini menjelaskan struktur fisik, bukan konten halaman. Bagaimana tanda
mendarat di sebuah halaman — operator content-stream, penampilan teks, graphics
state — adalah subjek tersendiri. Ia juga menjelaskan berkas yang terbentuk dengan
baik. PDF di dunia nyata sering kali sedikit rusak dan bertahan hanya karena
penampil yang pemaaf membangun ulang tabel referensi silang dengan memindai kata
kunci obj. Penyelamatan itu adalah perilaku penampil, bukan sesuatu yang dijamin
oleh format.
| Edition | Availability |
|---|---|
| Core | NextPDF is a writer. It records every offset from the output buffer at the moment each object is emitted, so the files it produces have a cross-reference section that matches the body by construction. |
| Pro | Parsing, reconstructing, or repairing a damaged cross-reference table in a file NextPDF did not write is out of scope across every edition. |
| Enterprise | For inspection of an existing file’s structure, use a dedicated parser or validator; NextPDF guarantees correctness for what it writes, not for what it reads. |
Mini-FAQ
Bagian berjudul “Mini-FAQ”Mengapa sebuah PDF memiliki baris penanda biner setelah header? Beberapa alat transfer lawas akan mengacaukan berkas yang mereka kira teks biasa. Komentar ber-bit-tinggi membuat berkasnya terlihat tak ambigu sebagai biner, sehingga ia bertahan melalui perjalanan tanpa perubahan.
Apakah xref stream hanya tabel yang lebih kecil? Sebagian besar, dengan satu kekuatan ekstra. Selain terkompresi, sebuah xref stream dapat mendeskripsikan objek yang disimpan di dalam object stream — entri yang tidak ada cara untuk diungkapkan oleh tabel teks 20-byte klasik.
Bisakah saya memiliki tabel dan stream sekaligus dalam satu berkas? Satu revisi tunggal memakai salah satu dari keduanya. Tetapi sebuah berkas hibrida dapat memasangkan tabel klasik untuk pembaca lama dengan cross-reference stream untuk yang baru, sehingga tiap jenis pembaca menemukan indeks yang ia pahami.
Dokumen terkait
Bagian berjudul “Dokumen terkait”- What a PDF actually is — empat bagian yang sama dilihat sebagai graf objek alih-alih tata letak fisik.
- Incremental updates and why they matter — bagaimana region kelima yang ditambahkan menumbuhkan sebuah berkas dan melindungi tanda tangan.
- Streams and filters — apa yang ada di dalam objek stream pada body dan bagaimana mereka dikompresi.
- PDF 2.0: what changed — mengapa cross-reference stream adalah struktur default yang ditulis NextPDF.
Glosarium
Bagian berjudul “Glosarium”- Header — baris pertama,
%PDF-2.0, menamai versinya; biasanya diikuti oleh komentar penanda biner. - Objek tak langsung (indirect object) — sebuah objek bernomor di body, ditulis
N G obj … endobj, di manaNadalah nomor objek danGgenerasinya. - Dictionary — sebuah peta
<< /Key value … >>dari nama ke nilai; bentuk objek yang paling umum. - Stream — sebuah dictionary ditambah satu blok byte di antara
streamdanendstream, dipakai untuk konten, font, dan gambar. - Cross-reference table (xref) — indeks dari nomor objek ke offset byte; sebuah
tabel teks 20-byte-per-entri secara klasik, sebuah stream
/Type /XRefpada PDF 2.0. - Trailer — kamus yang menamai
/Rootdan/Size, ditemukan melalui offsetstartxrefdi akhir berkas. - Pembaruan inkremental (incremental update) — objek yang berubah, sebuah
cross-reference section baru, dan sebuah trailer baru yang ditambahkan setelah
%%EOF, dengan/Prevmerantai mundur ke section sebelumnya.