MASARYKOVA UNIVERZITA FAKULTA INFORMATIKY
Implementace knihovny OpenJPEG do image serveru IIPImage BAKALÁŘSKÁ PRÁCE
Adam Brenkus
Brno, květen 2014
PROHLÁŠENÍ Prohlašuji, že tato práce je mým původním autorským dílem, které jsem vypracoval 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. V Brně dne 16. května 2014 vlastnoruční podpis autora
Jméno a příjmení autora:
Adam Brenkus
N á z e v b a k a l á ř s k é p rá c e :
Implementace knihovny OpenJPEG do image serveru IIPImage
N á z e v p rá c e v a n g l i č t i n ě :
Implementing OpenJPEG into IIPImage server
V e d o u c í d i p l o m ov é p r á c e :
Ing. Petr Žabička
Rok obhajoby:
2014
SHRNUTÍ Cílem práce je poskytnout možnost distribuovat server IIPImage s nativní podporou formátu JPEG 2000 pomocí svobodné knihovny OpenJPEG. V textu práce je popsána implementace zmíněné knihovny do serveru IIPImage. V práci lze také nalézt popis struktury serveru IIPImage a popis komunikace ovladačů externích knihoven s dalšími komponenty serveru IIPImage. V textu jsou uvedeny výsledky srovnávacích výkonnostních testů ovladačů obou knihoven.
KLÍČOVÁ SLOVA IIPImage, OpenJPEG, Kakadu, JPEG 2000
KEYWORDS IIPImage, OpenJPEG, Kakadu, JPEG 2000
OBSAH 1 ÚVOD...................................................................................................................................................................5 1.1 ÚVOD...............................................................................................................................................................5 1.2 CÍL PRÁCE........................................................................................................................................................6 2 SROVNÁNÍ LICENCÍ KNIHOVEN OPENJPEG A KAKADU...................................................................7 2.1 LICENCE KNIHOVNY KAKADU.........................................................................................................................7 2.2 LICENCE KNIHOVNY OPENJPEG......................................................................................................................7 3 STRUKTURA SERVERU IIPIMAGE.............................................................................................................8 3.1 SEZNÁMENÍ S IIPIMAGE ..................................................................................................................................8 3.2 KOMPONENTY V IIPIMAGE .............................................................................................................................8 3.3 EXTERNÍ KNIHOVNY A JEJICH OVLADAČE .......................................................................................................9 4 IMPLEMENTACE OVLADAČE KNIHOVNY OPENJPEG......................................................................10 4.1 SEZNÁMENÍ S KNIHOVNOU OPENJPEG .........................................................................................................10 4.2 OBRÁZKOVÁ DATA V KNIHOVNĚ OPENJPEG................................................................................................10 4.3 INSPIRACE A ZDROJE .....................................................................................................................................10 4.3.1 Ovladač knihovny Kakadu v IIPImage..................................................................................................10 4.3.2 Ovladač knihovny OpenJPEG v knihovně GDAL..................................................................................11 4.3.3 Zdrojový kód programu opj_decompress..............................................................................................11 4.4 STRUKTURA OVLADAČE ................................................................................................................................11 4.4.1 Metody openImage() a closeImage().....................................................................................................11 4.4.2 Metoda loadImageInfo()........................................................................................................................11 4.4.3 Metody getTile() a getRegion()..............................................................................................................11 4.4.4 Metoda process()...................................................................................................................................12 4.5 VIRTUÁLNÍ ÚROVNĚ ROZLIŠENÍ A DOWNSAMPLING .....................................................................................12 4.6 INTERAKCE OVLADAČE KNIHOVNY OPENJPEG SE SERVEREM IIPIMAGE ....................................................13 5 MĚŘENÍ VÝKONU OVLADAČŮ OPENJPEG A KAKADU.....................................................................14 5.1 PŘEDSTAVA ...................................................................................................................................................14 5.2 METODOLOGIE ..............................................................................................................................................14 5.3 VÝSLEDKY MĚŘENÍ .......................................................................................................................................15 5.3.1 První obrázek.........................................................................................................................................15 5.3.2 Druhý obrázek........................................................................................................................................16 6 ZÁVĚR...............................................................................................................................................................18 6.1 SHRNUTÍ VÝSLEDKŮ MĚŘENÍ ........................................................................................................................18 6.2 ZÁVĚR ...........................................................................................................................................................18 6.3 CO BY ŠLO V BUDOUCNU ZLEPŠIT .................................................................................................................18 SEZNAM POUŽITÝCH ZDROJŮ.....................................................................................................................20 SEZNAM ELEKTRONICKÝCH PŘÍLOH.......................................................................................................21 SEZNAM TABULEK...........................................................................................................................................22 SEZNAM OBRÁZKŮ...........................................................................................................................................23
1 ÚVOD 1.1
Úvod
Rychlé zobrazení obrázků v ultra vysokém rozlišení z internetového úložiště je velmi vyžadovaná funkce. Mezi takové obrázky patří například mapy nebo záběry pořízené vesmírnými teleskopy. Servery, které takové obrázky zprostředkovávají, je klientům předávají ve formě dlaždic (tile-based streaming). Klient si od serveru pomocí dotazu HTTP1 vyžádá několik dlaždic z původního obrázku, pomocí kterých dokáže sestavit obrázek nebo jeho část. Pro uživatele většinou zůstává tento proces zcela transparentní. Klientské aplikace se postarají o komunikaci se serverem a zasílání požadavků pomocí protokolu HTTP. IIPImage je server, který poskytuje rychlý a snadný přístup k těmto obrázkům. Využívá se v knihovnách a jiných institucích u nás i v zahraničí, včetně Národní knihovny a Moravské zemské knihovny, která v minulosti zajistila implementaci podpory pro JPEG 2000 do IIPImage. V této době ještě nebyla knihovna OpenJPEG pro tento účel použitelná. IIPImage je distribuován pod licencí GNU GPL2. JPEG 2000 je poměrně mladý standard pro kompresi obrázků. Měl by se stát nástupcem staršího formátu JPEG3, který obrázky komprimuje diskrétní kosinovou transformací. Novější standard komprimuje vlnkovou transformací. Také přidává možnost bezeztrátové komprese [1]. Pro servery, které poskytují obrázky, je formát JPEG 2000 zajímavý, protože umožňuje uložení několika vrstev obrázku v různých úrovních rozlišení. Tento formát se od roku 2011 používá i jako primární formát pro dlouhodobou archivaci digitalizovaných dokumentů v knihovnách. Obrázky uložené podle standardu JPEG 2000 server IIPImage nyní dekóduje pomocí proprietální knihovny Kakadu. Kakadu je kodek4 standardu JPEG 2000. Zdrojové kódy aplikace IIPImage s touto knihovnou nelze šířit pod licencí GNU GPL. Je možné poskytnout pouze zkompilovanou aplikaci v binární formě. Bylo by vhodné nahradit tuto knihovnu, protože omezuje možnosti aplikace serveru IIPImage. S podporou formátu JPEG 2000 jej lze využít pouze pro nekomerční účely, a pro uživatele je nemožné sestavit IIPImage s touto knihovnou ze zdrojových kódů. 1
HTTP (HyperText Transfer Protocol) je jednoduchý aplikační protokol, který lze využít například k přenosu webových dokumentů. Pracuje na principu dotaz-odpověď [2].
2
GNU (GNU's Not Unix!) General Public License (Obecně veřejná licence) je licence pro software a jiná díla. Koncovým uživatelům zaručuje svobodu používat, sdílet a upravovat tato díla.
3
JPEG (Joint Photographic Experts Group) je všeobecně rozšířený formát pro ztrátovou kompresi obrázků.
4
Kodek je zařízení nebo program schopný kódovat nebo dekódovat signál nebo datový proud.
5
Nabízí se řešení pomocí knihovny OpenJPEG. Ta se už využívá v jiných aplikacích, které pracují s formátem JPEG 2000. Knihovna OpenJPEG je kodek standardu JPEG 2000. Vznikla, aby podpořila tento standard a usnadnila jeho použití. Je šířena pod licencí BSD1. Každý tedy může svobodně modifikovat a používat tuto knihovnu [3].
1.2
Cíl práce
Podnětem pro tuto bakalářskou práci je ověření možnosti nahrazení knihovny Kakadu svobodnou knihovnou OpenJPEG. Hlavním cílem práce je implementovat knihovnu OpenJPEG do IIPImage. Při implementaci mi jako vzor posloužil zdrojový kód ovladače Kakadu v IIPImage a ovladače OpenJPEG v knihovně GDAL2. Ponechal jsem strukturu ovladače Kakadu a nahradil volání funkcí knihovny Kakadu funkcemi knihovny OpenJPEG. Dále jsem upravil a doladil části kódu, které nebyly kompatibilní s novou knihovnou. Aby si ovladač rozumněl s IIPImage, musel jsem také upravit některé komponenty, které se v IIPImage starají o komunikaci s ovladači a přidat přepínač, který umožňuje zvolit knihovnu, pokud jsou obě k dispozici. Podporu pro tento ovladač jsem také přidal do instalačních souborů projektu. Bakalářská práce umožní distribuovat IIPImage s nativní podporou formátu JPEG 2000. Tedy poskytne snadnější bezplatnou práci s formátem JPEG 2000 v IIPImage. Druhá část této práce je provedení srovnávacích výkonnostních testů. Testoval jsem rychlost dotazů na dlaždice v obrázku a porovnával výkon nového OpenJPEG ovladače s Kakadu ovladačem.
1
BSD (Berkeley Software Distribution) licence říká, že redistribuce a použití zdrojových i binárních forem díla, v původním i upravovaném tvaru, jsou povoleny, pokud jsou distribuovány s informacemi o autorských právech a textem této licence [4].
2
GDAL (Geospatial Data Abstraction Library) je knihovna, která aplikacím poskytuje jediný abstraktní datový model pro všechny formáty, které podporuje [5].
6
2 SROVNÁNÍ LICENCÍ KNIHOVEN OPENJPEG A KAKADU 2.1
Licence knihovny Kakadu
Projekt IIPImage je šířen s veřejnosti otevřeným zdrojovým kódem. Knihovna Kakadu, která se v IIPImage stará o dekódování formátu JPEG 2000, může být použita pouze k nekomerčním účelům. Stojí za tím její licence. Říká, že vlastník licence má právo šířit software Kakadu, pokud toto šíření nenese žádný přímý nebo nepřímý finanční zisk pro vlastníka licence nebo třetí stranu, která dále používá nebo distribuuje tento software [6]. Binární formu IIPImage s knihovnou Kakadu lze tedy použít pouze pro nekomerční účely. Omezení, které sebou nese tato licence jsou také důvodem, proč autor projektu IIPImage nemá zakoupenou licenci Kakadu a kompilaci IIPImage s podporou formátu JPEG 2000 musí zajišťovat třetí strana, například Moravská zemská knihovna. Zdrojový kód IIPImage je distribuován pod licencí GNU GPL. Licenční omezení knihovny Kakadu platí, pouze pokud je IIPImage sestaven s touto knihovnou. Pokud by uživatel chtěl provést nějaké úpravy a IIPImage s podporou formátu JPEG 2000 sestavit sám z veřejných zdrojových kódů, musel by koupit knihovnu Kakadu. Pokud mu ale stačí program v binární formě, jsou k dispozici binární balíky [7].
2.2
Licence knihovny OpenJPEG
Knihovna OpenJPEG má otevřený zdrojový kód a je šířena pod BSD licencí. Tato knihovna se již úspěšně využívá v jiných projektech, které pracují s formátem JPEG 2000. Jedním z nich je například knihovna GDAL. OpenJPEG je distribuován pod licencí BSD. Licence BSD říká, že šíření a používání projektu v jeho binární formě nebo jeho zdojového kódu je povoleno. Jediné omezení je, že distribuce projektu využívajícího tuto knihovnu musí obsahovat pojednání o autorských právech a text této licence [8]. Kdyby IIPImage umožňoval práci s formátem JPEG 2000 pomocí knihovny OpenJPEG, nebylo by nutné šířit jej v binární formě. Běžný uživatel si ale s binární formou vystačí. Implementace knihovny OpenJPEG do serveru IIPImage by také mohla zatlačit na optimalizaci a zrychlení této knihovny.
7
3 STRUKTURA SERVERU IIPIMAGE 3.1
Seznámení s IIPImage
Server IIPImage je navržen tak, aby mohl být vestavěn do webových serverů jako služba FCGI1. Dokáže spolupracovat se servery Apache, IIS, Lighttpd, Nginx, Myserver a pravděpodobně mnoha dalšími. S klientem komunikuje pomocí protokolů IIP (Internet Imaging Protocol), Zoomify, DeepZoom nebo IIIF (International Image Interoperability Framework). IIP byl původní protokol. Ty ostatní byly do IIPImage implementovány díky lidem kolem Moravské zemské knihovny. IIP je jednoduchý dotaz-odpověď protokol, který umožňuje přístup k jednotlivým dlaždicím v různých úrovních rozlišení. Umí také pracovat s metadaty2 obrázku. IIPImage pracuje s formáty, které umožňují uložit obrázek ve více rozlišeních. Těmi jsou TIFF3 a JPEG 2000. Formát TIFF je podporován nativně, ale pro podporu formátu JPEG 2000 musí IIPImage využívat externí knihovny. K dlaždicím nebo oblastem z těchto obrázků zprostředkovává přístup pomocí URL4. Ke snadnému prohlížení obrázků poskytnutých serverem je také potřeba některá z klientských aplikací, například OpenLayers. Tyto aplikace jsou vestavěny do webových stránek a komunikují s IIPImage pomocí jednoho z výše uvedených protokolů [9]. Zdrojový kód serveru IIPImage je napsán v programovacím jazyce C++ 5. IIPImage lze provozovat na většině operačních systémů z rodiny UNIX, Windows i Mac OS X.
3.2
Komponenty v IIPImage
IIPImage se skládá z několika druhů komponent. Jsou tu komponenty, které se starají o vyřizování požadavků od klienta a komponenty, které slouží jako jádro aplikace. Jsou tu 1
FCGI (FastCGI) je variace CGI (Common Gateway Interface). Je to protokol, který slouží ke svázání web serverů s interaktivními programy.
2
Metadata jsou data o datech. Například informace o tom, kdy a kde byla data pořízena.
3
TIFF (Tag Image File Format) je formát pro ukládání počítačové grafiky. Umožňuje například uložení vícestránkových souborů nebo obrázků, které obsahují více úrovní rozlišení.
4
URL (Uniform Resource Locator) je specifický textový řetězec, který odkazuje na nějaký zdroj. Nejčastěji se používá s protokolem HTTP.
5
C++ je imperativní objektový programovací jazyk. Obsahuje nízkoúrovňové i vysokoúrovňové prvky. Vychází z jazyka C, ke kterému přidává nejen objektově orientovaný přístup.
8
ovladače a ostatní komponenty, které obstarávají například cache1 nebo vodoznaky. Aby se požadavek z internetového prohlížeče klienta dostal přes IIPImage až k OpenJPEG knihovně a zpátky, musí překonat několik vrstev těchto komponent. Dotaz od klienta jako první zpracovává komponenta main, ve které běží hlavní fcgi cyklus. Tento cyklus odchytí a zpracuje všechny dotazy. Pro každý dotaz založí nový datový objekt session. Potom vybere komponentu, která bude dále zpracovávat tento dotaz a předá jí objekt session. Komponenta main očekává, že v předané struktuře session se jí nakonec vrátí data, která pošle zpátky klientovi. Předpokládejme, že klient požadavek zaslal pomocí protokolu Zoomify. Z komponenty main tedy datový objekt session putuje do komponenty zoomify. Tato komponenta ještě neví, s jakým obrázkem pracuje. Předá tedy datový objekt session další komponentě FIF. Komponenta FIF má za úkol rozebrat požadavek a vybrat správný ovladač. Pomocí správného ovladače obrázek otevřít a uložit do objektu session. Potom vrátí řízení komponentě zoomify. Komponenta zoomify nyní může komunikovat přímo s ovladačem. Pokračuje v rozkládání dotazu a žádá ovladač o zvolenou oblast nebo dlaždici v obrázku. Zpracuje také dotazy požadující jiná než výchozí rozlišení nebo vrstvy kvality. Před komunikací s ovladačem zkontroluje cache. Pokud v cache najde požadované části obrázku, není potřeba zatěžovat ovladač. Použije části obrázku uložené v cache.
3.3
Externí knihovny a jejich ovladače
Hlavním úkolem ovladačů v serveru IIPImage je zpracovat data z externích knihoven a předat je serveru v abstraktní podobě. Server dostane od každého ovladače data ve stejné formě, nehledě na to, kterou knihovnu ovladač využívá. Ovladače v IIPImage jsou potomci stejnojmenné třídy IIPImage. Tito potomci překrývají její metody openImage(), loadImageInfo(), closeImage(), getTile() a getRegion(). Pomocí těchto metod předávají serveru zpracovaná data z externích knihoven. Server tedy využívá dědičnosti a datové abstrakce pro práci s ovladači.
1
Cache je kolekce dat, které jsou uchovány i na jiném než původním místě. Například v operační paměti se udržují některá často používaná data, kvůli urychlení opakovaného přístupu k těmto datům.
9
4 IMPLEMENTACE OVLADAČE KNIHOVNY OPENJPEG 4.1
Seznámení s knihovnou OpenJPEG
Knihovna OpenJPEG je kodek standardu JPEG 2000 napsaný v jazyce C1 s otevřeným zdrojovým kódem. Hlavní část této knihovny pokrývá první část standardu JPEG 2000, ale jsou ve vývoji i ostatní moduly, které mají integrovat další částí tohoto standardu [2]. V této práci jsem pracoval s verzí 2.0.1 knihovny OpenJPEG.
4.2
Obrázková data v knihovně OpenJPEG
Knihovna OpenJPEG uchovává dekomprimovaná data obrázku ve struktuře opj_image. Tato struktura je rozdělena na barevné složky. Každý pixel obrázku je uložen jako 32-bitový integer2 v každé barevné složce. Ve standardních obrázcích je obsazen pouze první byte 3 tohoto integeru. Další tři byty jsou prázdné. Server IIPImage počítá s tím, že od ovladačů do svého bufferu4 dostane jeden byte pro každý pixel5 z každé barevné složky obrázku. Pro uložení prvního pixelu do IIPImage bufferu tedy ovladač vezme první integer z každé barevné složky obrázku. Z každého získaného integeru uloží jeho první byte do bufferu. Stejně pokračuje s následujícími pixely.
4.3
Inspirace a zdroje
4.3.1
Ovladač knihovny Kakadu v IIPImage
Při programování ovladače knihovny OpenJPEG jsem vycházel především ze zdrojového kódu ovladače Kakadu v IIPImage. Snažil jsem se z něj zachovat co nejvíce. Chtěl jsem, aby ovladače fungovaly na podobném principu, aby se chovaly stejně ve vyjímečných situacích a aby dokázaly obsloužit i odmítnout stejné požadavky. Tento ovladač mi poskytl především představu o tom, jakou funkci mají jednotlivé metody nového ovladače vykonávat. Pomohl mi také při kontrole parametrů předaných těmto metodám.
1
Jazyk C je populární programovací jazyk. Je nízkoúrovňový, minimalistický a vychází z něj mnoho komplexnějších jazyků. Je vhodný především pro programování systémového softwaru.
2
Integer je primitivní datový typ, který reprezentuje celé číslo
3
Byte je jednotka digitální informace. Skládá se z 8 bitů.
4
Buffer (vyrovnávací paměť) je část paměti, ve které jsou data uchována před přesunem na jiné místo. Například z operační paměti na pevný disk.
5
Pixel je nejmenší jednotka digitální grafiky. Představuje jediný bod v obrázku.
10
4.3.2
Ovladač knihovny OpenJPEG v knihovně GDAL
Inspiroval jsem se také ovladačem knihovny OpenJPEG v knihovně GDAL. Tento ovladač má úplně jinou strukturu než ovladače v IIPImage, ale také čerpá data z knihovny OpenJPEG a využívá její funkce. Pomohl mi porozumět způsobu, jakým jsou dekódovaná obrázková data uložena v datových strukturách knihovny OpenJPEG a jak z těchto dat správně poskládat zvolenou část obrázku. 4.3.3
Zdrojový kód programu opj_decompress
Pomohl mi i zdrojový kód programu opj_decompress, který je distribuován jako součást knihovny OpenJPEG. Tento kód prozrazuje, které funkce této knihovny použít pro otevření a dekódování obrázku ve formátu JPEG 2000.
4.4
Struktura ovladače
4.4.1
Metody openImage() a closeImage()
Při implementaci ovladače jsem postupně psal kód metod, které překrývají metody předka. Začal jsem metodou openImage(), kterou aplikace IIPImage volá jako první. V této metodě ovladač pouze otevře soubor s obrázkem a potom zavolá další metodu loadImageInfo(). Metoda closeImage() slouží k zavření souboru s obrázkem. 4.4.2
Metoda loadImageInfo()
Metoda loadImageInfo() také překrývá metodu předka. V této metodě ovladač nejprve inicializuje dekodér knihovny OpenJPEG. Pomocí tohoto dekodéru přečte hlavní JPEG 2000 hlavičku1 otevřeného souboru. Z této hlavičky zkopíruje informace o obrázku do svých datových struktur a do datových struktur serveru IIPImage. K těmto informacím patří například počet vrstev kvality, počet barevných kanálů nebo počet úrovní rozlišení. 4.4.3
Metody getTile() a getRegion()
Při svém běhu server IIPImage volá metody ovladače getTile() a getRegion(). Tyto metody mají společné jádro, soukromou metodu process(). Když server vyřizuje požadavek na konkrétní dlaždici, zavolá metodu getTile(), která se postará o načtení dlaždice do bufferu. Tato metoda nejprve zkontroluje, jestli dlaždice existuje v požadované úrovni rozlišení a potom zavolá metodu process().
1
Hlavní hlavička formátu JPEG 2000 obsahuje nejdůležitější informace o obrázku. Například rozměry obrázku.
11
Metodu getRegion() server volá, pokud zpracovává požadavek na oblast. Při použití protokolu IIP jde o oblast požádat pomocí parametru CVT. Výška a šířka oblasti lze zadat pomocí parametrů HEI a WID. V této metodě ovladač stejně jako v metodě getTile() zkontroluje, jestli zvolená oblast existuje a potom zavolá metodu process(). 4.4.4
Metoda process()
Metoda process() slouží jako jádro ovladače. Pracuje přímo s OpenJPEG knihovnou a stará se o zpracovávání obrázkových dat. V této metodě ovladač nejprve vytvoří dekodér knihovny OpenJPEG a pomocí něj přečte JPEG 2000 hlavičku. Potom vytvořenému dekodéru předá parametry. Sdělí mu například, ze které úrovně rozlišení data dekódovat a s jakou vrstvou kvality pracovat. Když dokončí inicializaci dekodéru, zavolá funkci knihovny OpenJPEG, která pomocí vytvořeného dekodéru dekóduje vybranou oblast nebo dlaždici z obrázku a uloží ji do struktury opj_image. Nakonec ovladač zkopíruje obrázková data z nové datové struktury opj_image do bufferu, který mu předal server IIPImage. Při tomto kopírování musí do bufferu správně poskládat všechny barevné složky a postarat se o downsampling 1, pokud jsou požadovaná data načítána z virtuální úrovně.
4.5
Virtuální úrovně rozlišení a downsampling
Pokud v IIPImage pracujeme s velikostí dlaždic menší, než je nejmenší úroveň rozlišení ve zpracovávaném obrázku, není možné zmenšit celý obrázek do jedné dlaždice. Ovladač tedy vytvoří virtuální úrovně rozlišení. Například pokud používáme velikost dlaždic 256x256 a obrázek má nejmenší úroveň rozlišení 2000x1200, ovladač vytvoří virtuální úrovně s rozlišením 1000x600, 500x300 a 250x150. Ve výsledku bude možné celý obrázek zmenšit do jedné dlaždice. Tento downsampling je umožněn pouhým vynecháním pixelů z původního obrázku. IIPImage poskytne buffer, do kterého ovladač kopíruje obrázková data získaná z externí knihovny. Když při kopírování pixelů vynechá každý druhý řádek a každý druhý sloupec, získá obrázek s polovičním rozlišením. Ve výsledku je ale lepší vygenerovat obrázek s dostatkem úrovní rozlišení. Virtuální downsampling by měl být aplikován pouze výjimečně a měl by pomoci předejít nepříjemnostem při zpracovávání výjimečných obrázků. Pokud ovladač tímto způsobem vygeneruje nějaké virtuální úrovně, vypíše varování do logovacího souboru2.
1
Downsampling je proces snižování počtu snímaných vzorků z nějakého média nebo signálu. Tedy zvýšení intervalů mezi získáním jednotlivých vzorků.
2
Logovací soubor je textový soubor, do kterého webový server zapisuje chyby, varování a důležité informace o svém běhu.
12
4.6
Interakce ovladače knihovny OpenJPEG se serverem IIPImage
IIPImage má nyní k dispozici dva ovladače pro práci s JPEG 2000 obrázky. Aby věděl, který z nich použít, musel jsem v něm provést několik úprav. Ovladač svoji funkcionalitu poskytuje pomocí překrytých metod třídy IIPImage. Odkaz na třídu nebo potomky třídy IIPImage server ukládá do struktury session. Do této struktury tedy uloží objekt, který reprezentuje zvolený ovladač. V našem případě instanci třídy OpenJPEGImage nebo KakaduImage. IIPImage potom pracuje s objektem uloženým v této struktuře a už se nemusí starat o to, která třída mu data poskytuje. Aby se dokázal rozhodnout, který objekt do struktury uložit, musel jsem do struktury session přidat proměnnou useOpenJPEG. Pokud je hodnota této proměnné nastavena na true, IIPImage použije knihovnu OpenJPEG místo knihovny Kakadu. Tuto proměnnou nastavuje komponenta serveru IIPImage main. Přečte ji z konfiguračního souboru serveru. Aby IIPImage nastavil hodnotu této proměnné na true, je zapotřebí nastavit v konfiguračním souboru hodnotu USE_OPENJPEG na 1. Tento přepínač zatím bohužel není použitelný. Nepodařilo se nám IIPImage sestavit s knihovnou Kakadu a knihovnou OpenJPEG současně. Příčinou jsou stejné názvy hlavičkových souborů obou knihoven. Aby mohl IIPImage použít ovladač OpenJPEG nebo Kakadu, musí být sestaven s příslušnými knihovnami. Při sestavení systém detekuje přítomnost těchto knihoven a definuje macro1 HAVE_KAKADU a HAVE_OPENJPEG. Pokud chceme na linuxovém systému sestavit IIPImage s podporou formátu JPEG 2000, musíme spustit soubor configure s parametry --with-openjpeg=/path_to_openjpeg nebo - -with-kakadu=/path_to_kakadu.
1
Macro je v jazyce C++ pojmenovaná část kódu. Kdykoliv preprocessor narazí na takové jméno, nahradí jej příslušnou částí kódu.
13
5 MĚŘENÍ VÝKONU OVLADAČŮ OPENJPEG A KAKADU 5.1
Představa
Primárním cílem měření je porovnat výkon obou ovladačů. Očekává se, že ovladač knihovny Kakadu bude výrazně rychlejší. Měřil jsem celkový čas provedení metod ovladačů getTile(). Tato metoda se stará o dekódování dlaždice a zkopírování dat této dlaždice do příslušného bufferu. U ovladače knihovny OpenJPEG jsem měřil i dobu čistého dekódování. Tím je volání jediné knihovní funkce opj_decode().
5.2
Metodologie
Jednoduché měření doby běhu metod ovladačů nebo jejich částí mi umožnila třída serveru IIPImage Timer.h. Pomocí volání metod této třídy jsem byl schopen změřit čas před vykonáním kusu kódu a po vykonání tohoto kusu kódu. Pomocí této třídy jsem potom odečetl první čas od druhého a zjistil, jak dlouho trvalo vykonání kusu kódu. Pokud IIPImage beží v debugovacím režimu, ovladač knihovny Kakadu vypisuje časy trvání každé své metody do logovacího souboru. V ovladači knihovny OpenJPEG jsem takové chování zachoval a přidal výpis doby trvání samotné funkce opj_decode(). Při testování jsem se potřeboval ujistit, že v procesu načítání dlaždic nebude figurovat žádný cache. Cache na úrovni operačního systému a systému souborů jsem obešel vytvořením jednoduchého RAM disku1, do kterého jsem přesunul obrázek. Při práci s obrázkem už tedy není zapotřebí přesouvat jej z disku do operační paměti nebo jej hledat v paměti cache. Cache na úrovni serveru IIPImage jsem obešel nastavením jeho velikosti na 0 MB pomocí konfiguračního souboru serveru. Tím jsem se ujistil, že dlaždice budou pomocí obou ovladačů načteny za stejných podmínek Měřil jsem rychlost načtení dlaždic z dvou různých obrázků. Na prvním obrázku je stará mapa s největší úrovní rozlišení o velikosti 8817x7608. Z tohoto obrázku jsem srovnával rychlosti načtení dlaždice z největšího rozlišení, nejmenšího rozlišení a třetího nejmenšího rozlišení. Tento obrázek má celkem sedm úrovní rozlišení. Druhý obrázek má velikost největší úrovně rozlišení 1308x2260. Z druhého obrázku jsem srovnával pouze časy načtení dlaždic z největšího rozlišení.
1
RAM disk je část pevného disku, která je trvale uchována v operační paměti – pro přístup k souborům z RAM disku tedy není nutné kopírovat tyto soubory do operační paměti.
14
Měření jsem prováděl pomocí dotazů protokolu Zoomify. Dotaz pomocí prokolu Zoomify měl následjící formu: http://adresa_iipimage/fcgi- bin/iipsrv?Zoomify=cesta_k_obrazku/TileGroup0/r-x-y Znaky v poslední části dotazu představují úroveň rozlišení, vertikální pozici dlaždice (sloupec) a horizontální pozici dlaždice (řádek).
5.3
Výsledky měření
5.3.1
První obrázek
Obrázek 1: Náhled obrázku se starou mapou
Nejprve jsem měřil čas načtení dlaždice číslo 284 z největší úrovně rozlišení. Výsledky v tabulce jsou uvedeny v mikrosekundách. TABULKA 1: NAČTENÍ DLAŽDICE Z NEJVĚTŠÍ ÚROVNĚ ROZLIŠENÍ Celkový čas metody getTile()
Čas čistého dekódování
Kakadu
27 663
Není k dispozici
OpenJPEG
22 168 704
22 084 777
15
Potom jsem měřil čas načtení dlaždice číslo 1 z třetí nejmenší úrovně rozlišení. Výsledky v tabulce jsou uvedeny v mikrosekundách. TABULKA 2: NAČTENÍ DLAŽDICE Z TŘETÍ NEJMENŠÍ ÚROVNĚ ROZLIŠENÍ Celkový čas metody getTile()
Čas čistého dekódování
Kakadu
38 835
Není k dispozici
OpenJPEG
2 003 617
1 910 535
V této tabulce jsou uvedeny časy načtení dlaždice číslo 0 z nejmenší úrovně rozlišení. Tedy celý obrázek zmenšený ovladačem do rozlišení 137x118. Výsledky v tabulce jsou uvedeny v mikrosekundách. TABULKA 3: NAČTENÍ DLAŽDICE Z NEJMENŠÍ ÚROVNĚ ROZLIŠENÍ Celkový čas metody getTile()
Čas čistého dekódování
Kakadu
26 295
Není k dispozici
OpenJPEG
1 825 499
1 738 162
5.3.2
Druhý obrázek
Obrázek 2: Náhled obrázku s obalem knížky 16
Z druhého obrázku jsem měřil pouze načtení třetí dlaždice z největší úrovně rozlišení. Výsledky v tabulce jsou uvedeny v mikrosekundách. TABULKA 4: NAČTENÍ DLAŽDICE Z NEJVĚTŠÍ ÚROVNĚ ROZLIŠENÍ Celkový čas metody getTile()
Čas čistého dekódování
Kakadu
16 279
Není k dispozici
OpenJPEG
91 175
85 564
17
6 ZÁVĚR 6.1
Shrnutí výsledků měření
Z uvedených výsledků testů v předchozí kapitole jde vidět, že ovladač knihovny Kakadu je mnohonásobně rychlejší. Načtení dlaždice z rozlišení 8817x7608 trvá pomocí ovladače knihovny OpenJPEG dokonce tisíckrát déle než pomocí ovladače knihovny Kakadu. Při práci s menším obrázkem už ale ovladač knihovny OpenJPEG pracuje lépe a dosahuje přibližně šestkrát horšího času. Většinu času načítání dlaždice z obrázku ale zabere samotné dekódování dlaždice, tedy volání funkce opj_decode(). Volání dalších funkcí a všechny ostatní operace zaberou ve všech případech pouze několik procent celkového času. V případě prvního obrázku a načítání dlaždice z rozlišení 8817x7608 zaberou přibližně 0.4 % celkového času načítání. V případě druhého obrázku a rozlišení 1308x2260 je to přibližně 6 %.
6.2
Závěr
V ovladači knihovny OpenJPEG čas načítání dlaždic závisí především na výkonu knihovny OpenJPEG a její funkce opj_decode(). Vykonání této funkce pokryje většinu času zpracování dotazu. Při načítání dlaždic z velkých obrázků jsou naměřené časy příliš vysoké. Nový ovladač tedy není příliš vhodný pro použití v praxi. Dal by se použít pro poskytování menších obrázků jako náhrada ovladače proprietální knihovny Kakadu. Pokud bude vývoj knihovny OpenJPEG pokračovat a její výkon se přiblíží výkonu knihovny Kakadu, bude možné ovladač použít i pro práci s většími obrázky. Ovladač také může sloužit pro porovnání výkonu obou knihoven v praxi.
6.3
Co by šlo v budoucnu zlepšit
Ovladač jsem implementoval pro potřeby Moravské zemské knihovny v Brně. Umí pracovat se standardními obrázky, ale obrázky s netypickými parametry odmítne. Netypickými parametry je myšlena například bitová hloubka obrázku větší než osm nebo jiné barevné prostory než sRGB a Greyscale. Pokud někdy bude potřeba pracovat s takovými obrázky, lze do ovladače přidat podporu pro netypické parametry. Server IIPImage standardně zpracovává 8-bitové obrázky. Umí ale pracovat i s 16-ti nebo 32-bitovými. Ovladač knihovny OpenJPEG nyní dokáže zpracovat pouze 8-bitové obrázky. Pro obrázky s jinou bitovou hloubkou má nedefinované chování. Podporu pro jiné bitové hloubky jsem nepřidával, protože ani ovladač knihovny Kakadu s nimi nepracuje.
18
Nový ovladač umí pracovat s barevnými prostory sRGB1 a Greyscale2. V IIPImage lze použít i prostor CIE L*a*b3. S ním v tuto chvíli ovladač knihovny OpenJPEG neumí pracovat, ale je možné podporu pro tento barevný prostor doimplementovat. Momentálně ovladač podporuje pouze obálkový formát jp2. V budoucnu je možné přidat podporu i pro ostatní JPEG 2000 obálky, například jpx. V instalačních souborech serveru IIPImage pro operační systém Windows zatím také není podpora knihovny OpenJPEG. Je ale možné ji do těchto instalačních souborů přidat a tedy umožnit provoz serveru IIPImage s tímto ovladačem na operačním systému Windows.
1
sRGB je standardní RGB (Red Green Blue, červená zelená modrá) barevný prostor.
2
Greyscale je černobílý barevný prostor. Skládá se pouze z jedné barevné složky.
3
CIE L*a*b je barevný prostor, který se skládá z jedné složky popisující míru osvětlení a dvou barevných složek.
19
SEZNAM POUŽITÝCH ZDROJŮ [1] JPEG 2000. In: Wikipedia: the free encyclopedia [online].
San Francisco (CA): Wikimedia Foundation, 2001-[cit. 2014-04-13]. Dostupné z: http://en.wikipedia.org/wiki/JPEG_2000 [2] ZAPLETAL, Lukáš. Protokol HTTP 1.1 pod lupou. In: Root.cz [online]. 1998
[cit. 2014-05-13]. Dostupné z: http://www.root.cz/clanky/protokol-http-1-1-pod-lupou/ [3] OpenJPEG [online]. 2002 [cit. 2014-04-29]. Dostupné z: http://www.openjpeg.org/ [4] BSD License Definition. The Linux Information Project [online]. 2004 [cit. 2014-04-29].
Dostupné z: http://www.linfo.org/bsdlicense.html [5] GDAL [online]. 2005 [cit. 2014-04-13]. Dostupné z: http://www.gdal.org/ [6] Kakadu Non-Commercial License. In: KAKADU SOFTWARE SINGLE USER NON-
COMMERCIAL LICENSE AGREEMENT [online]. 2011 [cit. 2014-05-13]. Dostupné z: http://www.kakadusoftware.com/documents/licences/KAKADU_Single_User_Non_Co mmercial_Licence_Agreement_070815.pdf [7] IIPImage JPEG2000. Old Maps Online [online]. [cit. 2014-05-13]. Dostupné z:
http://help.oldmapsonline.org/jpeg2000 [8] BSD license. In: BSDlicense.txt [online]. 2001 [cit. 2014-05-13]. Dostupné z: http://www.openjpeg.org/BSDlicense.txt [9] IIPImage [online]. 2000 [cit. 2014-05-13]. Dostupné z: http://iipimage.sourceforge.net/
20
SEZNAM ELEKTRONICKÝCH PŘÍLOH [1] Zdrojový kód ovladače knihovny OpenJPEG v souboru OpenJPEGImage.cc. [2] Hlavičkový soubor k tomuto zdrojovému kódu v souboru OpenJPEGImage.h. [3] Soubor readme.txt, ve kterém je odkaz na repozitář se všemi soubory potřebnými k sestavení serveru IIPImage s knihovnou OpenJPEG. Tento textový soubor také obsahuje popis změn, které jsem provedl v původních souborech. [4] Vzorový obrázek staré mapy, na kterém bylo prováděno měření výkonu.
21
SEZNAM TABULEK TABULKA 1: NAČTENÍ DLAŽDICE Z NEJVĚTŠÍ ÚROVNĚ ROZLIŠENÍ.............................................15 TABULKA 2: NAČTENÍ DLAŽDICE Z TŘETÍ NEJMENŠÍ ÚROVNĚ ROZLIŠENÍ...............................16 TABULKA 3: NAČTENÍ DLAŽDICE Z NEJMENŠÍ ÚROVNĚ ROZLIŠENÍ............................................16 TABULKA 4: NAČTENÍ DLAŽDICE Z NEJVĚTŠÍ ÚROVNĚ ROZLIŠENÍ.............................................17
22
SEZNAM OBRÁZKŮ OBRÁZEK 1: NÁHLED OBRÁZKU SE STAROU MAPOU..................................................................15 OBRÁZEK 2: NÁHLED OBRÁZKU S OBALEM KNIHY.....................................................................16
23