Chromium obrázek v minulém díle sice nezobrazilo, ale aspoň nám dalo k zabavení dva různé střídající se druhy chybových hlášek pod otráveně se tvářící autobaterií. Chromium také někdy zamrzne na dlouhou dobu už jen při otevření upload dialogu, pokud v předtím použitém adresáři je na prvním místě velký soubor JPEG. Nepřekresluje při tom okno a nereaguje na zavření.
| Legenda barev |
|---|
| Správná funkce nebo pouze spletení binárních a decimálních jednotek |
| Nelze provést z důvodu, za který aplikace nemůže |
| Správná funkce aplikace, ale neresponzivní během provádění |
| Nepřiměřeně pomalá funkce aplikace |
| Selhání aplikace chybovou hláškou o přektročení velikostního limitu, zobrazení uniformního pole nebo náhradní textová informace |
| Nelze provést vinou aplikace |
| Chybná funkce aplikace vč. chybové hlášky, která neříká že se jedná o překročení velikostního limitu |
| Spadnutí aplikace |
| Vytuhnutí aplikace |
| Chybná funkce operačního systému |
| DoS útok na systém |
| Zhroucení operačního systému |
Airdroid
Opět testujeme soubory různých velikostí, vytvořenými programem Jpeginsert.
| Program | Doba načítání JPEGu o výsledné velikosti | |||||
|---|---|---|---|---|---|---|
| 3,8 MB | 529 MB | 931 MB | 2,5 GB | 4,0 GB | 31 GB | |
| iPhone Airdroid - přístup do obrazové galerie prohlížečem | 5 s (což je i bez zvláštních fotek, někdy i 16 s) | Teprv za 11 s se zobrazí že v galerii vůbec nějaké obrázky jsou a obrázek můžeme stahnout rychlostí 90 Mbps (ipheth přes USB kabel). Obsah je bílá plocha, za dalších 26 s se nahradí ikonou obrázku přes kterou je throbber. | Teprv za 16 s se zobrazí že v galerii vůbec nějaké obrázky jsou. Obsah je bílá plocha, za dalších 35 s se nahradí ikonou obrázku přes kterou je throbber. | Nezobrazí se, Airdroid předstírá, že tam není. | Nezobrazí se, Airdroid předstírá, že tam není. | Nelze provést, na telefonu není dost místa. |
| iPhone Airdroid do PC: download obrázku (ipheth přes USB kabel) | 0 s | 90 Mbps.
Content-type je na rozdíl od ostatních obrázků application/octet-stream a při ukládání se nabídne jméno bez přípony.
| 103 Mbps.
Content-type je na rozdíl od ostatních obrázků application/octet-stream a při ukládání se nabídne jméno bez přípony.
| Nelze provést, Airdroid předstírá, že tam není. | Nelze provést, Airdroid předstírá, že tam není. | Nelze provést, na telefonu není dost místa. |
| Airdroid - smazání obrázku přes prohlížeč | 0 s | Airdroid v prohlížeči nás jako obvykle požádá, abychom odsouhlasili potvrzení mazání na obrazovce telefonu, tam se ale ani za 60 s žádné neobjeví. Obrázek se nesmaže. | Airdroid v prohlížeči nás jako obvykle požádá, abychom odsouhlasili potvrzení mazání na obrazovce telefonu, tam se ale ani za 60 s žádné neobjeví. Obrázek se nesmaže. | Nelze provést, Airdroid předstírá, že tam není. | Nelze provést, Airdroid předstírá, že tam není. | Nelze provést, na telefonu není dost místa. |
| Airdroid - upload jednotlivého obrázku | Upload 136 Mbps brutto, čekání 1 s, úspěch | Nejdříve prohlížeči trvá dlouho vygenerování thumbnailu při uploadu. Upload je přes USB ipheth 130 Mbps. Pak je 27 s pauza než se objeví hláška o úspěchu. | 136 Mbps brutto. Po 100% čekání 32 s. | 149 Mbps brutto.
Po 100% se objeví "Failed to upload file" a "Failed", v idevicepair pair &&
ifuse ~/iphone_mnt se ale objevil, a to se správnou MD5.
| 130 Mbps brutto. Nesprávně zobrazená velikost 3,72 GB, skutečná je 3,99 GB (3,72 GiB).
Po 100% se objeví "Failed to upload file" a "Failed", v idevicepair pair &&
ifuse ~/iphone_mnt se ale objevil, a to se správnou MD5.
| Nelze provést, na telefonu není dost místa. |
| Airdroid - dání obrázku do samostatného adresáře a upload adresáře do sekce Photos | Upload 136 Mbps, po 100% čekání 1 s, úspěch | Upload 132 Mbps, po 100% čekání 33 s, úspěch | Upload 134 Mbps, po 100% čekání 30 s, úspěch. | Uploaduje 136 Mbps, po 2 min 33 s dojde na 100% a ohlásí chybu "⚠ Failed to upload the file". V galerii iPhonu se nic neobjeví a volné místo se nesníží. | Uploaduje 136 Mbps, na 100% a ohlásí chybu "⚠ Failed to upload the file". V galerii iPhonu se nic neobjeví, ale v
idevicepair pair && ifuse ~/iphone_mnt se soubor objevil se správnou MD5.
| Nelze provést, na telefonu není dost místa. |
| Airdroid - upload adresáře s 1 obrázkem do sekce Files | 0,5 s | 136 Mbps brutto, po 100% je úspěch za 0 s. | 134 Mbps brutto, po 100% je úspěch za 1 s. | Upload 136 Mbps, po 100% je úspěch za 0 s. | 141 Mbps brutto. Nesprávně zobrazená velikost 3,72 GB, skutečná je 3,99 GB (3,72 GiB). | Nelze provést, na telefonu není dost místa. |
| Airdroid - otevření seznamu souborů, které přišly z PC do sekce Files | 0 s | 2,5 s | 3,5 s | 16 s | 12 s | Nelze provést, na telefonu není dost místa. |
| Airdroid - náhled obrázku v seznamu souborů, které přišly z PC do sekce Files | 0 s | 2,5 s | 3,5 s | Místo obrázku je pouze text jméno souboru, JPEG image a velikost | 1 s, místo obrázku je pouze text jméno souboru a "JPEG image 3,99 GB". | Nelze provést, na telefonu není dost místa. |
| Airdroid - uložení obrázku v seznamu souborů které přišly z PC do sekce Files, do iPhone fotogalerie | 0,5 s. [↑] neexistuje. Je třeba dlouze stisknout a "Save to album" nebo "Share", "Save Image" | [↑], "Save Image" existuje, dlouhý stisk na "obrázek" je ignorován. Nic se nestane, ač Airdroid předstírá že se operace provedla. | [↑], "Save Image" existuje, dlouhý stisk na "obrázek" je ignorován. Nic se nestane, ač Airdroid předstírá že se operace provedla. | [↑], "Save Image" existuje, dlouhý stisk na "obrázek" je ignorován. Nic se nestane, ač Airdroid předstírá že se operace provedla. | [↑], "Save Image" existuje, dlouhý stisk na "obrázek" je ignorován. Nic se nestane, ač Airdroid předstírá že se operace provedla. | Nelze provést, na telefonu není dost místa. |
| Airdroid - obrázek v seznamu souborů které přišly z PC do sekce Files: View Exif Lite | 0,5 s. [↑] neexistuje. Je třeba dlouze stisknout a "Share", "View Exif Lite" | Objeví se throbber a malá ikonka Exif Lite. Po 0,7 s se vrátí do menu aniž by se Exif Lite spustil. Při dalších pokusech je návrat za 0,1 s. | Objeví se throbber a malá ikonka Exif Lite. Po 1 s se vrátí do menu, aniž by se Exif Lite spustil. Při dalších pokusech je návrat za 0,6 s. | [↑], "View Exif Lite" existuje, dlouhý stisk na "obrázek" je ignorován. 0 × 0 (špatně), Zero KB (špatně) | [↑], "View Exif Lite" existuje, dlouhý stisk na "obrázek" je ignorován. Bílé pozadí, 0 × 0 (špatně), Zero KB (špatně) | Nelze provést, na telefonu není dost místa. |
| Airdroid - obrázek v seznamu souborů které přišly z PC do sekce Files, Save to Files | 0,5 s úspěch. [↑] neexistuje. Je třeba dlouze stisknout a "Share", "Save to Files" | 0 s úspěch, [↑], "Copy to Documents" existuje, dlouhý stisk na "obrázek" je ignorován. | 0 s úspěch, [↑], "Copy to Documents" existuje, dlouhý stisk na "obrázek" je ignorován. | 0 s úspěch, [↑], "Copy to Documents" existuje, dlouhý stisk na "obrázek" je ignorován. | 0 s úspěch, [↑], "Copy to Documents" existuje, dlouhý stisk na "obrázek" je ignorován. | Nelze provést, na telefonu není dost místa. |
| Airdroid - obrázek v seznamu souborů které přišly z PC do sekce Files: Copy to Documents (by Readdle) | 0,3 s úspěch. [↑] neexistuje. Je třeba dlouze stisknout a "Share", "Copy to Documents" | 0 s úspěch, [↑], "Copy to Documents" existuje, dlouhý stisk je ignorován. | 0 s úspěch, [↑], "Copy to Documents" existuje, dlouhý stisk je ignorován. | 0 s úspěch, [↑], "Copy to Documents" existuje, dlouhý stisk je ignorován. | 0 s úspěch, [↑], "Copy to Documents" existuje, dlouhý stisk je ignorován. | Nelze provést, na telefonu není dost místa. |
| Airdroid - smazání obrázku ze seznamu souborů které přišly z PC do sekce Files | 10 s (v přítomnosti jiného 2,5 GB obrázku který nemažeme), 0,5 s samotný. | 1,5 s | 2 s | 0,5 s | 2 s | Nelze provést, na telefonu není dost místa. |
Documents by Readdle
| Program | Doba načítání JPEGu o výsledné velikosti | |||||
|---|---|---|---|---|---|---|
| 3,8 MB | 529 MB | 931 MB | 2,5 GB | 4,0 GB | 31 GB | |
| Documents by Readdle - prohlédnutí obrázku | 0 s | 0,6 s, Ikona rozbitého obrázku a "Image is broken" | Ikona rozbitého obrázku a "Image is broken" | Ikona rozbitého obrázku a "Image is broken" | Ikona rozbitého obrázku a "Image is broken" | Nelze provést, na telefonu není dost místa. |
| Documents by Readdle - upload z PC přes webový prohlížeč přes síť přes USB ipheth | 0,5 s | Chromium po kliknutí na soubor před uploadem na 10 s zamrzne, nepřekresluje, nejde zavřít. Upload 136 Mbps brutto. | Chromium po vstupu do adresáře se souborem na 16 s zamrzne, nepřekresluje, nejde zavřít. Upload 136 Mbps brutto. | Chromium zamrzne a nereaguje na zavření na 1 min 15 s (v posledně použitém adresáři je na 1. místě 4 GB JPEG) a pak na 49 s při výběru souboru, který chceme. Upload 136 Mbps brutto. | Chromium zamrzne a nereaguje na zavření na 1 min 15 s. Upload 136 Mbps brutto. | Nelze provést, na telefonu není dost místa. |
| Documents by Readdle interní web browser: z PC do iPhone přes busybox httpd, USB kabel a ipheth | 0,5 s | 136 Mbps brutto | 136 Mbps brutto | 136 Mbps brutto. Někdy se ukazatel uploadu zasekne na 92 MB, telefon se nepřiměřeně přehřeje (baterie ale nevybuchne), ale data stále po síti proudí plnou rychlostí, pak ukazatel náhle skočí na 1,02 GB. Download je pak přerušený na 2,39 GB z 2,47 GB, první stisk restartovací ikony se ignoruje, po druhém stisku se zbytek souboru downloaduje. Data nebyla poškozena. | 136 Mbps brutto | Nelze provést, na telefonu není dost místa. |
| Z Documents by Readdle do fotogalerie: [↑] Save Image | 0,3 s | 0 s, ale operace se neprovede. Documents by Readdle se tváří, jako by se operace provedla. | 0 s, ale operace se neprovede. Documents by Readdle se tváří, jako by se operace provedla. | Obrázek se do galerie neuložil. Pouze se to tvářilo, jako by operace proběhla. | Obrázek se do galerie neuložil. Pouze se to tvářilo, jako by operace proběhla. | Nelze provést, na telefonu není dost místa. |
| Z Documents by Readdle do fotogalerie: ... vpravo nahoře, Save to Camera Roll | 0,4 s | 4,3 s | 7 s | "Error: The operation couldn't be completed. (RDVirtualFileSystemErrorDomain error
1)"
a obrázek se ve fotogalerii
neobjevil, místa na telefonu neubylo, ale v idevicepair pair && ifuse ~/iphone_mnt se objevil se správnou MD5. Po smazání
obrázku z "Documents by Readdle" ale místo na telefonu nepřibylo.
Při mačkání Retry se kopie hromadí, ale místo na telefonu nekonzumuje. Skip a Cancel se chovají stejně. Po několikerém zkoušení
těchto jevů iPhone (Settings) trvale zamrzá při pokusu zjistit volné místo na filesystému a je nutné ho natvrdo rebootovat.
| "Error: The operation couldn't be completed. (RDVirtualFileSystemErrorDomain error 1.)
a obrázek se ve fotogalerii
neobjevil, a to ani v idevicepair pair && ifuse ~/iphone_mnt, i když na telefonu bylo 6,9 GB volného místa.
| Nelze provést, na telefonu není dost místa. |
| Nahlédnutí aplikací Documents by Readdle když je obrázek ve fotogalerii iPhonu | 0 s | 5 s, ikona roztrženého obrázku, "Image is broken" | 7 s, ikona roztrženého obrázku, "Image is broken" | Předstírá, že tam obrázek není když tam je. | Předstírá, že tam obrázek není když tam je. | Nelze provést, na telefonu není dost místa. |
| Documents by Readdle, obrázek je ve fotogalerii iPhonu, otevření menu [↑] | 0,5 s | První 2-3 pokusy: "Can't open the file: Unable to access file.". Následné pokusy: "Preparing..." 4 s. Posuneme-li se na jiný obrázek a zpět, dostane se to zpět do stavu s chybovou hláškou. | 12 s | Nelze provést, předstírá, že tam obrázek není, když tam je. | Nelze provést, předstírá, že tam obrázek není, když tam je. | Nelze provést, na telefonu není dost místa. |
| Z Documents by Readdle do fotogalerie: ... pod obrázkem, Move, My Files/Photos | 0,9 s | 5 s. Po nahlédnutí obrázku v iPhone galerii a zobrazení velikosti se iPhone krátce rebootuje s černou obrazovkou a throbberem a nereaguje na vstupy, tento problém jsem replikoval 3× za sebou, někdy se iPhone pak i rebootuje samovolně. Telefon byl nabitý na 98%, nebyl přehřátý a měl 8,3 GB volného místa. | 9 s | "Error occured while processing file ... The operation couldn't be completed.
(PHPhotosErrorDomain error 3305.)". Jindy je místo čísla 3305 číslo -1.
Obrázek se ve fotogalerii
neobjevil, místa na telefonu neubylo, ale v idevicepair pair && ifuse ~/iphone_mnt se objevil se správnou MD5. Po smazání
obrázku z "Documents by Readdle" ale místo na telefonu nepřibylo.
Při mačkání Retry se kopie hromadí, ale místo na telefonu nekonzumuje. Skip a Cancel se chovají stejně.
| "Error occured while processing file ... The operation couldn't be completed.
(PHPhotosErrorDomain error -1.)".
Obrázek se ve fotogalerii
neobjevil, místa na telefonu neubylo, ale v idevicepair pair && ifuse ~/iphone_mnt se objevil se správnou MD5.
Při opakovaném provedení se kopie hromadí.
| Nelze provést, na telefonu není dost místa. |
| Z Documents by Readdle [↑], Save to Files | 0 s | 0 s | 0 s | 0 s | 0 s | Nelze provést, na telefonu není dost místa. |
Výsledné komentáře
- Jedničku s hvězdičkou dostává Internetový archív, GIMP, ImageMagick a G'MIC za vždy korektní a rychlé provedení i při velikosti 31 GB.
- Firmě Apple bych doporučil ať si vezme svoji frázi „it just works“ a jde si udělat domácí úkol v programování. Její produkt reaguje na JPEG korektní podle 30 let starého standardu haváriemi systému ve 3 případech, DoSem v 1 a četnými pády fotogalerie. Všechny mohou znamenat zranitelnost.
- Firefoxu zde byla multiprocesorová architektura Electrolysis platná jak mrtvému zimník (anglicky: jako čajník z čokolády). Kdepak nechal architekt díru?
Knihovna GNU MP (GMP)
1,5 MB knihovna umožňuje práci s velkými čísly, zde jejich přepočítávání mezi 256-kovou a 255-kovou soustavou. Na Raspberry (Debian
Bullseye, Buster) jsem knihovnu ke kompilaci nainstaloval z balíčku libgmp-dev, ale na jiných distribucích se názvy
různí, vypsané jsou na stránce Jpeginsert. V Makefile knihovnu přilinkuji
pomocí LDFLAGS=-lgmp.
Pochopení dokumentace mi trvalo asi 2 hodiny a musel jsem přitom psát testovací program. Jak již to dle mé zkušenosti bývá, dokumentace GNU je bohužel nejednoznačná. Výrok "all the div_ui functions" (všechny ty div_ui funkce) jsem pochopil jako "všechny funkce které mají v názvu div a ui", v tomto výkladu pak dokumentace obsahuje 3 vnitřní spory a není jasné, jak se funkce chovají. Teprve pozorování chování funkcí v testovacím programu odhalilo, že existuje ještě jiná varianta pochopení "pouze ty funkce které mají v názvu podřetězec div_ui nepřerušený", s kterou dokumentace dává smysl.
Performance s base255
Začátek Romerova kultovního trháku (jeden z nejprofitabilnějších filmů do té doby, kasíroval 250násobek rozpočtu) embedovaný v JPEG souboru. Vidíme, jak se kodér vyhýbá bajtové hodnotě 0 a bloky nul kóduje jako bloky jedniček, aby se splnila specifikace JPEGu, že kvantizační tabulky nesmí obsahovat nulové hodnoty.
jpeginsert i vkládá rychlostí 5,9 MiB/s (49 Mbps) JPEG dat,
jpeginsert x extrahuje rychlostí 11,7 MiB/s (98 Mbps) JPEG dat.
Optimalizujeme
Mohlo by se zdát že „pomalost“ je konečná a fundamentální, způsobená aritmetikou: pro každý přesený bajt se musí násobit nebo dělit dlouhé 512-bitové číslo. Program se dá ale zrychlit tak, že nebudeme násobit pro každou číslici 255kové soustavy, ale pro každé čtyři číslice 255kové soustavy, a čtveřice číslic si již rozebereme nebo složíme obyčejnou 32bitovou unsigned aritmetikou. Mocniny 255:
| Mocnina | Dekadicky | Hexadecimálně | Binárně |
|---|---|---|---|
| 2551 | 255 | FF | 11111111 |
| 2552 | 65025 | FE01 | 1111111000000001 |
| 2553 | 16581375 | FD02FF | 111111010000001011111111 |
| 2554 | 4228250625 | FC05FC01 | 11111100000001011111110000000001 |
Místo číslem 255 budeme tedy násobit číslem 4228250625. Po této optimalizaci vkládal jpeginsert Noc Oživlých Mrtvol rychlostí 16,1 MiB/s (135 Mbps) místo 5,9 MiB/s (49 Mbps), tedy zrychlení 2,73×! Kritický kód po optimalizaci vypadal takhle:
unsigned long digits_3210=mpz_tdiv_q_ui(base255, base255, 255UL*255UL*255UL*255UL); putchar(1+digits_3210%255); digits_3210/=255; putchar(1+digits_3210%255); digits_3210/=255; putchar(1+digits_3210%255); digits_3210/=255; putchar(1+digits_3210);
Raspberry Pi 4B má třícestný out of order superskalární pipelining. Nevím, jestli jí budou vadit závislosti mezi následujícími výpočetními kroky. Přepíšu to ještě bez závislostí, zda to pojede rychleji. Počet operátorů dělení a zbytků klesl na 6 ze 7, ale pokud CPU instrukce vrací současně podíl a zbytek, těch počet vzrostl ze 3 na 5:
putchar (1+digits_3210%255); putchar (1+digits_3210/255%255); putchar (1+digits_3210/(255UL*255UL)%255); putchar (1+digits_3210/(255UL*255UL*255UL);
Rychlost byla prakticky stejná. Teď to zkusím ještě rozstromečkovat. Dělicí operátory vůči prvnímu pokusu zůstanou na 6, a CPU instrukce zůstanou na 3:
unsigned long digits_32=digits_3210/(255UL*255UL); unsigned long digits_10=digits_3210%(255UL*255UL); putchar (1+digits_10%255); putchar (1+digits_10/255); putchar (1+digits_32%255); putchar (1+digits_32/255);
Tentokrát Romerův klasický horor kodérem profičel ještě o něco rychleji, 17,4 MiB/s (146 Mbps) oproti předchozím 16,1 MiB/s (135 Mbps), tedy další 8% zrychlení. Celkové zrychlení, kterého jsme touto 4-číslicovou optimalizací dosáhli, je 2,9×.
Optimalizace dekodéru
Analogicky zoptimalizuju dekodér, zde je jen násobení:
unsigned char digit0=buf[digit_pos+0]-1; unsigned char digit1=buf[digit_pos+1]-1; unsigned char digit2=buf[digit_pos+2]-1; unsigned char digit3=buf[digit_pos+3]-1; unsigned long digits3210; digits3210=digit0+255UL*digit1+255UL*255UL*digit2+255UL*255UL*255UL*digit3; if (digits3210>=255UL*255UL*255UL*255UL) digits3210=0; /* Protect robustly (without stopping decoding) against damaged data */ mpz_mul_ui(base255, base255, 255UL*255UL*255UL*255UL); mpz_add_ui(base255, base255, digits3210);
Teď se Oživlé Mrtvoly ze souboru vyvalily rychlostí 22,7 MiB/s (190 Mbps), o 94% rychleji než původně!
Přehrávání videa přímo z JPEGu
930 MB JPEG notld_movie.jpg jsem na rozdíl od ostatních nevystavil z důvodu komplikovaného mezinárodního autorského práva: v zemi kde jsem, film ještě není v public domain.
Vytvořil jsem si k filmu 175 kB JPEG poster (title_card.jpg), do kterého jsem film embedoval a vznikl 930 MB JPEG
(notld_movie.jpg). Vidíme, že G'MIC 930 MB JPEG s embedovaným filmem normálně načte (vlevo). Vpravo: extraktor extrahuje
720p HD film z JPEG souboru a posílá ho na stdout, kde ho v reálném čase přehrává MPV.
3,8 MB JPEG soubor 1280x720 s hudbou jsem postnul na svůj Facebook jako obrázek bez komentáře.
| Původní obrázek bez zakódovaných dat | 79132 | 1280x720 | Neobsahuje data |
| Původní obrázek se zakódovanými daty | 3791575 | 1280x720 | Obsahuje data |
| Preview obrázek na facebookové stránce | 33283 | 960x540 | Neobsahuje data |
| Obrázek který se zobrazí po kliknutí a má identický název souboru | 70399 | 1280x720 | Neobsahuje data |
| Obrázek který se zobrazí po kliknutí na "Download" a má identický název i obsah jako ten co se zobrazí po kliknutí | 70399 | 1280x720 | Neobsahuje data |
File
Program file na těchto obrázcích nezobrazuje jejich rozměry, a to i tehdy když je v nich zakódováno pouze 3,7 MB dat:
../lullaby_card.jpg: JPEG image data, JFIF standard 1.01, resolution (DPCM), density 28x28, segment length 16, baseline, precision 8, 1280x720, components 3 ../lullaby_with_audio.jpg: JPEG image data
Závěr
Doufal jsem v možnost ukládat libovolná data na platformách které povolují pouze JPEG obrázky, jako fotogalerie smartphonů, některá sociální média, různé systémy které filtrují určité datové typy atd. To se částečně splnilo: do fotogalerie iPhonu se dají prakticky uložit až soubory zhruba gigabajtové.
Kvalita existujícího softwaru obecně je ale nízká a často nezvládá velké korektní JPEG soubory. Někdy dochází k agresivnímu překódování a odstranění vložených dat. Proto si myslím, že vhodnost bude k vložení menších až středně velkých souborů, skrytí souborů proti zběžné inspekci a nebo obejití filtrování datových typů.
Zdá se, že pokud potřebujeme v souladu s autorskými právy veřejně zdarma hostovat soubory o libovolném typu a velikosti i desítek gigabajtů, snadno použitelný, poměrně necenzurovaný a o dlouhověkost se snažící je Internet Archive. Ale i ten si vyhrazuje právo obsah bez udání důvodu mazat.





