2026/08/28

PNG autopsy III

A következőkben a Filterezés támadását tovább gondoljuk és saját filtereket találunk ki. Érdemes az előző bejegyzéssel alapozni, ha nem onnan jöttél. 

Tehát azt már tudni véljük, hogy a PNG 5 filterétől eltérő (más irányokból is építkező) filterek alkalmazásának nincs pragmatikus vonatkozása, de ez nem jelenti azt, hogy nem kísérletezhetünk vele.
Már van olyan eszközünk (köszi Ai, vagy ti mindannyian, akik drágább memória árakkal fizetitek ezt helyettem, vagy az utókornak, akinek ezzel éljük fel a jövőjét), amelyik képes olyan PNG-ket menteni (csak RGB8 semmia alfa és semmi interlace), ahol a scanlineokra kötelezően általunk választott filtert alkalmaz, csak annyit kell hozzáprogramozni, hogy saját algoritmusokat is tudjon kezelni. Ezeknek mondjuk a filter byte-ját 5-6-7 és így tovább, írná bele a képbe, amitől egy normális képnézegető egyből hülyét kap, például a Photoshop, hiszen nem ismert Filtert nem tud használni. De például az Irfan (sőt a windows file explorer nézete) nem esik kétségbe, látszólag az összes nem értelmezhető filterű scanlinet None-nak tekint és megjeleníti. De van olyan eszközünk is, ami adott scanline típus-byteokat el tud hazudni. Az ilyen Custom filterezett képeinknek itt tudunk valid filter-byteot beállítani, ezután már minden képnézegető meg fogja nyitani a képünket a kiválasztott algoritmus szerint, ami természetesen a glitchet fogja okozni.

Három Custom filterrel próbálkoztunk, remélve a szebbnél szebb glitch mintázatokat. Amit ha nem is sikerült elérni, de tapasztalatokat azért szereztünk. Fontos, hogy ezeknél a teszteknél az előző bejegyzésben is említett kis segédprogramunkat használjuk, ami minden scanlinra ráerőlteti ugyanazt a filtert.

Custom1 -- Körkörös prediktor (mind a 8 szomszéd átlaga) - ami körbe minden pixelt figyel, vagyis 4 már elkódoltat a szokásos irányból (balsó, felső irányok), és négy pixelt a jobbra és alul elterülő részről, aminek ekkor még nem tudhatjuk az értékét, elkódolásnál azért, mert még nem kódoltuk el, kikódolásnál azért, mert még nem kódoltuk ki (ha nem világos, tényleg menj vissza az előző posztra). Nyilván emiatt egy ilyen filterrel elkódolt kép nem invertálható (dekódolható) egyszerű szekvenciális dekódolással, de most ez nem is cél, hiszen a Glitch okozására hajtunk, ezért csak ENCODE-ra használjuk.

Custom2 -- RGB-Average (csatornánként MÁSHOVA néző prediktor) - vagyis
- R csatorna <- bal szomszéd R csatornája
- G csatorna <- balsó-fenti szomszéd G csatornája
- B csatorna <- fenti szomszéd B csatornája
Ez az algoritmus elvileg ENCODE-ra és DECODE-ra is használható, hiszen csak valid irányokból veszi az adatot.

Custom3 -- InverseAverage (jobbra / lent szomszédok átlaga) - itt minden hivatkozás jövőbeli, tehát későbbi feldolgozású pixelre mutat, ENCODE-ra tökéletesen használható, de DECODE-ot csak fordított irányban lehetne végrehajtani rajta, tehát ha a jobb alsó pixeltől indulva visszafelé zajlana a dekódolás.

És így néznek ki a Custom Filterekkel elkódolt, de valós Filtereknek (azokkal kikódolt) hazudva:



Emlékeztetésnek és összehasonlításnak (az előző bejegyzésből átemelve),  a valós filterek egymás között elhazudva így néztek ki:

Kis felbontású és JPG-nek mentett nézet, az eredeti jóval gazdagabb.


Az eredmény érdekes, de sajnos nem a reményeink szerint való, azt vártuk volna ugyanis, hogy a merőben eltérő encoder filtereink merőben eltérő hatásokat fognak produkálni, rosszabb esetben annyira összeborzolják a képet, hogy az felismerhetetlenné válik. Ezzel szemben a kikódolásra használt filter hatása a domináns, tehát például egy UP függőlegesen vonalas, egy Average átlósan, stb, és egyáltalán nem felismerhetetlen a kép sem. 

Ezen a ponton végleg el kellett fogadnunk, hogy a végső, meg-glitchet kép zajmintázatát, a glitch geometriáját leginkább nem az határozza meg, hogy eredetileg milyen filterrel volt elkódolva, hanem jellemzően a kikódoló algoritmus. Tehát hiába találunk ki bármilyen irányú, csillag alakú, hatszög, stb. saját-filtert, a végeredmény mégis a kikódoló filter jellegzetességeit fogja mutatni. 

De hogyan lehetne megnézni egy (bármilyen filterezésű) képet a saját filterrel kikódolva, amikor nincs a földön olyan képszerkesztő, amelyik ismerné a mi saját filterünk algoritmusát?  Na erre is írattunk egy python progit a mesterséges intelligenciával, ami bármilyen filterezésű bemeneti képet egy saját filterrel próbál értelmezni. A saját filternek azt választottuk, amelyik a pixel összes (körben mind a 8) szomszédjának átlagával dolgozik, és ugyanúgy, balról jobbra, fentről lefelé járja be a képet. Ilyenkor értelemszerűen az adott pixel kikódolásakor a 8 szomszédból csak négynek (balra és felül található) az értéke ismert, a többi négynek (jobbra és alul található pixeleknek) az értéke még nincs kikódolva. Ez fogja okozni  a glitchet. Ezt egy kis parancssoros pythonnal értük el, ami annyit csinál, hogy bármilyen filterezésű bemeneti képet a mi saját filterünkkel kódol ki, majd az egyszerűség kedvéért sima bmp-nek ment.


Azt vártuk, hogy olyan zaj-katyvaszt kapunk, hogy a fal adja a másikat, ezzel szemben meglepődtünk. Egyrészt igazolódott, hogy mindig a kikódoló filter karakterisztikája lesz a domináns a glitchelt képen. Vagyis közelről megnézve pontszerű (pointilista-szerű) zaj keletkezik, ami nem meglepő hiszen egyes pixelek értéke minden irányból származik, nincs kitüntetett irány. Ugyanakkor az is látszik, hogy az elkódoló filterek is rányomják, bár sokkal csekélyebb mértékben, a kézjegyüket a végleges glitchre. Érdemes megfigyelni, hogy az eredetileg Sub-nak kódolt, majd Customnak kikódolt képen a nagyobb felületek élei dominánsan függőlegesek, míg az Up-nak elkódolt és Customnak kikódoltak esetében vízszintesek. Az Average filterrel elkódolt és Custommal kikódolt képeknél, az összefüggő felületek alsó-jobboldali élei dominánsak. Külön meglepett, hogy a Paeth elkódolás, ami mindig borzalmas kristályszerű szín-glitcheket okozott, itt egyáltalán nem mutatta a szivárványos geometriáit. 

A további 3 kép, amikor az elkódolás során három saját filtert használtunk, külön érdekes. A bejegyzés elején felsoroltuk ezeket a saját filtereket, a C1 az maga a körkörös, amit a kikódolásra is használunk (C1 - C1). Természetesen nem tudja visszaadni az eredeti képet glitchmentesen, hiszen említettük, hogy a 8 szomszédos pixel értékéből, amiből építkezik, 4 értéke nem ismert. Egyfajta edge-detection hatást vélünk felfedezni itt. A C2-C1 esetében az elkódolás során a második saját filterünket próbáljuk kikódolni az első saját filterünkkel, egyszerűsítve, a C2 az RGB értékeinek eltérését három szomszédjától veszi, a pirosat a baltól, a zöldet a bal felsőtől, a kéket pedig a felsőtől.)
A C3-C1 meg hasonló, de itt a C3 egy inverz Average filter, vagyis jobboldali és alsó szomszédaiból építkezik (gyakorlatilag mindkét szomszédja ismeretlen a kikódolás balról és fentről bejárása miatt), ezért látszik úgy, mintha a zajban az edge-detection fordított irányú lenne az Average-C1-hez képest. 

Na így. A programokat, szkipteket elküldöm annak aki kéri, de nem látom értelmét ide felpakolni a blogra, mert valószínű, hogy az elkövetkező 10 évben nem lesz több érdeklődő mint 0.


Nincsenek megjegyzések:

Megjegyzés küldése