MASARYKOVA UNIVERZITA FAKULTA INFORMATIKY
C
w
%, ^ 4
S
-4^ M
^
Vodoznak v PDF souborech BAKALÁŘSKÁ PRÁCE
Lukáš Holeček
Brno, jaro 2008
Prohlášení Prohlašuji, že tato bakalářská práce je mým původním autorským dílem, které jsem vypraco val samostatně. Všechny zdroje, prameny a literaturu, které jsem při vypracování používal nebo z nich čerpal, v práci řádně cituji s uvedením úplného odkazu na příslušný zdroj.
Vedoucí práce: Ing. Michal Brandejs, CSc. 11
Shrnutí Hlavní motivací pro vytvoření této práce bylo nalezení algoritmu, který umožňuje vkládat do PDF dokumentu digitální vodoznak, a napsání příslušného programu spustitelného pod operačním systémem Linux. Velká část práce je věnována formátu PDF a podrobnějšímu popisu vlastností PDF použitých v algoritmu.
m
Klíčová slova PDF, vodoznak, knihovna, C++, Linux, Poppler, font, FreeType
Obsah 1 Úvod 2 Portable Document Format 2.1 Formát PDF 2.2 Struktura souboru PDF 2.2.1 Hlavička 2.2.2 Tělo 2.2.3 Objekty 2.2.4 Objekt typu slovník 2.2.5 Objekt typu proud 2.2.6 Nepřímé objekty 2.2.7 Předdefinované objekty 2.2.8 Tabulka křížových odkazů (cross-reference table) 2.2.9 Trailer 2.3 Přírůstkové aktualizace 2.4 Struktura dokumentu 2.4.1 Katalogstran 2.4.2 Seznam stran 2.4.3 Strana 2.4.4 Dědičnost 2.5 Stránka PDF dokumentu a její obsah 2.5.1 Obsah stránky 2.5.2 Zdroje stránky 2.5.3 Písmo 2.5.4 Font descriptor 2.5.5 Slovník Font 2.5.6 Encoding 2.5.7 Průhlednost a míchání barev 2.5.8 Formulář 2.6 Základní vykreslování v PDF 2.6.1 Transformační matice 2.6.2 Operátory vykreslování 2.6.3 Vykreslení textu 2.7 Bezpečnost a ochrana autorských práv 2.7.1 Šifrování PDF souboru 2.7.2 Standardní ovladač bezpečnosti 2.7.3 Digitální podpis 3 Vodoznak v PDF dokumentu 3.1 Vodoznak 3.2 Postup vložení vodoznaku do PDF dokumentu
3 4 4 4 5 5 5 6 6 6
8 8 9 9 9 10 10 10 11 11 12 12 13 13 14 14 14 14 15 15 16 16 16 16 17 17 17 1
3.3 Spolehlivost vodoznaku v PDF dokumentu Programátorská dokumentace 4.1 Návrh programu 4.1.1 Uživatelské rozhraní 4.1.2 Hierarchie tříd 4.2 Knihovna PDFWriter 4.2.1 Modul PDFWriter 4.2.2 Modul XRefWriter 4.2.3 Modul ObjectWriter 4.2.4 Modul ArrayWriter 4.2.5 Modul DictWriter 4.2.6 Modul StreamWriter 4.2.7 Modul FontWriter 4.2.8 Modul WatermarkWriter 4.3 Nástroj pro vkládání vodoznaku do PDF souboru 4.3.1 Procedura main() 5 Uživatelská dokumentace 5.1 Zkompilování a instalace 5.2 Používání programu 5.2.1 Příklady 5.2.2 Dávkové zpracování více souborů 6 Závěr
4
19 21 21 21 21 22 22 23 25 26 26 27 28 28 29 29 31 31 31 31 35 37
2
Kapitola 1
Úvod Vodoznak na listu papíru od pradávna slouží k určení pravosti a znemožnění (popř. znesnadnění) falzifikace daného dokumentu. Vzhledem k rozšířenosti PDF je dobré vědět, jak dokument v tomto formátu chránit před zneužitím. Vytvoření digitálního vodoznaku po mocí funkcí, které formát PDF nabízí, je jednou z možností. Tato značka se mírně odlišuje od pravého vodoznaku (podrobněji 3.1), ale bezpečnostní funkce jsou - v rámci možností zachovány. Cílem druhé kapitoly je seznámit čtenáře s formátem PDF, jeho syntaxí (2.2), strukturou dokumentu (2.4) a vlastnostmi ulehčujícími modifikaci PDF (2.3). Dále jsou zde uvedeny objekty a funkce důležité pro vykreslení vodoznaku (2.5 a 2.6). O bezpečnosti a šifrování v PDF stručně pojednává podkapitola 2.7. V třetí kapitole se čtenář dozví, co je vodoznak v PDF dokumentu (3.1) a hlavně jakým způsobem ho vytvořit (3.2). Na závěr je probrána možnost odstranění nebo modifikace vodoznaku a obsahu v takto vytvořeném dokumentu a prevence této činnosti (3.3). Čtvrtá kapitola popisuje aplikaci v programovacím jazyku C++, která pomocí postupu vytvořeného v druhé kapitole, doplní do existujícího PDF souboru vodoznak. Tento program je funkční pod operačním systémem Linux a je součástí práce. Postup při instalaci knihovny a nástroje pro vkládání vodoznaku se nachází v úvodu páté kapitoly. Dále je zdůrazněn význam jednotlivých přepínačů zkompilovaného nástroje a probrány některé případy zpracování PDF dokumentů. Kapitola číslo šest shrnuje hlavní cíle práce a vyvozuje závěry.
3
Kapitola 2
Portable Document Format 2.1
Formát PDF
Portable Document Format (PDF) je formát souboru pro přenositelné dokumenty softwarové společnosti Adobe Systems. Jeho hlavním účelem je schopnost zobrazit svůj obsah na růz ných zařízeních stejně. Dokument by měl být vzhledově srovnatelný (v nejhorším případě podobný), pokud je jeho obsah zobrazen na monitoru nebo vytištěn na tiskárně. Tato vlast nost pravděpodobně nejvíce dopomohla k rozsáhlému rozšíření formátu a jeho následné standardizaci. Verze formátu PDF jsou 1.0,1.1,1.2,1.3,1.4,1.5,1.6 a aktuální 1.7. PDF je otevřený formát (veřejně přístupný) a v roce 2007 se verze PDF 1.7 stala mezinárodním standardem (ISO 32000 [1]). Všechny vlastnosti vztahující se k této verzi jsou popsány v referenční příručce [2] volně dostupné na [ ]} Rozsáhlost příručky (přes tisíc stran) je známkou složitosti formátu a velkého množství vlastností. Některé nejvýraznější jsou jmenovitě: •
vložení obrázku, fontu nebo jiného multimediálního souboru přímo do PDF souboru,
•
vytváření vektorové grafiky,
•
míchání barev,
•
transformace (posun, otočení, škálování) souřadného systému,
•
optimalizace PDF souboru pro efektivnější zobrazení na síti,
•
šifrování a zabezpečení dat proti neoprávněnému přístupu,
•
zpětná kompatibilita se staršími verzemi a
•
spousta dalších.
2.2
Struktura souboru PDF
Struktura souboru PDF, jak je zde popsána, slouží pouze pro zorientování v zadaném pro blému. Úplný popis objektů a jejich vlastností lze najít v referenční příručce PDF [2]. Soubor PDF je složen ze čtyř základních částí: •
hlavičky,
•
těla,
1. Většina odborných výrazů použitých při označení formátovacích prvků PDF vychází právě z této oficiální příručky.
4
2. PORTABLE DOCUMENT FORMAT
•
tabulky křížových odkazů a
•
slovníku trailer.
Syntax formátu je case-sensitive, tj. rozlišuje mezi velkými a malými písmeny. Jednořád kové komentáře jsou uvedeny znakem procento („%")• Jednotlivá klíčová slova jsou oddě lena alespoň jedním bílým znakem. Tento znak může být mezera, tabulátor, znak „line feed", „form feed", „carriage return" nebo znak „null". 2.2.1 Hlavička První řádek PDF souboru obsahuje pouze direktivu %PDF-1.7 pro verzi PDF 1.7 (obdobně pro ostatní verze). Navíc může následovat - a často se také uvádí komentář s hodnotou znaků větší než 127, což zaručuje, že program, který zpracovává soubor (např. textový editor), na něj bude nahlížet jako na binární (některé aplikace totiž čtou byty na začátku, aby určily, zda se jedná o ASCII soubor, kde je hodnota každého znaku menší než 128, nebo naopak binární soubor). 2.2.2 Tělo Tělo PDF souboru obsahuje výhradně nepřímé objekty (viz podkapitola 2.2.7). Všechny viditelné prvky na stránkách dokumentu - včetně stránek samotných - jsou popsány v této části souboru. 2.2.3 Objekty Objekty mohou znázorňovat například vložené písmo, obrázek, základní popis stránky, kódování, mohou zprostředkovávat příkazy pro výpis textu a vektorové grafiky nebo repre zentují čísla, řetězce aj. Typy objektů jsou: •
boolean - binární hodnota (true nebo false),
•
číslo - libovolné reálné číslo,
•
řetězec - znaky jsou uvedeny v kulatých závorkách nebo jejich kódy jako série dvojic hexadecimálních číslic v ostrých závorkách,
•
název (nebo jméno) - uveden lomítkem (např. název písmene „é" v PDF se značí ,,/eacute"),
•
null - prázdný objekt; klíčové slovo „null". Komplexnější typy objektů, které mohou obsahovat jiné objekty, jsou:
•
pole - n-tice objektů libovolných typů - každý může být jiný - oddělených bílými znaky v hranatých závorkách,
•
slovník - viz podkapitola 2.2.4,
•
proud - viz podkapitola 2.2.5. 5
2. PORTABLE DOCUMENT FORMAT
2.2.4 Objekt typu slovník Slovník je seznam tvořený dvojicemi objektů, z nichž první je typu název a druhý je libovolný. Celý seznam je uzavřen do dvojic ostrých závorek. Taková struktura umožňuje přiřadit ke každému názvu hodnotu podobně jako u asociativních polí. Slovník na příkladu 1 obsahuje položku „Stringltem", která representuje řetězec s hodno tou „řetězec" a položka „Subdictionary" je opět slovník. Často se také uvádí názvy „Type" a popřípadě i „Subtype" jako identifikátory slovníku. «
/Type / P ř i k l a d /Subtype / P r i k l a d S l o v n i k u /Stringltem (řetězec) /Subdictionary « / I t e m l 0.4 /Item2 true / L a s t l t e m (OK) » » Příklad 1: Objekt typu slovník.
2.2.5 Objekt typu proud Proud je slovník následovaný posloupností znaků uzavřených do klíčových slov „stream" a „endstream". Používá se hlavně pro uložení grafických operátorů PDF (vykreslení textu a jiných geometrických útvarů) nebo vsazení souboru písma, obrázků do PDF souboru. Slovník proudu musí obsahovat položku „Length" určující, kolik bytů je obsaženo mezi klíčovými slovy „stream" a „endstream". Další podstatnou položkou je „Filter". Je to název nebo pole názvů filtrů, které se použijí k dekódování posloupnosti bytů před jejím použitím. Nespornou výhodou proudu oproti řetězci je možnost uložení neomezeného množství dat. To je dáno tím, že proud může být načítán do paměti postupně, kdežto řetězec musí být načten celý. Poznámka: Proud je nutné uvádět jako nepřímý objekt (viz další podkapitola).
2.2.6 Nepřímé objekty Speciální případ objektu je nepřímý objekt (angl. indirect objed). Ten nesmí být součástí jiného objektu a lze se na něj odkazovat. Dvě čísla na začátku slouží k identifikaci objektu. První je číslo objektu a druhé je číslo jeho generace (angl. generation number, viz podkapitola 2.3). Následuje klíčové slovo „obj" a samotný objekt libovolného typu, který končí klíčovým slovem „endobj". Na příkladu 2 je nepřímý objekt číslo jedna s generačním číslem nula typu název. Tuto identifikaci lze použít k odkazování na skutečný nepřímý objekt. 6
2. PORTABLE DOCUMENT FORMAT
1 0 obj /NejakyNazev endobj Příklad 2: Nepřímý objekt typu název. Odkaz „5 0 R" ukazuje na nepřímý objekt s číslem pět a generačním číslem nula. Odkazy lze dosadit místo skutečných hodnot. Příklad 3 znázorňuje slovník, který má položku „Rete zec" nahrazenu odkazem na nepřímý objekt číslo devět. Ekvivalentní slovník by měl stejné položky, ale hodnota „Retezec" by byla konkrétní hodnota přímo dosazená za odkaz. Řešení z příkladu 3 je vhodné pouze v případě, že se na řetězec (nepřímý objekt) odkazuje vícekrát, tak je možné snížit velikost PDF souboru a potřebné paměti při zpracovávání dokumentu. Tato skutečnost je stěžejní pro efektivní využití paměti nástroje pro vkládání vodoznaku.
8 0 obj « /Type /Slovník /ID 100 /Retezec 9 0 R » endobj 9 0 obj ( T o h l e je n e j a k ý endobj
retezec.)
Příklad 3: Odkaz na nepřímý objekt typu řetězec.
Poznámka: Protože proud musí být nepřímý objekt, ve slovníku se vždy uvádí pouze jeho odkaz.
2.2.7 Předdefinované objekty Formát PDF uvádí mnoho předdefinovaných slovníků a proudů. Např. slovník, který popi suje jednu stránku dokumentu (viz podkapitola 2.2.7) musí mít položku se jménem „Type" nastavenu na hodnotu „Page" apod. 2.2.8 Tabulka křížových odkazů (cross-reference table) Tabulka křížových odkazů slouží primárně k rychlému přístupu k nepřímým objektům. Obsahuje byte offset, generační číslo a příznak každého nepřímého objektu v PDF souboru. Má pevně stanovený formát (viz příklad 4). Dvojčíslí, která se v seznamu vyskytují (v příkladě „0 1", „3 1", „23 2" a „30 1") značí číslo objektu, na který položka následující za dvojčíslím ukazuje, a počet položek v tomto 7
2. PORTABLE DOCUMENT FORMAT
xref 0 1 0000000000 65535 f 3 1 0000025325 00000 n 23 2
0000025518 00002 n 0000025635 00000 n 30 1 0000025777 00000 n Příklad 4: Tabulka křížových odkazů. podseznamu. Objekty 23 a 24 jsou popsány v podseznamu uvedeném dvojčíslím „23 2". Řádky podseznamu mají velikost dvacet bytů (včetně dvou-bytového znaku konce řádku nebo mezery a jedno-bytového znaku konce řádku). Každý řádek podseznamu obsahuje: •
desetimístné číslo - místo v souboru (byte offset; počet bytů od začátku souboru), kde se daný objekt nachází,
•
pětimístné číslo - generace objektu,
•
příznak - „f" pro volnou položku (odstraněný objekt) nebo „n" používanou položku.
Položka označená nulou má vždy příznak „f" a neukazuje na žádný objekt, ale na další volnou položku v seznamu (tj. byte offset je číslo další volné položky tabulce). Podobně další volné položky až na poslední ukazující opět na nultou položku (volné položky tvoří cyklický seznam). Soubor PDF může mít více těchto tabulek (viz kapitola 2.3). 2.2.9 Trailer Na posledním řádku PDF souboru je řetězec „%%EOF". Dva řádky před touto značkou ob sahují klíčové slovo „startxref" a byte offset poslední tabulky křížových odkazů. Předcházející řádky jsou slovník (tzv. trailer) uvedený slovem „trailer". Důležité položky slovníku jsou: •
„Size" - nejvyšší číslo objektu v souboru plus jedna,
•
„Prev" - byte offset předposlední tabulky odkazů,
•
„Root" - odkaz na katalog stran (viz podkapitola 2.4.1),
•
„Encrypt" (viz kapitola 2.7).
2.3
Přírůstkové aktualizace
Obsah souboru PDF je možné jednoduchým způsobem modifikovat obsah pomocí tzv. pří růstkových aktualizací (angl. incremental updates). Pokud je potřeba změnit některý objekt v PDF, mění se pouze jeho kopie, která se následně připojí na konec souboru (za poslední značku „%%EOF") do nového aktualizovaného těla. Poté je nutné vložit nakonec souboru: 8
2. PORTABLE DOCUMENT FORMAT
•
tabulku křížových odkazů - tabulka obsahuje pouze položky, které byly přidány (viz dále), modifikovány (mají nový byte offset) nebo smazány (změní se příznak z „n" na „f" a číslo generace objektu se zvýší o jedna 2 ),
•
trailer - položka: -
„Size" musí obsahovat původní počet objektů v souboru plus počet nově přida ných objektů,
-
„Prev" je byte offset předchozí tabulky křížových odkazů a
-
„Encrypt" musí být obsažena v novém slovníku, pokud je dokument zašifrován (viz podkapitola 2.7),
•
byte offset nové tabulky odkazů za klíčovým slovem „startxref" a
•
značku „%%EOF" na konci souboru.
Poznámka: V souboru se může nacházet více objektů se stejnou dvojicí čísel, ale použije se pouze ten, který je v nejnovější tabulce křížových odkazů. Nově přidaný objekt má v PDF buďto: •
unikátní číslo objektu a číslo generace nula nebo
•
číslo jedné z volných položek (nesmí to být položka nula) a její číslo generace (položka v tabulce odkazů mění příznak z „f" na „n").
2.4
Struktura dokumentu
Stránky v PDF dokumentu tvoří stromovou strukturu. Kořen stromu je seznam stránek, uzly stromu jsou další seznamy stránek a listy jednotlivé stránky. 2.4.1 Katalogstran Katalog je nepřímý objekt typu slovník, na který odkazuje položka „Root" ve slovníku „trai ler". Umožňuje nastavit různé parametry (aktualizace verze PDF souboru, očíslování stránek, nastavení prohlížeče, záložky apod.) a odkazy, z nichž nejdůležitější ukazuje na kořen stromu stran. Nezanedbatelné položky slovníku jsou: •
»Type" - musí obsahovat řetězec „Catalog",
•
„Pages" - odkaz na seznam stránek, který je kořenem stromu stran.
2.4.2 Seznam stran Seznamy stran (Page Tree Nodes) jsou kořenem a uzly stromu. Je to nepřímý objekt typu slovník. Musí obsahovat následující položky: •
nType" - řetězec „Pages",
2. Maximální velikost čísla generace objektu je 65535 (tj. taková položka není znovu použitá).
9
2. PORTABLE DOCUMENT FORMAT
•
„Parent" - odkaz na předcházející uzel (tato položka chybí v kořenu stromu stran),
•
„Kids" - pole odkazů na následující uzly nebo listy,
•
„Count" - počet listů (stránek), které obsahuje podstrom s tímto seznamem stran v roli kořene podstromu.
2.4.3 Strana Strana je listem ve stromu stran. Je to opět nepřímý objekt typu slovník. Povinné a důležité položky jsou: •
„Type" - řetězec „Page",
•
„Parent" - odkaz na předchozí uzel,
•
„LastModified" - datum a čas poslední změny, 3
•
„Resources" - slovník obsahující objekty potřebné k zobrazení stránky (viz podkapi tola 2.5.2),
•
„MediaBox" - pole čtyř čísel označujících rozměry fyzického média, na kterém se má stránka zobrazit/vytisknout,
•
„CropBox" - pole čtyř čísel označujících hranice viditelné části stránky (pokud položka chybí je implicitně použita hodnota „MediaBox"),
•
„Contents" - odkaz nebo pole odkazů na proudy potřebné k vykreslení stránky (viz podkapitola 2.5.1),
•
„Rotate" - otočení stránky po jejím vykreslení (hodnota v násobcích devadesáti stupňů; implicitně nula).
Pro zachování přenositelnosti elektronické podoby dokumentu jsou všechny jednotky (platí pro „MediaBox" a „CropBox") uváděny v 1/72 palce. 2.4.4 Dědičnost Pokud některá položka ve slovníku stránky chybí, může být nahrazena stejnou položkou z nejbližšího předchozího uzlu, který ji definuje. Tato vlastnost se nazývá dědičnost. Pouze položky „Resources", „MediaBox", „CropBox" a „Rotate" lze takto nahradit. Například ve stromu, kde má jeden z uzlů nastaveno otočení („Rotate") na hodnotu devadesát, budou všechny stránky podstromu s tímto uzlem jako kořen, otočeny o devadesát stupňů, není-li uvedeno jinak v nejbližším podstromu. Znázornění takového stromu je na obrázku 1, kde tmavé prvky mají položku „Rotate" rovnu devadesáti. 2.5
Stránka PDF dokumentu a její obsah
K zobrazení PDF stránky je třeba znát písmo, obrázky a jiné multimediální prvky (zdroje stránky), které se na ní nachází, a operátory nutné k vykreslení jejího obsahu. 3. Datum a čas v PDF je řetězec tvaru „D:YYYYMMDDHHmmSSZ", kde „YYYY" je rok, „MM" měsíc, „DD" den, „HH" hodina, „mm" minuta, „SS" sekunda, „Z" značí, že jede o univerzální čas (LÍT). Podrobnější popis se nachází v [4].
10
2. PORTABLE DOCUMENT FORMAT
Obrázek 1: Dědičnost - tmavé prvky jsou pootočeny o devadesát stupňů. 2.5.1 Obsah stránky Vzhled stránky je dán sérií operátorů pro vykreslení textu, obrázků a jiných grafických prvků (viz podkapitola 2.6). Tyto operátory jsou zadány v proudech, na které odkazuje položka „Contents" (odkaz nebo pole odkazů) dané stránky. 2.5.2 Zdroje stránky Položka stránky „Resources" odkazuje na zdroje stránky. Je to slovník, kde jsou uvedeny odkazy na nepřímé objekty použité pří vykreslování stránky. Nepovinnou položkou slovníku je pole jmen „ProcSet" udávající, jaké sady operátorů se použijí pro zobrazení stránky na postscriptovém zařízení. Jména a významy sad kreslících operátorů jsou: „PDF" - kreslení, průhlednost a míchání barev, „Text" - vykreslování písma, „ImageB" - černobílé obrázky (masky), „ImageC" - barevné obrázky, „Imagel" - obrázky s definovanou paletou barev. Ostatní položky jsou slovníky zdrojů, které přiřazují nepřímým objektům názvy (viz příklad 5). Tyto názvy jsou použity jako parametry operátorů v proudu obsahu stránky. Jsou to: 11
2. PORTABLE DOCUMENT FORMAT
•
„Font" - písma (viz podkapitola 2.5.3),
•
„XObject" - obrázky nebo formuláře Form (viz podkapitola 2.5.8),
•
„ExtGState" - objekty měnící stav vykreslování (viz podkapitola 2.5.7).
XObject « /Obrazek2 11 0 R / F o r m u l a r 5 15 0 R » Příklad 5: Slovník zdrojů typu XObject
2.5.3 Písmo Soubor písma tzv. font je možné (jako jiné zdroje) do PDF souboru vložit nebo - v horším případě - se odkazovat na externí soubor. Vložený font je uložen jako proud. Slovník proudu pro TrueType a Type 1 písma obsahuje položky (kromě standardní „Length"): •
„Lengthl" - velikost TrueType souboru nebo délka textové části Type 1 fontu v bytech,
•
„Lengthl" - délka zašifrované části Type 1 fontu,
•
„Lengths" - délka poslední části písma Type 1 (většinou obsahuje 512 nul a klíčové slovo „cleartomark").
Na objekt s fontem odkazuje položka „FontFile" resp. „FontFilel" pro Type 1 resp. TrueType písma v tzv. font descriptoru. Poznámka: PDF může obsahovat některý ze čtrnácti standardních fontů, u kterých se neu vádí soubor písma. Bohužel neobsahují všechny české znaky, proto zde nebudou podrobněji popsány.
2.5.4 Font descriptor Slovník font descriptor popisuje podrobně vlastnosti fontu. Jeho povinné položky jsou:4 •
nType" - řetězec „FontDescriptor",
•
„FontName" - postscriptový název písma,
•
„Flags",
•
„FontBBox",
•
„ItalicAngle",
•
„Ascent",
4. Popis položek týkajících fontu je v [ ] a hlavně na [5].
12
2. PORTABLE DOCUMENT FORMAT
•
„Descent",
•
„CapHeight",
•
„StemV". Na tento objekt odkazuje položka „FontDescriptor" ve slovníku Font.
2.5.5 Slovník Font Slovník písma Font je nepřímý objekt, který se použije ve zdrojích stránky v podslovníku Font k pojmenování písma. Základní položky jsou: •
„Type" - řetězec „Font",
•
„Subtype" - řetězec „Typel" nebo „TrueType" určující typ fontu,
•
„BaseFont" - stejné jako „FontName" položka ve slovníku font descriptor,
•
„Widths" - ke kódu znaku přiřadí jeho šířku (pole šířek; kód znaku je index pole),
•
„FirstChar" - kód prvního znaku v poli „Widths",
•
„LastChar" - kód poledního znaku v poli „Widths",
•
„FontDescriptor",
•
„Encoding" - odkaz nebo slovník (viz podkapitola 2.5.6).
2.5.6 Encoding Slovník Encoding, který je položkou ve slovníku Font, blíže specifikuje, jaké kódování bude pro text používající konkrétní písmo použito. Položky jsou: •
„Type" - řetězec „Encoding",
•
„BaseEncoding" - základní kódování („MacRomanEncoding", „MacExpertEncoding" nebo „ WinAnsiEncoding"),
•
„Differences" - mapuje kód znaku (rozsah je 0 - 255) na daný název znaku (např. „rcaron" pro „i"),
Kódy znaků v poli Differences se nahradí příslušnými písmeny podle názvu písmene. Po kud dalšímu názvu nepředchází kód použije se předchozí o jedna větší. Neuvedené kódy jsou mapovány pomocí základního kódování. Pole Differences může vypadat jako na příkladu 6. [
39 / q u o t e s i n g l e 96 / g r a v e 174 /AE / O s l a s h
] Příklad 6: Slovník Encoding.
13
2. PORTABLE DOCUMENT FORMAT
2.5.7 Průhlednost a míchání barev Míchání barev (tzv. blending) je operace, při které se jednotlivé obrazové body spodních vrstev a vrchní vrstvy určitým způsobem směšují (např. násobení, dělení, sčítání, odčítání a jiné složitější operace). K tomu slouží slovník stavu grafických parametrů (angl. graphical state parameter dictionary). Položky slovníku důležité pro míchání barev a průhlednost jsou: •
„Type" - řetězec „ExtGState",
•
„BM" - název operace pro míchání barev (hodnoty mohou být „Normal", „Multiply", „Screen", „Overlay", „Darken", „Lighten", „ColorDodge", „ColorBurn", „HardLight", „SoftLight", „Difference" a „Exclusion"),
•
„CA" - průhlednost obrysu (koeficient 0,0 -1,0),
•
„ca"- průhlednost výplně.
2.5.8 Formulář Formulář (angl. form XObject) je nepřímý objekt typu proud, který zahrnuje - podobně jako stránka - položku „Resources", kde jsou popsány zdroje formuláře, a operátory pro vykreslení obsahu mezi klíčovými slovy proudu „stream" a „endstream". Takový objekt lze poté, co byl přidán do zdrojů stránky, zobrazit na stránku jednoduchým operátorem pro vykreslení (viz kapitola 2.6). Tento postup se hodí hlavně pro grafické prvky, které se opakovaně vykreslují (např. vodoznak). Položky formuláře jsou: •
„SubType" - musí být řetězec „Form",
•
„BBox" - pole čtyř čísel značících rozměry celého formuláře,
•
„LastModified" - datum a čas poslední změny. Jméno formuláře je ve zdrojích stránky uvedeno ve slovníku „XObject".
2.6
Základní vykreslování v PDF
Vykreslení stránky probíhá pomocí operátorů uvedených v proudu stránky nebo formuláře. Grafické prvky jsou vykreslovaný do souřadného systému stránky v pořadí, v jakém jsou uvedeny jejich příslušné operátory (platí i pro text). 2.6.1 Transformační matice Transformační matice se v PDF dokumentu používají k posunutí, zvětšení, zmenšení, otočení a zkosení souřadného systému. Tak lze docílit toho, že následně vykreslený grafický objekt bude transformován stejným způsobem. Základní typy transformačních matic jsou matice: •
identity - [1, 0,0,1,0,0] (tj. souřadný systém zůstane nezměněn),
•
posunutí -[1,0, 0,1, tx,ty], kde tx je posunutí na horizontální ose a ty na vertikální ose souřadného systému, 14
2. PORTABLE DOCUMENT FORMAT
•
změny velikosti - [sx,0,0,sy,0,Ö\, roztažení,
kde sx je horizontální roztažení a sy je vertikální
•
otočení - [cos6, sin6, sin6, cos6,0,0] je otočení o úhel 9,
•
zkosení - [l,tana, tanß, 1,0,0] pro zkosení horizontální resp. vertikální osy o úhel a resp. ß. Poznámka: Prvky matice v PDF mají jednotku radián pro úhel a 1 /72 palce pro vzdálenost.
2.6.2 Operátory vykreslování Operátory vykreslování a změny grafických parametrů (např. transformace souřadného systému, změna tlouštky čar nebo použití průhlednosti) se zapisují v postfixovém tvaru do proudu, na který odkazuje hodnota v položce Contents objektu stránky (viz podkapitola 2.5.1). Operátor pro změnu souřadného systému je pak zapsán v následujícím tvaru. a b c d e f cm Za prvky (čísla v pohyblivé desetinné čárce) transformační matice oddělenými bílým místem následuje operátor „cm". Při změně určitých grafických parametrů je vhodné předchozí hodnoty parametrů uložit. To se provádí pomocí operátoru „q", který zapíše parametry na vrchol zásobníku. Naopak „Q" obnoví stav parametrů podle hodnot na vrcholu zásobníku a ty jsou z něj následně odstraněny. Formulář (viz podkapitola 2.5.8) je vykreslován jednoduchým operátorem „Do" 5 s pa rametrem název formuláře (stejný název musí být uveden v podslovníku „XObject" zdrojů stránky). Podobně se provádí změna průhlednosti a míchání barev (viz podkapitola 2.5.7) operátorem „gs". 2.6.3 Vykreslení textu Komplexnější jsou operátory pro vykreslení textu použitím některého fontu z PDF souboru. Ty jsou uzavřeny do klíčových slov „BT" a „ET". Výběr aktivního fontu se provádí operá torem „Tf". Jeho prvním parametrem je název nějakého fontu ze slovníku Resources. Druhý parametr je velikost písma. Operátor „Tj" má jako argument řetězec, který vykreslí na stránku aktivním fontem. Před vykreslením textuje možné změnit jeho vlastnosti. Nejzajímavější je mód vykreslení textu. Mění se pomocí „Tr". Jediným parametrem je číslo. Může to být například: •
0 - pouze vyplní text zvolenou barvou (barva výplně se mění operátorem „rg" 6 ),
•
1 - vykreslí pouze obrys textu (barva resp. šířka obrysu se mění operátorem „RG" resp. „w"),
•
2 - vyplní text i jeho obrys.
5. Po provedení operátoru „Do" se hodnoty grafických parametrů nezmění (implicitně jsou použity operátory „q" a „Q"). 6. Barvy v PDF jsou definovány třemi reálnými čísly v rozsahu 0,0-1,0. Čísla jsou oddělena bílým místem a značí koeficienty jednotlivých barevných složek v systému RGB.
15
2. PORTABLE DOCUMENT FORMAT
2.7
Bezpečnost a ochrana autorských práv
V této kapitole je velmi stručně popsána bezpečnost a přístupová oprávnění formátu PDF (pro bližší informace [6] a [7]). 2.7.1 Šifrování PDF souboru PDF dokument může být zašifrován a chráněn tak před neoprávněným přístupem (mo difikací nebo čtením dokumentu). O to se stará tzv. šifrovací slovník. Je to objekt, na který odkazuje položka Encrypt slovníku trailer. Zašifrovány mohou být pouze objekty typu řetězec a proud. Nejdůležitější položky slovníku jsou: •
„Filter" - název tzv. ovladače bezpečnosti (viz podkapitola 2.7.2),
•
„SubFilter" - nepovinný název plně popisující formát slovníku,
•
„V" - kódovací a dekódovací algoritmus (hodnoty 1-4),
•
„Length" - délka klíče, kterým byla data zašifrována, v bitech (hodnota je v rozsahu 40 -128 a je násobkem osmi).
2.7.2 Standardní ovladač bezpečnosti Ovladač bezpečnosti (angl. security handler) je program sloužící ke správě bezpečnosti PDF dokumentu. Název ovladače se uvádí v šifrovacím slovníku v položce „Filter". Všechny aplikace by měly podporovat standardní ovladač (jeho název je „Standard"). Standardní ovladač je založen na dvou heslech. Heslo vlastníka (angl. owner password) umožňuje uživateli plnou kontrolu na PDF dokumentem (včetně jeho modifikace). Oproti tomu uživatelské heslo (angl. user password) ho omezuje pouze na operace specifikované v šifrovacím slovníku. 2.7.3 Digitální podpis Digitální podpis umožňuje vložit do PDF informace o autorovi (podpisujícím) a o stavu dokumentu a tím zajistit autenticitu uživatele a obsahu. Informace jsou uloženy ve speciálním slovníku (tzv. signature dictionary). Hodnota podpisu se vypočítá pomocí určité funkce z části nebo z celého dokumentu (kromě položky, která podpis obsahuje) a uloží se do položky slovníku „Contents". Hodnota položky „Filter" je název ovladače, který se použije k ověření podpisu.
16
Kapitola 3
Vodoznak v PDF dokumentu 3.1
Vodoznak
Pravý vodoznak je značka na papíře, která vzniká během jeho výroby [8]. Digitální vodo znak PDF dokumentu (dále jen vodoznak) je obsažen - oproti pravému vodoznaku - na elektronické podobě stránky Musí splňovat následující kritéria. •
Neměl by být odstranitelný nebo změnitelný
•
Měl by na stránce zůstat stále rozpoznatelný (i po jejím vytisknutí).
•
Měl by chránit obsah dokumentu před neoprávněným zásahem.
•
Text a jiné prvky stránky, na kterou byl vodoznak přidán, musí zůstat čitelné.
Vodoznak popsaný v dalších kapitolách je textový (tj. řetězec zobrazený v dokumentu použitím určitého fontu), pro jednoduchost se nachází se na všech stránkách a má největší možnou velikost. Úkolem této části je najít postup pro zakomponování textu, který bude mít - pokud možno - výše uvedené vlastnosti, do PDF souboru a zhodnotit výsledný vodoznak z hlediska zabezpečení PDF dokumentu. 3.2
Postup vložení vodoznaku do PDF dokumentu
Vodoznak je v dokumentu většinou samostatný objekt, který se vícekrát opakuje (např. je na více stránkách). Objekt formulář (viz podkapitola 2.5.8) má podobné vlastnosti. Lze ho použít vícekrát bez zbytečného opakovaného užití zobrazovacích operátorů a je nezávislý na obsahu stránky (tj. obsahuje vlastní zdroje a lze jej posunout, otočit nebo zvětšit bez ovlivnění ostatních objektů na stránce). Proto je to vhodný prvek pro vykreslování vodoznaku. Kvůli zachování čitelnosti je nutné použít slovník graphical state parameter dictionary (viz podkapitola 2.5.7) pro zprůhlednění textu vodoznaku. Vodoznak je možné na stránce vykres lit jako první (ve spodní vrstvě) bez použití průhlednosti, ale některé objekty (např. obrázky) mohou znemožnit jeho čitelnost.1 Průhlednosti a míchání barev využívají vlastnosti PDF verze 1.4 a vyšší. PDF podporuje změnu čísla verze formátu dokumentu na pozdější ve slovníku Catalog u položky Version, ale opět až od PDF 1.4. U nižších verzí PDF dokumentu se musí modifikovat přímo hlavička. Měl by to být jediný zásah do původní části dokumentu. 1. Tento přístup je přeci jenom vhodnější, pokud je třeba později převést PDF soubor do formátu PostScript Level 1 (např. tisk na staré postscriptové tiskárně) a také se nemusí počítat hodnota obrazového bodu (tj. není použita průhlednost a míchání barev).
17
3. VODOZNAK V PDF DOKUMENTU
30 0 obj « / S u b t y p e /Form /BBox [ - 1 1 4 - 1 8 0 15410 803 ] / L e n g t h 92 /Resources « / E x t G S t a t e « /GSWM 28 0 R » / F o n t « /ECNiWM 29 0 R » / P r o c S e t [ /PDF / T e x t ] » » stream /GSWM gs 1.0 1.0 0.9 rg 0.9 0.9 0.9 RG 20 w BT /ECNTWM 1000 Tf 2 Tr <566F646F7A6E616B> Tj ET endstream endobj Příklad 7: Nepřímý objekt typu Form.
18
3. VODOZNAK V PDF DOKUMENTU
Celý formulář může vypadat jako na příkladu 7, kde „BBox" označuje hranice konkrétního textu vodoznaku a „Length" délku proudu v bytech. Ve slovníku „Resources" jsou uvedeny zdroje písma vodoznaku a slovník graphical state parameter dictionary. Vykreslování používá sady operátorů „PDF" (průhlednost) a „Text" (vykreslení písma). V proudu je operátor „gs" k aplikování průhlednosti, „rg" a „RG" pro nastavení barvy výplně a obrysu, „w" k definování šířky obrysu, nastavení fontu písma a jeho velikosti „Tf" a „Tr" s parametrem „2" k zobrazení výplně i obrysu písma. Zadaný text se vypíše pomocí operátoru „Tj", kde jako parametr je hexadecimální řetězec. S použitím míchání barev a průhlednosti bude vodoznak vykreslen jako poslední objekt na stránce. Proto je nutné přidat odkaz na objekt vodoznaku (formulář) do zdrojů stránky a do pole „Contents" přidat odkaz na nový objekt,2 který bude vykreslovat formulář (tj. obsahuje operátor „Do"). Před vykreslením použít transformační matice tak, aby vodoznak zabíral celou stránku. Pomocí přírůstkových aktualizací (viz kapitola 2.3) se na konec PDF souboru vypíší všechny nové a aktualizované objekty a modifikovaná část tabulky křížových odkazů se slovníkem trailer. 3.3
Spolehlivost vodoznaku v PDF dokumentu
Pravý vodoznak má chránit obsah dokumentu a jeho pravost a je proto důležité, aby jej nebylo možné snadno odstranit. Digitální vodoznak vytvořený způsobem popsaným v předchozí kapitole lze poměrně jednoduše odstranit. Stačí smazat poslední přírůstek aktualizace, kte rým byl do souboru vložen i vodoznak, a tím získat předchozí verzi dokumentu. Vhodnější metoda - oproti přírůstkovým aktualizacím - je nezahrnout do PDF souboru původní verze změněných objektů (tj. stránky a jejich zdroje). Poté je stále možné - sice s vyna ložením většího úsilí - získat původní dokument pouhým odstraněním nových prvků v poli „Contents". Řešení, které potenciálnímu útočníkovi ještě více znesnadní práci, je zřetězení bytů ve všech proudech s příkazy pro vykreslení jedné stránky do jednoho objektu (položka „Contents" bude obsahovat pouze odkaz na tento objekt) a použití filtru (např. komprese) na celý tento proud. Ovšem stále lze měnit objekty v souboru. Proto je nejlepším řešením - bohužel značně komplikovaným-použití šifrování a digitálního podpisu (viz kapitola 2.7) bez přírůstkových aktualizací.
2. Pořadí vykreslování je dáno pozicí v poli „Contents"
19
3. VODOZNAK V PDF DOKUMENTU
Obrys stránky
Volitelné vlastnosti textu: - písmo, - barva výplně, - barva obrysu, - způsob míchání barev a průhlednost, - vrstva (před nebo za původním textem), - úhel otočení,
Obrázek 2: Náčrtek vodoznaku na stránce.
20
Kapitola 4
Programátorská dokumentace 4.1
Návrh programu
Postup z podkapitoly 3.2 popisující vložení vodoznaku do PDF dokumentu je využit při návrhu aplikace v programovacím jazyku C++ v této kapitole. Program byl navržen s ohle dem na případné další rozšíření o funkcionalitu popsanou v podkapitole 3.3 (tj. šifrování a digitální podpis). Základním účelem programu je vložení objektů vodoznaku a změna stránek a jejich zdrojů. Načtení objektů a struktury dokumentu z původního souboru je možné provést po mocí funkcí a tříd knihovny Poppler [9].1 K modifikaci PDF dokumentu slouží nově vytvořená knihovna nazvaná PDFWriter, která je součástí práce. Vkládání vodoznaku je realizováno voláním funkcí knihovny z procedury main(). 4.1.1 Uživatelské rozhraní Uživatel musí mít možnost výběru vlastního fontu, kterým bude vodoznak vykreslen, pro tože standardní písma PDF neumí jiná kódování než ISO 8859-1 (tj. chybí některé české znaky). K načtení vlastností a metriky písma je pravděpodobně nejvhodnějším kandidátem knihovna funkcí FreeType [10].1 Vodoznak může být v některých případech nečitelný, proto - kromě zmíněného písma by měl uživatel moci změnit: •
barvu výplně,
•
barvu a šířku obrysu,
•
natočení a
•
průhlednost vodoznaku.
Samozřejmě je nutné, aby uživatel byl schopen měnit také text vodoznaku. Parametry jsou předávány pomocí příkazové řádky nebo na standardní vstup aplikace. 4.1.2 Hierarchie tříd Nová knihovna PDFWriter často používá funkce knihovny Poppler, pokud čte z existujícího souboru. Pro zachování transparentnosti kódu byla také použita podobná hierarchie tříd. Třída PDFWriter je obdobou PDFDoc v knihovně Poppler. Spravuje nový nebo existující dokument. Hlavně umožňuje přístup k tabulce křížových odkazů, která je reprezentována třídou XRefWriter. S její pomocí lze měnit, vytvářet a mazat odkazy v tabulce, objekty v PDF 1. Knihovny použité v programu jsou vydány pod licencí GNU GPL.
21
4. P R O G R A M Á T O R S K Á D O K U M E N T A C E
souboru a položky slovníku trailer. Tabulku znázorňuje třída XRefWriterTable. Zde je číslo každého nepřímého objektu uvedeno jako index v asociativním poli (typ Map), které ukazuje na jednotlivé prvky tabulky typu XRefWriterEntry. Prvky obsahují - stejně jako u klasické tabulky - offset, číslo generace a příznak objektu, na který ukazují. Navíc je zde ukazatel na nepřímý objekt. Třída ObjectWriter (podobně jako Object v knihovně Poppler) je rozhraním pro PDF objekty. Zde je uveden typ (číslo, odkaz, slovník, pole apod.) a proměnná příslušného typu (např. int pro celé číslo). Typy komplexnějších objektů (slovník, proud a pole) podrobněji popisují další třídy (viz kapitola 4.2). Pro snížení spotřeby paměti: •
je použito výhradně ukazatelů a kontejnerů typu Map a List1 standardní knihovny jazyka C++.
•
jsou objekty (ObjectWriter) v tabulce XRefWriterTable alokovány, pouze pokud jsou změněny původní objekty.
•
jsou byty proud vypsány do dočasného souboru.
4.2
Knihovna
PDFWriter
Jak už bylo popsáno v předchozí kapitole, knihovna PDFWriter poskytuje třídy a funkce k vytváření nebo modifikaci souboru PDF. Zde jsou popsány podrobně funkce a vlastnosti tříd knihovny a způsob vytváření objektů pro manipulaci s PDF dokumenty. Kapitola slouží výhradně programátorům a předpokládá znalosti programovacího jazyka C++. Následující podkapitoly nesou názvy jednotlivých hlavičkových souborů (modulů) a popisují třídy, které jsou v nich obsaženy. 4.2.1 Modul PDFWriter Třída PDFWriter slouží k vytvoření nového nebo načtení existujícího souboru PDF. Konstruktor má stejné parametry jako konstruktor PDFDoc z knihovny Poppler. Jediným rozdílem je to, že pokud má parametrfilenameA (název existujícího PDF souboru) hodnotu NULL (tj. neplatný ukazatel), potom se vytváří nový PDF soubor. Šifrování není „zatím" podporováno, proto ostatní parametry (heslo vlastníka a uživatele) jsou použitelné pouze pro čtení ze zašifrovaného souboru (to lze využít pro uložení souboru v nezašifrované podobě a k následující modifikaci pomocí knihovny PDFWriter). Konstruktor také vytvoří objekt typu XRefWriter (viz podkapitola 4.2.2) znázorňující novou tabulku křížových odkazů. Funkce: •
okToChangeO - zjistí, jestli má uživatel dostatečná práva k editaci souboru (pokud ano, vrátí hodnotu gTrue2),
1. Kontejnery typu Map a List jsou použity místo obyčejného pole, protože funkce reallocQ nebo dvojice operátorů delete a new potřebné při vytváření nových prvků pole, by přesunuly celé pole na jiné místo v paměti a to by způsobilo neplatnost ukazatelů odkazujících na jednotlivé prvky pole, které byly předány jako návratové hodnoty některých metod před samotnou realokací paměti pole. Navíc lze k prvkům přistupovat rychleji, pokud jsou uspořádány v asociativním poli Map. 2. Hodnoty typu GBool, které používá knihovna Poppler a PDFWriter, jsou ekvivalentní hodnotám typu bool (tj. gTrue = true a gFalse = false)
22
4. P R O G R A M Á T O R S K Á D O K U M E N T A C E
•
getCatalogO - vrátí katalog stran z původního souboru nebo NULL pokud soubor neexistuje,
•
replacePageO s parametrem i - vrátí PDF objekt3 reprezentující z'-tou stránku,
•
printO - vytiskne novou část PDF dokumentu pomocí přírůstkových aktualizací,
•
getWriterErrorO - vrátí kód poslední chyby
4.2.2 Modul XRefWriter Objekt typu XRefWriter slouží ke správě tabulky křížových odkazů a slovníku trailer. Konstruktor vytvoří tabulku a slovník trailer z hodnot původního souboru. Tabulka odkazů je typu XRefWriterTable a obsahuje asociativní pole Map, které je indexo vané podle čísla objektu a ukazuje na položku tabulky (objekt typu XRefWriterEntry). Konstruktor XRefWriterTableO vyplní tabulku podle původního souboru (pokud byl za dán) z objektu typu ukazatel na XRef knihovny Poppler a změní prvek číslo nula na prázdný (příznak „f") s offsetem nula a generačním číslem 65535. Funkce třídy XRefWriter jsou: getNewTrailerDictO - vrátí slovník trailer, getXReJTableO - vrátí tabulku odkazů, setFreeO - označí z-tý prvek tabulky příznakem „f" (smaže objekt), pokud je hodnota parametru free rovna gFalse, tak prvek označí příznakem „n", fetchO - vrátí objekt s daným číslem (následuje odkazy), printO - předá na výstup tabulku křížových odkazů, slovník trailer a klíčové slovo „%%EOF". Ostatní funkce jsou odvozené z třídy XRefWriterTable. Funkce třídy XRefWriterTable jsou: getEntryO - vrátí prvek tabulky podle zadaného čísla nepřímého objektu, getOldXRefO - vrátí starou tabulku odkazů (pokud nebyl zadán PDF soubor k editaci, vrátí NULL), getRefO - vrátí odkaz na daný objekt, newObjectO - návratová hodnota je nově vytvořený objekt (přidá příslušný prvek do tabulky), replaceObjectO - aktualizuje nepřímý objekt, tj. vrátí: -
kopii objektu z původního PDF souboru (pokud byl zadán PDF soubor k modifi kaci a ještě neexistuje příslušný aktualizovaný objekt),
3. Pokud je návratovou hodnotou funkce PDF objekt (typ ukazatel na objekt typu ObjectWriter), pak se vrátí pouze jeho nejnovější verze (tj. nejvyšší číslo generace) nebo hodnota NULL pokud objekt s daným číslem neexistuje.
23
4. PROGRAMÁTORSKÁ DOKUMENTACE
-
aktualizovaný objekt nebo NULL při chybě.
•
•
restoreObjectO - smaže aktualizovaný objekt a obnoví původní (tj. objekt se v novém těle souboru neobjeví; funkce je přetížená a parametrem je buď číslo objektu nebo ukazatel na ObjectWriter), freeObjectO - vrátí gTrue, pokud byla položka úspěšně uvolněna (nastaví příznak „í" a číslo generace plus jedna), jinak gFalse (položka neexistuje nebo už volná je),
•
getSizeO - vrátí velikost tabulky (stejné jako položka „Size" ve slovníku trailer),
•
printObjectO - předá na výstup nepřímý objekt s daným číslem a uloží jeho offset,
•
printAUObjectsO - stejné jako printObjectO, ale pro všechny objekty,
•
printO - předá na výstup samotnou tabulku (je nutné volat funkci printAUObjectsO pro zjištění validních byte offsetů jednotlivých prvků), Funkce třídy XRefWriterEntry jsou:
•
replaceObjectO - alokuje paměť pro nový objekt (pokud neexistuje nebo nebyl aktuali zován),
•
rmObjectO - odstraní objekt z paměti (pokud existuje),
•
getGenO - vrátí číslo generace položky,
•
getOjfsetO - vrátí offset nepřímého objektu, na který položka ukazuje,
•
getObjectO - vrátí příslušný objekt (NULL, pokud nebyl vytvořen nebo aktualizován),
•
isFreeO - gTrue, pokud je příznak „f",
•
getTypeO - vrátí příznak položky,
•
getOlďTypeO - vrátí původní příznak položky (vhodné pokud byla položka původně volná, tak není třeba ji znovu uvolňovat; tj. na výstup se předají jen objekty a položky, které byly změněny/aktualizovány),
•
changedO - gTrue, pokud se položka liší od původní,
•
setTypeO - nastaví příznak,
•
setOlďTypeO - nastaví původní příznak,
•
printO - předá položku na výstup. 24
4. P R O G R A M Á T O R S K Á D O K U M E N T A C E
4.2.3 Modul ObjectWriter ObjecťWriterje třída pro správu objektů všech typů. Typy objektů (a příslušné typy datových proměnných) jsou: •
boolean (GBool),
•
číslo (int),
•
číslo v plovoucí desetinné čárce (double),
•
řetězec (ukazatel na char),
•
název (ukazatel na char),
•
null /neplatný/prázdný objekt (bez proměnné),
•
odkaz na nepřímý objekt (Ref - viz ukázka kódu 1)
a komplexní typy jsou: •
pole (ArrayWriter),
•
slovník (DictWriter),
•
proud (StreamWriter).
s t r u c t Ref { i n t num; / / int gen; / / };
číslo číslo
objektu generace
Ukázka kódu 1: struct Ref (z hlavičkového souboru „Object.h" knihovny Poppler) Funkce getTypeO vrátí typ podle identifikátoru (viz ukázka kódu 2). Konstruktor nastaví počáteční typ na objNull. Funkce s předponou mit slouží k inicializaci typu objektu a nastavení jeho hodnoty, get k získání příslušné proměnné a is k zjištění typu objektu. Zbytek názvu těchto funkcí se doplní podle identifikátorů (např. initArrayO inicializuje pole). Inicializační funkce komplex ních typů vrací ukazatel na příslušnou třídu (ArrayWriter, DictWriter nebo StreamWriter). Před každou další inicializací je nutné volat funkci gFreeO, která bezpečně uvolní veškerou alokovanou paměťa nastaví typ objektu na původní objNull. Funkce copyO zkopíruje vlastnosti objektu z původního PDF souboru (parametrem je ukazatel na Object - třída z knihovny Poppler), aby jej bylo možné posléze modifikovat. Podobně se chovají funkce addAUO u konkrétních typů objArray, objDict a objStream (viz dále). 25
4. PROGRAMÁTORSKÁ DOKUMENTACE
enum ObjType objBool , objlnt , objReal , objString , objName, objNull , objArray , objDict , objStream , objRef ,
{ // // // // // // // // // //
boolean číslo číslo v plovoucí řetězec název null pole slovník proud odkaz na nepřímý
II další identifikátory objCmd, objError , objEOF, objNone
(pro
desetinné
čárce
objekt knihovnu
PDFWriter
nepodstatné)
}; endobj Ukázka kódu 2: enum ObjType (z hlavičkového souboru „Object.h" knihovny Poppler) 4.2.4 Modul Array Writer ArrayWriter je třída pro PDF objekty typu pole. Nově vytvořené pole je prázdné a prvky do něj lze přidávat pomocí funkcí newElemO nebo newFirstElemO. První z jmenovaných vrátí nový prvek (typ ukazatel na ObjectWriterO) z konce a druhá ze začátku pole. Podobně je to s funkcemi pro odebírání prvků removehasti) a removeFirstO (bez návratových hodnot). Smazaní z-tého prvku provede delElemO (vrátí gFolse, pokud je parametr i mimo rozsah pole). Funkce gFreeO vymaže všechny prvky pole. Další funkce jsou: •
addAllO - (volaná z ObjectWriter::copy()) zkopíruje prvky objektu typu pole (třída Array knihovny Poppler) získaného z původního souboru,
•
getValO - vrátí i-tý prvek pole a getLengthO jeho délku,
•
printO - vytiskne pole.
4.2.5 Modul DictWriter Třída pro správu objektů typu slovník se nazývá DictWriter. K udržení jednotlivých prvků je použito asociativní pole s klíčem typu název (ukazatel na const char) a příslušnou hodnotou (ukazatel na ObjectWriter). Funkce: •
newEntryO - vytvoří položku slovníku se zadaným klíčem (typ ukazatel na const char) a vrátí její hodnotu (ukazatel na ObjectWriter), 26
4. P R O G R A M Á T O R S K Á D O K U M E N T A C E
•
delEntryO - oproti předchozí smaže položku s daným klíčem ze slovníku,
•
addAUO - podobně jako u třídy ArrayWriter zkopíruje všechny položky ze slovníku původního souboru PDF,
•
getValO - vrátí položku slovníku podle klíče zadaného jako parametr,
•
printO - vytiskne slovník.
4.2.6 Modul
StreamWriter
Třída StreamWriter slouží ke správě objektů typu proud. Konstruktor vytvoří prázdný seznam proudů typů ukazatel na Stream (abstraktní třída; definice v knihovně Poppler). Posloupnost všech bytů každého proudu v seznamu tvoří výsledný proud, který reprezentuje třída StreamWriter a který se vytiskne funkcí print(). Přidání proudu do seznamu se provede funkcí addStreamO (parametr je ukazatel na objekt typu Stream). Takto lze jednoduše zkopírovat nebo zřetězit byty proudů i z původního souboru. Slovník proudu lze získat jako návratovou hodnotu (ukazatel na DictWriter) funkce getDictO. Funkce: •
getLengthO - vrátí celkovou velikost proudu v bytech,
•
getStreamO - vrátí ukazatel na z-tý proud v seznamu nebo NULL při nenalezení proudu,
•
clearO - vymaže všechny prvky v seznamu,
•
newDictEntryO, delDictEntryO a getDictValO - slouží pro přímý přístup k metodám slovníku,
•
newRawStreamO resp. newFileStreamO - jsou určeny k přidání speciálního proudu typu RawStreamWriter resp. FileStreamWriter do seznamu.
Třída RawStreamWriter může být použita hlavně pro proudy, kde se vyskytují operátory pro vykreslování. Funkce addCStringO zkopíruje zadaný řetězec na konec proudu a vrátí přidanou část jako ukazatel na char. Poznámka: Ostatní funkce jsou zděděné z abstraktní třídy Stream (pohyb v proudu a zjiš tění jeho velikosti), která je popsána v hlavičkovém souboru „Stream.h" knihovny Poppler. K uložení a komprimaci bytů souboru v proudu slouží třída FileStreamWriter. Funkce openO (viz ukázka kódu 3) uloží soubor filename v proudu od pozice souboru dané para metrem startA a omezené, pokud je limitedA gTrue, na délce dané hodnotou limitedA. Byty v proudu budou zkomprimovány pokud má parametr deflate hodnotu gTrue a navíc bude vytvořen dočasný soubor standardní funkcí mkstempO, do kterého se zkomprimovaná data uloží. Pokud byl soubor do proudu úspěšně přidán, funkce vrátí gTrue. Před dalším voláním openO musí být soubor řádně uzavřen a dočasný soubor smazán funkcí close(). 27
4. P R O G R A M Á T O R S K Á D O K U M E N T A C E
GBool open( const GBool Guint GBool Guint );
char ^ f i l e n a m e , deflate = gTrue, s t a r t A = 0, limitedA = gFalse , lengthA = 0
Ukázka kódu 3: Prototyp funkce open(). 4.2.7 Modul FontWriter Třída FontWriter umožňuje do PDF souboru vložit soubor písma a nastavit objekty písma (slovníky Font a FontDescriptor). Zatím podporuje kódování ISO 8859-2 a font TrueType nebo Typel. Vytvoření objektů písma v PDF se provede funkcí addFontO (s parametrem typu PDFWriter). Návratová hodnota je ukazatel na slovník Font v tomto dokumentu (NULL pokud došlo k chybě). Před vytvořením objektů je třeba volat členskou funkci fromFileO, která otevře soubor písma podle zadané cesty k souboru a vrátí gTrue, pokud byl font úspěšně otevřen (případnou chybu vytiskne na standardní chybový výstup). Funkce: •
gfreeO - obnoví strukturu písma do počátečního stavu (stav po volání konstruktem),
•
getGlyphNameO - vrátí název znaku podle zadaného kódu Unicode (typ unsigned short),
•
getUnicodeO - převede znak z aktuální znakové sady (parametr typu unsigned short) do Unicode (návratová hodnota typu unsigned short),
•
getTextWidthO resp. getTextHeightO - spočítá šířku resp. výšku zadaného textu, který by byl vypsán do PDF dokumentu tímto písmem s velikostí tisíc,
•
getTypeO - vrátí identifikátor druhu fontu (TRUETYPE, TYPE1 nebo CFF).
4.2.8 Modul
WatermarkWriter
Třída pro vkládání vodoznaku do PDF dokumentu se nazývá WatermarkWriter. Nepovinné parametry konstruktoru jsou názvy objektu formuláře a slovníku graphical state parameter dictionary. Funkce setTextO nastaví text vodoznaku a jeho šířku a výšku při velikosti písma tisíc. Pro vypsání tohoto textu se volá drawWatermarkO (viz ukázka kódu 4). Do PDF souboru (parametr pdf) vloží objekty vodoznaku a změněné stránky. Parametr obj-font je slovník písma v PDF souboru, který se použije k vykreslení textu na všech stránkách. Ostatní parametry jsou: •
fillcl
- barva výplně písma,
•
stroked - barva obrysu písma,
•
strokew - šířka obrysu, 28
4. P R O G R A M Á T O R S K Á D O K U M E N T A C E
•
blendjnode - název operace pro míchání barev (viz 2.5.7),
•
alpha - koeficient průhlednosti,
•
angle - úhel natočení vodoznaku,
•
ontop - pokud je gTrue, vodoznak se vykreslí jako poslední objekt na stránce (jinak se vykreslí první).
GBool drawWatermark ( PDFWriter *pdf, ObjectWriter * o b j _ f o n t , c o n s t char * f o n t n a m e , c o n s t char * f i 11 c 1 , c o n s t char * s t r o k e c l , unsigned i n t s t r o k e w , c o n s t char * b l e n d _ m o d e , float alpha , float angle , GBool ontop = gTrue ) const; Ukázka kódu 4: Prototyp funkce drawWatermarkO.
4.3
Nástroj pro vkládání vodoznaku do PDF souboru
V nástroji pro vkládání vodoznaku (zdrojové kódy se nachází v adresáři „utils") je implemen továno základní uživatelské rozhraní. Změny parametrů se provádí přepínači na příkazové řádce. Vstupem je název PDF souboru k modifikaci a výstupem je soubor s vloženým vodo znakem. 4.3.1 Procedura main() Prvním krokem v proceduře main() je zpracování přepínačů. K tomu používá převážně funkci getoptO ze standardního hlavičkového souboru „unistd.h". Dále zkontroluje přepínače a načte text ze standardního vstupu (pokud nebyl zadán na příkazové řádce). Jestliže byly některé parametry zadány nekorektně, vytiskne se na standardní výstup ná pověda programu (metoda print JielpO), jinak se vytvoří nový objekt typu PDFWriter a předá se mu název vstupního PDF souboru. Při chybném otevření souboru je program ukon čen s chybovým kódem převzatým z funkce PDFWriter::getWriterError(). Proběhne kontrola oprávnění k modifikaci PDF dokumentu. Je-li vstupní soubor načten bez chyby, otevře se výstupní soubor pro zápis. Pokud bylo otevření úspěšné, vytvoří se objekt typu FonťWriter, který načte font ze souboru zadaného pomocí přepínače (funkce FonťWriter::fromFile()) a přidá font do vstupního pdf souboru (funkce FontWriter::addFont()). Dále je vytvořen objekt typu WatermarkWriter. Metodou WatermarkWriter::setText() je na staven text, jeho šířka a výška. Objekty vodoznaku a modifikované stránky jsou vloženy do 29
4. P R O G R A M Á T O R S K Á D O K U M E N T A C E
struktury PDFWriter funkcí WatermarkWriter::drawWatermark(), která používá většinu para metrů z příkazové řádky (nebo jejich implicitní hodnoty). Na výstup programu se vytiskne vstupní PDF soubor s modifikovanou hlavičkou (metoda saveOldPDFO) a nový přírůstek obsahující přidané a modifikované objekty. Na závěr jsou zavřeny všechny soubory a zrušena veškerá alokovaná paměťprogramu. 4
4. K odstranění závažných chyb programu (ne-dealokovaná paměť apod.) byla použita aplikace valgrind [11].
30
Kapitola 5
Uživatelská dokumentace Tato kapitola je vhodná zejména pro uživatele nástroje pro vkládání digitálního vodoznaku do PDF dokumentu, kteří nemusí podrobněji vědět, jak program soubory zpracovává. 5.1
Zkompilování a instalace
Zkompilování a instalace nástroje i s knihovnou PDFWriter se provede pomocí následující série příkazů spuštěné z kořenového adresáře projektu. $ ./configure $ make $ sudo make install
Pro úspěšné vykonání příkazů je navíc nutné mít nainstalovány knihovny FreeType a Poppler (ve verzi 0.6.1 a vyšší). 5.2
Používání programu
Povinné přepínače programu jsou pouze soubor písma (přepínač ,,-f"; ve formátu TrueType nebo Typel), PDF k modifikaci (bez přepínače) a text vodoznaku („-t"), který může být alternativně zadán na standardní vstup programu. Implicitně se vytiskne PDF s vodoznakem na standardní výstup, ale je možné zadat výstupní soubor přepínačem ,,-o". Jak už zde bylo uvedeno, program podporuje pouze kódování ISO 8859-2, proto je často nutné prvně předat text vodoznaku na standardní vstup aplikace iconv s parametrem ,,-t iso8859-2". Tím se převede původní znaková sada do ISO 8859-2. Celá roura může vypadat jako na příkladu 8 (znak dolaru uvádí příkaz shellu a obrácené lomítko pokračování na dalším řádku). $ iconv - t iso8859-2
| pdfwm d o k u m e n t . p d f - f f o n t . t t f \ -o dokument_s_vodoznakem.pdf
Příklad 8: Zkonvertování textu do kódování ISO 8859-2 a předání na standardní vstup programu. Všechny přepínače jsou uvedeny v anglické nápovědě programu, kterou je možné vyvolat přepínačem ,,-h" nebo při chybném použití přepínačů. 5.2.1 Příklady Implicitní hodnoty parametrů programu jsou vhodné pro vkládání vodoznaku na doku menty s tmavým textem na světlém pozadí - to znamená, že přidaný vodoznak by měl být 31
5. UŽIVATELSKÁ DOKUMENTACE
$ pdfwm pdfwm, version 0.1 usage: pdfwm -f FONT [OPTIONS] FILE Embeds watermark in a PDF document. This watermark is scaled text (see option ' - ť ) written on each page in given truetype font. -a -b
-c -C -f -h -o
-r -t -u -w
Watermark transparency (from 0.0 to 1.0). Default is 1.000000. Blending mode (values are: Normal, Multiply, Screen, Overlay, Darken, Lighten, ColorDodge, ColorBurn, HardLight, SoftLight, Difference, Exclusion). Default is Multiply, Watermark text fill color in RGB format. (e.g. "1 1 0.5" for light yellow). Default is 1.0 1.0 0.9. Set text stroke color in RGB format (see '-c' option). Default is 0.9 0.9 0.9. Watermark font (truetype font file(ttf)). Display this help message, Output file or '-' for standard output (only new part of pdf file will be printed on standard output). Without using this option the standard output is used, Rotate Watermark text (in degrees). Default is 0. Watermark text. Without using this option text is taken from standard input, Put watermark under all objects on each page. Default is on top of each page, Set stroke width. Default is 20.
Příklad 9: Výpis nápovědy.
32
5. UŽIVATELSKÁ DOKUMENTACE
dobře rozpoznatelný a čitelnost textu stránky zachována. Vodoznak vytvořený příkazem z příkladu 10 je na obrázku 3. Zde je text vodoznaku navíc pootočen o 20 stupňů (,,-r 20").
$ pdfwm p r i k l a d . p d f - f / u s r / s h a r e / f o n t s / c o r e f o n t s / t i m e s b d . t t f - o p r i k l a d _ s _ v o d o z n a k e m . p d f - t VODOZNAK - r 2 0
\
Příklad 10: Vstupní argumenty programu.
Watermark A watermark is a recognizable image or pattern in paper that appears lighter when viewed by transmitted light (or darker when viewed by reflected light, atop a dark background). There are two main types of watermark, the Dandy Roll process, and the more complex Cylinder Mould process. A watermark is very useful in the examination of paper because it can be used for dating, identifying sizes, mill trademarks and locations, and the quality of a paper. Watermarks vary greatly in their visibility; while some are obvious on casual inspection, others require some study to pick out. Various aids have been developed, such as watermark fluid that wets the paper without damaging it. Encoding an identifying code into digitized music, video, picture, or other file is known as a digital watermark. The Dandy Roll Process A Dandy Roll watermark is made by impressing a watercoated metal stamp or dandy roll onto the paper during manufacturing. These watermarks were first introduced in Bologna, Italy in 1282; they have been used by papermakers to identify their product, and also on postage stamps, currency, and other government documents to discourage counterfeiting. The dandy roll is a light roller covered by material similar to window screen that is embossed with a pattern. Faint lines are made by laid wires that run parallel to the axis of the dandy roll, and the bold lines are made by chain wires that run around the circumference to secure the laid wires to the roll from the outside. Because the chain wires are located on
Obrázek 3: Ukázka výstupního PDF dokumentu. Naopak pokud jsou stránky tmavé a popředí světlé, je vhodné pozměnit hodnoty parame trů jako například průhlednost (přepínač „-a"), způsob míchání barev („-b") nebo případně barvu výplně („-c") a obrysu („-C"). Při použití příkazu z příkladu 11 lze dosáhnout poměrně uspokojivého výsledku (viz. obrázek 4) za použití metody míchání barev „Screen".
$ pdfwm priklad_tmavy.pdf \ -f /usr/share/fonts/corefonts/timesbd.ttf \ -o wm_priklad_tmavy.pdf -t VODOZNAK -b Screen \ -c "0.4 0.4 0.4" -C "0.5 0.5 0.5" -r -30"
Příklad 11: Argumenty programu pro vytvoření vodoznaku na tmavé stránce. Poslední příkaz (viz příklad 12) odstraní obrys vodoznaku („-w 0") a kvůli zachování či telnosti je použita padesáti procentní průhlednost („-a 0.5") místo implicitního míchání barev „Multiply" („-b Normal" zapne klasickou průhlednost). Výsledek je vidět na obrázku 5). 33
5. UŽIVATELSKÁ DOKUMENTACE
Obrázek 4: Ukázka výstupního PDF dokumentu.
$ pdfwm priklad_tmavy.pdf -b Normal \ -f /usr/share/fonts/corefonts/georgia.ttf \ -o wm_priklad_tmavy2.pdf -t VODOZNAK \ -w 0 -c "1 1 1" -a 0.5 -r -60
Příklad 12: Alternativní hodnoty parametrů programu pro vytvoření vodoznaku na tmavé stránce.
34
5. UŽIVATELSKÁ DOKUMENTACE
Obrázek 5: Ukázka výstupního PDF dokumentu. 5.2.2 Dávkové zpracování více souborů Pro zpracování více souborů na příkazové řádce je možné vytvořit jednoduchý skript, aby bylo zřejmé, kam se mají jednotlivé soubory vypsat. Ukázka takového skriptu je na pří kladu 13. Hodnoty některých přepínačů jsou definované na začátku jako proměnné, tak lze jed noduše změnit jednotlivé parametry vodoznaku pro všechny vstupní PDF dokumenty. Ná sledující řádek obsahuje příkaz trap, který umožní přerušit provádění cyklu pro zpracování jednotlivých souborů. Cyklus se pokusí postupně přidat vodoznak do každého PDF doku mentu zadaného na příkazové řádce skriptu a uložit jej s předponou „wm_". Uživatel je informován o průběhu textem předávaným na standardní výstup. Samozřejmě by bylo také možné jednoduchou modifikací přimět proceduru main(), aby zpracovala více vstupních souborů z příkazové řádky a ukládala každý z nich - podobně jako předchozí skript - do souboru s konkrétním názvem (např. k názvu vstupního souboru je přidána konkrétní přípona nebo předpona) nebo vytvářela adresář pro uložení výstupních souborů se stejným názvem jako na vstupu.
35
5. UŽIVATELSKÁ DOKUMENTACE
#.' /bin/bash TEXT="VODOZNAK" FONT="/usr/share/fonts/corefonts/timesbd.ttf" ALPHA=1 BLEND="Multiply" ANGLE=-30 trap 'echo -e "\nINTERRUPTED!"; exit ľ
INT TERM
for FILE in "$@" do echo "Adding watermark to $FILE ..." echo $TEXT | iconv -t iso8859-2 | pdfwm \ -a $ALPHA -b $BLEND -r $ANGLE \ -f $FONT -o "wm_$FILE" "$FILE" if [ $? -ne 0 ] then echo "... FAILED!" else echo "... SUCCESS!" fi done echo -e "\nALL DONE!"
Příklad 13: Shell skript pro dávkové vkládání vodoznaku do PDF dokumentu.
36
Kapitola 6
Závěr Popis formátu PDF v této práci je velice stručný Jsou vysvětleny pouze základní pojmy a elementy PDF a pokročilejší prvky formátu, které se uplatní při vkládání vodoznaku. Digitální vodoznak, který nástroj vkládá do PDF souboru, je uživatelem zvolený text vypsaný zvoleným písmem na každou stránku vstupního dokumentu. Jednoduchý nástroj (funkce mainO) závisí z velké části na vytvořené knihovně PDFWriter. Knihovna má imple mentovány třídy znázorňující jednotlivé typy objektů PDF a její hierarchie a struktura kódu jsou podobné knihovně Poppler. Velkou nevýhodou je, že hlavní třída pro správu PDF dokumentu PDFWriter postrádá možnost načítat a ukládat dokumenty v zašifrované podobě a s digitálním podpisem. Uživatel by měl mít možnost vybrat stránky, na které chce vodoznak přidat, a vkládat kromě textu i jiné grafické prvky (např. obrázky). Tato rozšíření z velké části souvisí s třídou WatermarkWriter, kterou je třeba „rozložit" na několik menších činností/funkcí (např. modi fikace souřadného systému, vykreslení textu nebo obrázku) místo toho, aby prováděla pouze jednu komplexní činnost (vložení vodoznaku). Přístup k hierarchii stran dokumentu by mohla zajišťovat třída CatalogWriter, která by spravovala stránky původního dokumentu (podobně jako třída Catalog knihovny Poppler) i s nově přidanými stránkami. Třída StreamWriter je poměrně „neohrabaná". Tady by se mohla všechna data přidaná do proudu vypisovat do dočasného souboru, protože přístup k nim není příliš frekventovaný. Tím by se ušetřilo něco málo z operační paměti. Také chybí možnost zakódovat data proudu s použitím různých kombinací filtrů. Například položka proudu „Filter" může mít následující hodnotu. [ ASCIIHexDecode LZWDecode ] Zde se pro čtení bytů proudu nejdříve musí aplikovat dekódovací filtr „ASCIIHexDecode" a následně „LZWDecode". V opačném případě - k zakódování proudu - by bylo nutné použít příslušné kodéry v obráceném pořadí. Třídě FontWriter schází funkce k načtení fontu, který už je v PDF dokumentu obsažen. A hlavně chybí jiná kódování textu než ISO 8859-2. Také by mohla být vyřešena přenositelnost knihovny PDFWriter na jiné operační systémy (použité knihovny Poppler a FreeType jsou přenositelné). Kód knihovny je konstruován s ohledem na minimalizaci časové složitosti a paměťové náročnosti. Operační paměť je většinou alokována podle potřeby. Tím, že vodoznak vy kresluje pouze jeden objekt typu formulář, nenaroste velikost výstupního souboru o mnoho (největší podíl na velikosti má soubor písma vložený do PDF, ale ten je zkomprimován). Zdrojové kódy jsou opatřeny příslušnými komentáři (v anglickém jazyce) pro osvětlení jednotlivých částí. Komentáře obsahující direktivu „TODO:" popisují úkony, které je vhodné provést k rozšíření o vlastnosti popsané výše. 37
6. ZÁVĚR Knihovna umožňuje provádět s PDF dokumentem i jiné úkony než pouze vkládat vo doznak, ale využívá pouze malou část z vlastností, které PDF nabízí, takže je stále možné jí rozšiřovat.
38
Literatura International Organization for Standardization. Iso/dis 32000. http: //www.iso.org/iso/iso_catalogue/catalogue_tc/catalogue_detail. htm?csnumber=4 58 7 3, 2007. [online; navštíveno 31.12. 2007]. Kolektiv autorů. PDF Reference, sixth edition: Adobe Portable Document Format version 1.7. Adobe Systems Incorporated, 2006. Adobe Systems Incorporated. Adobe PDF Technology Center, PDF Reference, h t t p : //www. adobe . c o m / d e v n e t / p d f / p d f _ r e f e r e n c e .html,2007. [online;navštíveno 19.12.2007]. Kolektiv autorů. PDF Reference, sixth edition: Adobe Portable Document Format version 1.7, chapter 3.8.3, Dates. Adobe Systems Incorporated, 2006. The FreeType Development Team David Turner. Freetype Glyph Conventions, version 2.1. http : //freetype . sourcef orge . net/f reetype2/docs/glyphs/index . h t m l , 2000. [online; navštíveno 19.12.2007]. Kolektiv autorů. PDF Reference, sixth edition: Adobe Portable Document Format version 1.7, chapter 3.5, Encryption. Adobe Systems Incorporated, 2006. Kolektiv autorů. PDF Reference, sixth edition: Adobe Portable Document Format version 1.7, chapter 8.7, Digital Signatures. Adobe Systems Incorporated, 2006. Wikipedia. Watermark, h t t p : / / e n . w i k i p e d i a . o r g / w i k i / W a t e r m a r k , 2 0 0 6 . [On line; navštíveno 10.11.2006]. Kristián Hogsberg. Poppier, h t t p : / / p o p p l e r . f r e e d e s k t o p . o r g , 2006. [online; navštíveno 25.12.2007]. David Turner. The Freetype Project website, h t t p : / / w w w . f r e e t y p e . o r g , 2006. [online; navštíveno 25.12.2007]. Valgrind Developers. Valgrind - hlavní strana, h t t p : / / v a l g r i n d . org,2007. [online; navštíveno 31.12.2007].
39
Příloha A K práci přiložené CD obsahuje: •
textovou část práce ve formátu LTpX,
•
přeložený text ve formátech DVI, PS a PDF,
•
zdrojové kódy knihovny PDFWriter a nástroje pro vkládání vodoznaku (úspešné zkom pilováno a spuštěno na strojích s operačním systémem Linux a IRIX) a
•
shell skript pro dávkové vkládání vodoznaku do PDF dokumentů.
40