<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xml" href="/cjs/screen.xsl" media="screen"?>
<lecture>

<meta>
    <maintitle>Webové technologie</maintitle>
    <author>Jiří Znamenáček</author>
    <title>NetPBM</title>
    <date>2011-04-07</date>
    <link><!--a href="http://vyuka.ookami.cz" rel="external">http://vyuka.ookami.cz</a--></link>
</meta>
<!--
  „“–
  ↵ aneb &#x21B5; aneb \r aneb CR aneb CarriageReturn
-->


<slide title="Úvod">

    <p>
        Rodinu grafických formátů <strong>PBM</strong> (někdy též souhrnně nazývanou <strong>PNM</strong>, <em>portable anymap format</em>) vymyslel v 80. letech Jef Poskanzer. Jeho původním záměrem bylo vytvořit monochromatický grafický formát, který by se dal přenášet v těle emailu jako obyčejné ASCII.
    </p>
    <p>
        Později byl formát rozšířen o možnost zobrazení škály šedé a klasické 8-bitové RGB-spektrum a nakonec i o 16-bitové (které je ale dosti nestandardizované). Je sice velmi nešikovný na uchovávání větších objemů dat, protože jde v podstatě pouze o nekomprimovanou sekvenci údajů o jednotlivých pixelech obrázku, ale na druhou stranu se s ním z úplně stejného důvodu velmi snadno pracuje, a proto je často používán jako pracovní grafický formát.
    </p>
    <p>
        Dnes se o jeho udržování stará projekt <a href="http://netpbm.sourceforge.net/doc/pbm.html">Netpbm</a>.
    </p>
    <note>
        Příklady ve slajdech převzaty a případně upraveny podle <a href="http://en.wikipedia.org/wiki/Netpbm_format">Wikipedie</a>.
    </note>

</slide>
<slide title="Rozdělení">

    <p>
        Rodina formátů <b>Netpbm</b> je extrémně jednoduchá na zpracovávání (a ruku v ruce s tím extrémně nevhodná na uchovávání :). Obsahuje celkem 6 různých formátů lišících se barevnou „hloubkou“ a typem kódování:
    </p>
    <table align="center">
        <tr>
            <th> identifikátor pro kódování<br/>ASCII / binary </th>
            <th> typ </th>
        </tr>
        <tr>
            <td> P1 / P4 </td>
            <td> PBM = portable bitmap (černobílé) </td>
        </tr>
        <tr>
            <td> P2 / P5 </td>
            <td> PGM = portable graymap (odstíny šedé) </td>
        </tr>
        <tr>
            <td> P3 / P6 </td>
            <td> PPM = portable pixmap (RGB) </td>
        </tr>
    </table>
    <p>
        <i>ASCII</i> se bezvadně čte, ale pochopitelně je oproti <i>binary</i> pekelně nafouknuté – kde v binárním P6 pro zápis RGB-pixelu stačí 3 bajty, tam ASCII P3 potřebuje bajtů až 11 (a to počítám pouze mezery mezi barvami jednoho pixelu, nikoli mezi jednotlivými pixely).
    </p>

</slide>
<slide title="Struktura">

    <p>
        Struktura PNM-formátů je obecně následující:
    </p>
    <pre>identifikátor↵↵          # identifikátor podle tabulky výše
[# komentář↵↵]           # nepovinný; často je zde název souboru
šířka↵↵výška↵↵           # rozměry zadány jako dekadické číslo v ASCII
maximální-počet-barev↵   # zadán jako dekadické číslo v ASCII; >0 &amp; &lt;=255 (resp. 65536)
data-obrázku             # „mřížka“ pixelů o daném počtu řádků a sloupců  </pre>
    <note>
        <code>↵↵</code> představuje libovolný počet bílých znaků (<em>whitespace</em>, tj. mezery, TABy, CR, LF), <code>↵</code> zastupuje právě jeden bílý znak.
    </note>
    <p>
        Dejte si pozor, kam a jak píšete komentáře – obecně všechno za znakem <code>#</code> je pokládáno za komentář, to znamená i uprostřed řádky (a hlavně odřádkování na konci komentáře), což může někdy udělat nečekanou paseku. Podobně není (u ASCII-kódování) doporučováno mít datové řádky delší než 70 znaků. A nakonec data obrázku by také měla končit na <em>whitespace</em>, protože některé programy si s tím jinak neporadí.
    </p>

</slide>
<slide title="PBM ASCII">

    <p>
        Struktura PBM je obecně následující (nyní už zjednodušeně oproti obecnému popisu z předchozího slajdu):
    </p>
    <pre>identifikátor
šířka výška
data-obrázku  </pre>

    <p>
        Pro ukázku PBM-souboru (tj. černobílého) si ukažme jednoduché písmeno J ve variantě P1, tj. ASCII:
    </p>
    <example src="_files/PBM-example.pbm" lang="text" />
    <p>
        V tomto souboru je zaznamenán následující obrázek (dvacetkrát zvětšené): <img src="_files/PBM-example.scale20.png" width="120" height="190" alt="" title="" />
    </p>
    <p>
        PS: Formát <em>P1</em> je také jediný, ve kterém můžete vynechat mezery mezi daty obrázku – rozlišení mezi 0 a 1 je zadrátováno ve všech prohlížečích.
    </p>

</slide>
<slide title="PBM binary">

    <p>
        Binární podoba, tedy varianta P4, se z pochopitelných důvodů úspornosti liší od binárních variant vícebarevných formátů PGM a PPM:
    </p>
    <blockquote>
        Po hlavičce, která je společná ASCII i binární variantě, následují (za povinným <strong>právě jedním prázdným znakem/bajtem</strong>) data obrázku v podobě – <em>co 8 pixelů, to jeden bajt</em>.
    </blockquote>
    <p>
        Každých osm sloupečků je tedy sloučeno do jednoho bajtu, ve kterém jejich barvové hodnoty (černá/bílá) představuje nastavení příslušných bitů (0/1). „Přebytečné“ sloupečky (tedy sloupečky, které musíme doplnit, abychom dostali celý počet bajtů) jsou „shrnuty“ do posledního bajtu v podobě nul.
    </p>
    <note>
        PS: V principu prohlížeče obrázků na data v „přebytečných“ sloupcích nemají důvod vůbec brát zřetel, takže do nich můžete schovat, co vás napadne, a neomezovat se jen na stadardní nuly. Co třebas šifrovaná zpráva v kódování na tři bity? ^_~
    </note>

</slide>
<slide title="PS: Vynucení zobrazení pixelů bez vyhlazování">
    
    <p>
        Jelikož při ladění PNM-obrázků je poměrně důležité vidět jednotlivé pixely a jelikož prakticky všechny běžně používané zobrazovače mají ve výchozím nastavení zapnuto vyhlazování obrázků (pokud neděláte s něčím určeným specificky pro <em>pixel art</em>), je třeba uvedené vypnout. Zde pro příklad nastavení prohlížeče <a href="https://www.irfanview.com" class="external">IrfanView</a>:
    </p>
    <img src="_files/_nastaveni_IrfanView.jpg" width="776" height="700" alt="vypnutí vyhlazování v IrfanView" />
    
</slide>
<slide title="PGM ASCII">

    <p>
        Struktura PGM je obecně následující (opět zjednodušeně oproti obecnému popisu):
    </p>
    <pre>identifikátor
šířka výška
maximální-počet-stupňů-šedi
data-obrázku  </pre>
    
    <p>
        Jako příklad PGM (tj. obrázek ve stupních šedi) ve variantě P2, tj. ASCII, si ukažme následující:
    </p>
    <example src="_files/PGM-example.2.pgm" lang="text" />
    <p>
        V tomto souboru je zaznamenán následující obrázek (asi třicetkrát zvětšené): <img src="_files/PGM-example.2.scale30.png" width="589" height="173" alt="" title="" />
    </p>
    <p>
        PS: Navzdory logice zde mezera mezi jednotlivými pixely je <!--(alespoň pro většinu programů)--> nutná i v případě, že používáme pouze barvy s maximálním indexem 9. Optimalizované rozlišení mezi jedno- a vícecifernými čísly už není nikde přítomno.
    </p>

</slide>
<slide title="PGM binary">

    <p>
        Binární podoba, tedy varianta P5, je zcela průhledná:
    </p>
    <blockquote>
        Po hlavičce, která je společná ASCII i binární variantě, následují (za povinným <strong>právě jedním prázdným znakem/bajtem</strong>) data obrázku v podobě – <em>co pixel, to jeden bajt</em>.
    </blockquote>
    <p>
        Binární varianta tedy sdílí – samozřejmě až na identifikátor – s ASCII-variantou hlavičku (a to klidně až po finální bílý znak, který ale musí být opravdu jen a pouze jeden<sup>*</sup>) a k vlastnímu ušetření paměti dochází až na úrovni dat obrázků.
    </p>
    <note>
        <sup>*</sup> Pozor tedy na rozdělovače typu „dvoubajtový konec řádky textového souboru ve Windows“! Jinak je první bajt použit jako rozdělovač a druhý jako první bajt dat obrázku a nebudete se stačit divit výsledku ^_~
    </note>

</slide>
<slide title="PPM ASCII">

    <p>
        Struktura PPM je obecně následující (opět zjednodušeně oproti obecnému popisu):
    </p>
    <pre>identifikátor
šířka výška
maximální-počet-barev
data-obrázku  </pre>
    
    <p>
        PPM se od PGM liší tím, že na každý pixel musí zaznamenat tři barvy, a to postupně v pořadí R-G-B (tj. červená, zelená, modrá). Použijeme-li podobně přehledný způsob zaznamenání jako dříve, následující obrázek (šedesátčtyři-krát zvětšeno) <img src="_files/PPM-example.scale64.png" width="192" height="128" alt="" title="" /> bude v ASCII-variantě P3 zapsán takto:
    </p>
    <example src="_files/PPM-example.ppm" lang="text" />
    <note>
        Jak jsou pixely „rozházené“ po řádcích není podstatné, protože příslušnou informaci si zpracovávající software načte z druhého významového řádku.
    </note>

</slide>
<slide title="PPM binary">

    <p>
        Binární podoba, tedy varianta P6, je opět zcela průhledná a prakticky stejná, jako u P5 (šedotónový binární), pouze na každý pixel připadají nyní tři barvové údaje (za červenou, zelenou a modrou složku):
    </p>
    <blockquote>
        Po hlavičce, která je (až na identifikátor) společná ASCII i binární variantě, následují (za povinným <strong>právě jedním prázdným znakem/bajtem</strong>) data obrázku v podobě – <em>co pixel, to právě tři bajty (postupně R, G a B)</em>.
    </blockquote>

</slide>
<slide title="Srovnávací tabulka">

    <table class="center" border="1">
        <tr>
            <th>formát</th>
            <th>varianta</th>
            <th>kódování</th>
            <th>poznámky</th>
        </tr>
        <tr>
            <th>PBM</th>
            <td>P1</td>
            <td>ascii</td>
            <td>
                Daty jsou buď 0 (bílá) nebo 1 (černá).
                <br/>
                1 pixel ~ 1 znak (mezera nepovinná)
            </td>
        </tr>
        <tr>
            <th/>
            <td>P4</td>
            <td>binární</td>
            <td>
                8 pixelů ~ 1 bajt
                <br/>
                Doplňkové sloupečky součástí posledního bajtu (většinou jako nuly).
            </td>
        </tr>
        <tr>
            <th>PGM</th>
            <td>P2</td>
            <td>ascii</td>
            <td>
                Daty jsou čísla od 0 (černá) po nejvyšší odstín (bílá).
                <br/>
                1 pixel ~ až 3 znaky (plus další na mezeru)
            </td>
        </tr>
        <tr>
            <th/>
            <td>P5</td>
            <td>binární</td>
            <td>1 pixel ~ 1 bajt</td>
        </tr>
        <tr>
            <th>PPM</th>
            <td>P3</td>
            <td>ascii</td>
            <td>
                Daty jsou trojce čísel od 0 po (převážně) 255.
                <br/>
                1 pixel ~ až 11 znaků (plus další na mezeru)
            </td>
        </tr>
        <tr>
            <th/>
            <td>P6</td>
            <td>binární</td>
            <td>1 pixel ~ 3 bajty</td>
        </tr>
    </table>

</slide>
<slide title="Poznámky">

    <p class="enumerate">
        ASCII-kódování znamená, že to jsou řetězcové údaje v kódování ASCII! V základním nastavení by to mělo být v pořádku, protože spodní polovina jednobajtových kódování (ve většině případů ) i UTF8 bez BOMu jsou v podstatě právě ASCII.
    </p>
    
    <p class="enumerate">
        Rozložení pixelů do řádek v datech obrázku není podstatné – zpracovávající program ví vše potřebné už z hlavičky. Pouze se doporučuje, aby u ASCII-formátů nebyla žádná z řádek delší než 70 znaků.
    </p>
    <note>
        Pro vlastní ruční tvorbu (nebo čtení) je samozřejmě vizuální rozdělení po pixelech velmi přínosné.
    </note>
    
    <p class="enumerate">
        Komprese do bajtů mezi ASCII-formátem a binárním formátem se projevuje až na úrovni dat obrázků – celá hlavička je zaznamenána znakově v ASCII!
    </p>
    
    <p class="enumerate">
        Rozšíření na 16-bitovou barevnou hloubku s sebou nese potřebu rozhodnout o pořadí příslušných dvou bajtů. Nepřekvapivě se na tom jednotlivé implementace neshodnou, ale <em>de facto</em> standard <em>Netpbm</em> bere jako nejvýznamější bajt ten první.
    </p>

</slide>


</lecture>
