Egy kis újabb csemege a bitpornó kedvelőinek :-)
Nem tudom, hányan ismeritek a Quite OK Image képformátumot. A lényege, hogy eszeveszettül faék egyszerű, mégis egész jó tömörítési rátát képes produkálni (a honlapja mondjuk hazudik, speciálisan kézzel összeválogatott képen demózza). Viszont volt benne pár dolog, ami mindig is zavart (például hogy nem képes transzparens képeket tömöríteni), ezért feltúrbóztam kicsit:
Fícsörök:
- ugyanúgy egyetlen függőség nélküli fejlécfájl, mint az elődje (kb. 200 SLoC a kicsomagoló-becsomagoló együtt)
- ugyanúgy MIT licenszű, Szabad és Nyílt Forráskódú
- azonban ez sokkal gyorsabb, pláne nagy képek esetén
- ráadásul sokkal jobban tömörít (különösen anti-aliasolt képeket)
A sebességnövekedés amiatt van, hogy mutatókat és switch/case-t használ bájttömbindexek és if/else blokkok helyett, egyébként ugyanaz a logika, nincs benne semmi trükk. A jobb tömörítési rátát pedig úgy éri el, hogy okosabban osztja ki a biteket, a legtöbb utasítás ugyanaz, de a futásidejű tömörítésre van egy hosszabb futamot is tárolni képes opció, a differencál utasításoknál van egy olyan, ami alfát és nagyobb tartományt képes leírni, a teljes csatornát tároló utasítás pedig csak a megváltozott csatornákat tárolja az összes helyett. Röviden.
- 1078 megtekintés
Hozzászólások
Szuper! Megneztem az algoritmust, de ez leginkabb csak rajzokra jo (ahol sok pixel pont ugyanolyan szinu), foto jellegu kepeknel szerintem ez nagyobb lesz mint BMP-ben :)
A PNG-ben vannak filterek amik differencialnak akar az elozo pixel sorhoz is, es az eredmenyt huffman kodolja, az se kozeliti a jpeget, de azert az fotoknal is hatasos valamennyire.
En 20 eve jpeg-bol csinaltam egy sajat egyszerusitett verziot ami YUV helyet RGB-t tarolt, gyorsan lehetett parsolni (huffman/idct megvolt de a jpeg-fele markereket es egyeb bonyolitast kihagytam teljesen) es tamogatott alpha-t is, megpedig ugy hogy blokkonkent (8x8 pixel) tarolta 1 biten hogy van-e atlatszosag/alpha, a 0=nem (RGB volt tarolva csak) es ha 1=igen akkor a kovetkezo biten hogy teljesen atlatszo-e a blokk (ilyenkor nem is tarolt mast) vagy csak reszben, akkor RGBA data jott. igy a dekoder tudta optimalizalni blokkonkent a blendinget, csak a reszben atlatszoknal kellett a hatterrel mixelnie, kulonben vagy siman felulirta a hattaret vagy beken hagyta teljes egeszeben. mivel a blokkok max 5-10%-a volt reszben atlatszo ezzel sok cpu idot nyertunk. meg azzal is hogy a hatternel nem kellett semmit dekodolni meg blendelni/irni, csak atugrani.
- A hozzászóláshoz be kell jelentkezni
de ez leginkabb csak rajzokra jo (ahol sok pixel pont ugyanolyan szinu)
Nem. Valóban van benne run-length encoding is, de a lényegi tömörítést a LUMA és RGBA csatorna differenciál kódolás adja.
foto jellegu kepeknel szerintem ez nagyobb lesz mint BMP-ben :)
Faszt. Ott van a klasszikus Lena példakép, fotó jellegű, felére tömörítette: 256K helyett csak 137K. De tény, hogy fotó jellegű képeknél QOI 1.0 szintjén van, elsősorban transzparens hátterű, anti-aliasolt képekhez lett kitalálva. Azoknál közel PNG szinten van a törmörítési rátája, ugyanakkor milliószor gyorsabb kicsomagolni annál. De a képtől is függ, a Kurisu példakép például kissebb QOI-ben, mint PNG-ben.
A PNG-ben vannak filterek amik differencialnak akar az elozo pixel sorhoz is, es az eredmenyt huffman kodolja, az se kozeliti a jpeget, de azert az fotoknal is hatasos valamennyire.
A PNG sem remekelt sokkal jobban Lénán, az a 256K-ból 109K-t csinált, de cserébe nagyságrendekkel tovább tart kicsomagolni (mármint SOKKAL), pont a Huffman és a filterek miatt és nem is írod meg 100 SLoC-ból.
igy a dekoder tudta optimalizalni blokkonkent a blendinget
Már bocs, de ennek semmi értelme. Mégis melyik kódban kell a dekódernek blendingelnie??? A legtöbb szoftverben ezek teljesen külön rétegben vannak (dekóder a fájlekezésnél, blending meg a view rétegben fordulhat elő), egyetlen közös kódsoruk sincs.
Csak hogy tisztázzuk: az eredeti QOI codec Dominic Szablewski találmánya, az én hozzájárulásom a QOI 2.0-ával csak annyi, hogy ez képes anti-aliasolt képeket is jól tömöríteni. Ha megnézed az eredeti QOI specifikációt (1 oldal csak), akkor láthatod, hogy az egyetlen utasítás, amivel alfa csatorna értéket lehet váltani, az bizony 5 bájtos. Nem véletlen, hogy a QOI honlapján lévő tesztképek között egyetlen egy transzparens sincs... Na ez nekem nagyon nem tetszett, mivel a legtöbb ikon az biza transzparens hátterű, alfa átmenetekkel az ábrák szélén, és ezeken csúnyán elvérzik az eredeti QOI. Csak ezért írtam meg a QOI 2.0-át, hogy az ilyen képeket is kezelje. A nem transzparens, fotó jellegű képeknél a tömörítési arány kb. azonos az eredeti QOI tömörítési arányával.
- A hozzászóláshoz be kell jelentkezni
> Ott van a klasszikus Lena példakép
hat az mar 30 eve is ott volt, emlexem azon (is) teszteltem az ESP nevu tomoritomet akkoriban... ami par honapig vezette is a keptomoritesi versenyt...
> és nem is írod meg 100 SLoC-ból
ez teny... nyilvan van ahol fontos az egyszeruseg (maga a SLOC ritkan szamit valojaban)
> Mégis melyik kódban kell a dekódernek blendingelnie?
hat az enyemben!!! :) ipari embedded pc ami kb 10 evvel volt lemaradva, talan 200mhz via cpu szar lassu vrammal, nagyon keves rammal kellett sok atlatszo grafikai elemet megjelenitsen. ahhoz hogy elferjen minden kellett min jpeg szintu tomorites. es direktbe a vram-ba dekodoltam, mert ezzel sok idot lehetett nyerni.
> mivel a legtöbb ikon az biza transzparens hátterű
ezzel kellett volna kezdened, hogy ez kis ikonokra valo, arra el hiszem hogy jobb akar meg a png-nel is, ha csak par 100 pixeles.
- A hozzászóláshoz be kell jelentkezni
Sajnos ezt most elkapkodtad. Már indításból nincs Makefile, ezzel már el is űzted a potenciális felhasználók 90%-át. Az sem igaz, hogy függőség nélküli, mert igényli a png.h-t (libpng).
Továbbmenve teszteltem mindenféle háttérképpel, és a legtöbbet sokkal nagyobbra tömörítette össze, mint az eredeti .png fájl volt. Egyedül csak akkor tömörített jobban, mint egy png, ha a képen sok azonos színű pixel volt egymás mellett, ahogy a kolléga írta felettem, a rajzolt, mesterséges képek, UI screenshotok fekszenek neki.
A QOA viszont tetszik, de nem teszteltem még eleget.
“The world runs on Excel spreadsheets.” (Dylan Beattie)
- A hozzászóláshoz be kell jelentkezni
Sajnos ezt most elkapkodtad.
Súlyos tévedésben leledzel, nem ártana elolvasni a README-t vagy a forráskód legtetején a kommenteket, ugye...
Már indításból nincs Makefile
Soha, egyetlen stb single header library-hoz sincs, mert nem is lehet. Nincs mit lefordítani, egy fejlécfájl csupán, amit csak "#include"-olni kell.
Az sem igaz, hogy függőség nélküli, mert igényli a png.h-t (libpng).
Lófasz kell neki, nem a libpng. Az csak a konvertálóknak kell, azok ugyanis PNG-ből vagy PNG-be konvertálnak, ugye és hát ahhoz biza köll a libpng... A QOI / QOI 2.0 függvénykönyvtárakhoz NEM kell. De ha írsz egy konvertálót, ami PPM-et használ, vagy mondjuk az stb_image.h fejlécfájlt, akkor ahhoz sem fog kelleni a libpng.
A konvertálók fordítása meg egyébként (ott van leírva a kommentben, mindjárt a fájl legtetején) a legprimitívebb egysoros, gcc qoi2enc.c -o qoi2enc -lpng, ehhez felesleges a Makefile.
De direkt a kedvedért csináltam egyet.
Továbbmenve teszteltem mindenféle háttérképpel, és a legtöbbet sokkal nagyobbra tömörítette össze, mint az eredeti .png fájl volt.
Ejnye, de nem erősséged az olvasás. Sosem állítottam ezt. Igen, a PNG jobban tömörít, cserébe SOKKAL lassabb és sokkal több erőforrást (memóriát és CPU-t) zabál. Le van írva feketén fehéren:
- a repó README legelején: It is extremely small (~200 SLoC), super-duper fast to decode, yet it provides just slightly worse compression ratios than PNG (slightly worse != jobb lenne)
- samples/README-ben: In general PNG still compresses better, but requires considerably more (I mean, by magnitudes more) CPU time to decode
- eggyel korábbi hozzászólásomban is leírtam: közel PNG szinten van a törmörítési rátája, ugyanakkor milliószor gyorsabb kicsomagolni annál (közel != hogy mindig jobb)
Itt a hangsúly azon van, hogy baromi gyors, csak egy kis statikus memóriát eszik, ehhez képest mégse rossz a tömörítési rátája. Mindig is erről szólt a QOI, és ez nincs másként a QOI 2.0-ában sem.
Egyedül csak akkor tömörített jobban, mint egy png, ha a képen sok azonos színű pixel volt egymás mellett, ahogy a kolléga írta felettem, a rajzolt, mesterséges képek, UI screenshotok fekszenek neki.
Mármint most az eredeti QOI-ról beszélsz, ugye? Igen, az ilyen, az egyáltalán nem képes anti-aliasolt transzparens képeket tömöríteni, mint a QOI 2.0. Pont emiatt csináltam.
Tipikus példa erre a samples/pnglogo: ez PNG-ben 311K (nyilván ez a legjobban törmörített), ez az eredeti QOI-ban 406K, az én QOI 2.0-mmal meg 377K. Az még mindig több, mint a PNG, ugyanakkor SOKKAL jobb, mint az eredeti QOI, 10%-ot ráver. A többi példaképnél is hasonló az eredmény, a legrosszabb a Lena, amin egyáltalán nincs egyetlen transzparens pixel se, az csak ~400 bájttal kissebb. De ezt is írtam már, hogy ilyen esetben azonos a rátája az eredeti QOI-val.
- A hozzászóláshoz be kell jelentkezni
Továbbra sem értek egyet. Kell Makefile, ahhoz, hogy az érdeklődök normálisan és könnyen ki tudják próbálni. Mert hiába az 1 szál .h headerfile, ha nem tudja kipróbálni, be fogják zárni a fület, és többet nem néznek rá. A jó dokumentációt ne becsüld alá, sokszor majdnem olyan fontos, mint a kód maga. El sem hiszed, hogy a legtöbben nem tudják lefordítani, ha nem adsz makefile, vagy m4/cmake/meson, vagy akármilyen más buildtool által támogatott könnyítést hozzá, Windowson meg milyen fontos a VS project file. A Rust-ot is hiába utáljuk, ott is a népszerűségének a fele nem is a nyelv maga, hanem a cargo, ami a sok idiótának leegyszerűsíti a dolgát, frissít, beemel, belefordít minden függőséget, egy lépésben, ezt a fajta kényelmet a legtöbb dev jobban értékeli, mint az te gondolnád.
Igen, a readme.md-ben ott van, hogy include-olni kell, de az ugye 0 segítség, amíg az ember ki sem tudja próbálni. Nyilván, én ki tudtam, mert hozzá vagyok szokva ehhez a lyukkártya szintű minimalizmushoz, hogy mindenért én gépelgetek, meg kiderítek függőségeket, meg ismerem a folyamatot, de akkor sem keltett sok bizadalmat.
Mondom, nem pocskondiázni akarom, de a kommentedben is túltoltad a marketinget, mert a QOI 1-et úgy vázoltad, hogy a PNG-vel egyenértékű tömörítés, a QOI 2-őt, meg hogy jobban tömörít, innen meg az ember összekapcsolja azzal, hogy akkor a PNG-nél is jobban fog. Most már értem, hogy csak a QOI 1-nél tömörít jobban, de elismerheted, hogy ez így erősen félreérthető. Azért tisztáztam csak.
“The world runs on Excel spreadsheets.” (Dylan Beattie)
- A hozzászóláshoz be kell jelentkezni
Én nagyon nem szerezem bzt-t, direkt nem is kommentelek a topikjaidba, de szerintem álmában több sor kódot ír, mint te egész életedben, úgyhogy kivételesen abbahagyhatnád a fogalom nélküli szakértést.
- A hozzászóláshoz be kell jelentkezni
Ja, az nagyon jó is lenne, ha nem írnál olyan topikba. Nem azért, mert bzt-é, hanem ha nem tudod miről van szó, akkor ne szóljál bele. Itt pont, hogy most nem arról volt szó, hogy 1) kinek a farka nagyobb, 2) ki írt több kódot, 3) kinek a faterja tudja leverni Chuck Norrist. Ehelyett én arra akarom rávezetni, hogy ha nem magának írogatja csak a kódot, hanem azt akarja, hogy mások is használják, akkor sajnos kell a dokumentáció, meg a jobb bemutatása a projektnek. Mert az, ami neki egyértelmű, meg nem tűnik fontosnak, azzal mások simán ellenkezőleg fognak állni.
Mint írtam, azzal sincs baj, ha nem versenytársa a QOI 2 a PNG-nek, csak akkor ezt normálisan hangsúlyozni kell, hogy ne legyen félreértés.
“The world runs on Excel spreadsheets.” (Dylan Beattie)
- A hozzászóláshoz be kell jelentkezni
hat pedig "felig" igaza van. az elso dolog amit egy cuccnal nezek az az examples: az mutatja meg mennyire bonyoult a hasznalata, abbol tudom meg hogy kell hasznalni (a doksi tul rizsas, mar amikor van :D, amikor nekem csak egy kis valami kell). 'szom akar kodban tudni hogy rajojjek hogy is kene pontosan hasznalni. szoval ha nem is egy makefile, de 1-2 pelda kell (gcc -o teszt1 examples/test1.c).
A vegtelen ciklus is vegeter egyszer, csak kelloen eros hardver kell hozza!
- A hozzászóláshoz be kell jelentkezni
Nem értem.
az elso dolog amit egy cuccnal nezek az az examples
Itt most az a gondod, a példafájlok könyvtárát nem "examples"-nek, hanem "samples"-nek neveztem? Vagy nem értem.
'szom akar kodban tudni hogy rajojjek hogy is kene pontosan hasznalni
Miért kéne turkálnod? Inkább a README-t kéne elolvasni. Mindjárt a repó README legelején egy nyúlfarknyi 5 soros "mégis mi a fasz ez" bevezető után máris jön az "Usage", a teljes API dokumentációval, de idemásolom a kedvedért:
In exactly one of your source files, define QOI2_IMPLEMENTATION and include the header:
#define QOI2_IMPLEMENTATION
#include "qoi2.h"To provide your own malloc(), you can define QOI2_MALLOC (free() and memset() not used by QOI2). You can also define QOI2_DECODER_ONLY or QOI2_ENCODER_ONLY to configure which parts to include (by default both included).
The library has only two API functions:
uint32_t *qoi2_decode(const uint8_t *buf, int *w, int *h, int size);
Uncompress a QOI 2.0 stream of size bytes into a newly allocated 32 bit pixel buffer, returns its dimensions in w and h. It is the caller responsibility to free the returned buffer when they're done using it.
uint8_t *qoi2_encode(const uint32_t *buf, int w, int h, int *size);
Compress a 32 bit RGBA pixel buffer of w x h pixels, returns a newly allocated QOI 2.0 stream buffer and its size in size. It is the caller responsibility to free the returned buffer when they're done using it.
Ennyi. Nincs több függvény, csak ez a kettő, és define-ból sincs több, csak az a négy. Faék egyszerű.
- A hozzászóláshoz be kell jelentkezni
a példafájlok könyvtárát nem "examples"-nek, hanem "samples"-nek neveztem
igen, ebben a konyvtarban csak kep fajlok vannak nem forraskodot. csak kozben megneztem hogy a qoi2dec.c es qoi2enc.c fajloknak kene ott lennie, mert ezzel lehet kiprobalni mit tud. eloszor azt hittem az a project resze. csak ennyi volt a readmeben: "Take a look at qoi2enc.c and qoi2dec.c for examples." jol elbujt. :/
A vegtelen ciklus is vegeter egyszer, csak kelloen eros hardver kell hozza!
- A hozzászóláshoz be kell jelentkezni
eloszor azt hittem az a project resze
Az, de ha beépíted a QOI2-t egy programodba, akkor nincs rájuk szükség, mint ahogy a libpng függőségükre sem.
csak ennyi volt a readmeben: "Take a look at qoi2enc.c and qoi2dec.c for examples." jol elbujt. :/
Hát mert annyira faék egyszerű, tényleg nincs értelme többet beszélni róla. Itt a forráspélda, tényleg csak ennyi:
/* decode QOI2 to pixel buffer */ if(!(pixbuf = qoi2_decode(qoibuf, &w, &h, size))) { free(qoibuf); fprintf(stderr, "unable to decode QOI2\n"); return 1; } free(qoibuf);
A többi már csak standard fájl beolvasás meg png-be kódolás, aminek nincs köze a QOI2 függvénykönyvtár használatához.
- A hozzászóláshoz be kell jelentkezni
bzt ambivalens figura. Egy igazi zseni, imádom a szigorúan technikai hozzászólásait. Ugyanakkor tuti küzd valamilyen disorderrel, és nem-technikai témákban néha hajmeresztő dolgokat produkál. Egyesek számára ez ijesztő lehet. Szerintem kár leírni valakit pusztán a tökéletlensége és a gyengeségei miatt.
Számomra inkább szimpatikus, ugyanakkor tudom, hogy nem-technikai témákban kár vitákba belemenni vele. Nem a megértés szándékával lép fel, nem is tudom, képes-e egyáltalán más nézőpontot megvizsgálni. De ez nem teszi semmissé az erősségeit. (Másnak meg más defektusa van - bizonyára magamnak is van egy pár.)
- A hozzászóláshoz be kell jelentkezni
nem-technikai témákban néha hajmeresztő dolgokat produkál.
Tudnál példát mondani?
nem-technikai témákban kár vitákba belemenni vele
Miért? Az igaz, hogy eddig akárhányszor próbáltak meg a tisztelt fórumtársak lehülyézni, mindig kiderült utólag, hogy nekem lett igazam és ők tévedtek. De ez nem azért van, mert szuperman lennék, hanem mert alaposan utánnajárok a dolgoknak, mielőtt egy kijelentést tennék, és nem köt gúsba a predesztináció, ha logikusan jutottam egy érvre, akkor elfogadom azt, bármennyire is hajmeresztőnek hangozzék.
De ettől még lehet vitatkozni velem, csak épp értelmes stílusban, az állításai indoklásával és alátámasztásával érvelve, nem pedig köcsögparaszt TROLL stílusban.
Nem a megértés szándékával lép fel
Hát, ha valaki azzal próbál meg érvelni, hogy "csak mert", vagy épp "buta vagy, hogy nem tudod", na az ilyeneket valóban emberszámba sem veszem és nem szándékozom megérteni.
nem is tudom, képes-e egyáltalán más nézőpontot megvizsgálni
Sőt, mire a poszot írom, már meg is vizsgáltam őket. Alaposan indokolni kell, remélhetőleg forrásmegjelöléssel, és akkor odafigyelek. Ennyire egyszerű. A vélemény nem nézőpont amíg nincs alátámasztva, hanem csak egy vélemény, kb. mint a lapos-föld.
Másnak meg más defektusa van
Úgy bizony. Rengetegen szenvednek abban, hogy bedőlnek a fake news-nak, nem tűnik fel nekik a sok önellentmondás, és képtelenek hosszú távon látni az egyes dolgok következményeit. Ez sajnos a többség, homo ludens, nem homo sapiens.
- A hozzászóláshoz be kell jelentkezni
A header libeket pont hogy egyszerűbb kipróbálni, mint bármit amihez Makefile van adva. Bepasztázod a projektedbe, inklúdolod és hajrá. Én éppen azért is használtam egy projektben, mert ennyire egyszerű. A projekt multiplatform volt, Linuxra és Windowsra is kellett fordítani. Pont ugyanúgy kellett megcsinálni a két platformon. Ezt a legegyszerűbb használni, aki ért hozzá direkt ilyet keres.
Ja, és ez eleve egy header only lib volt, nem bzt csinálta ilyenné.
- A hozzászóláshoz be kell jelentkezni
Továbbra sem értek egyet. Kell Makefile
Továbbra is nehezedre esik olvasni. "De direkt a kedvedért csináltam egyet." Amikor ezt a posztot írtad, már volt.
a kommentedben is túltoltad a marketinget, mert a QOI 1-et úgy vázoltad, hogy a PNG-vel egyenértékű tömörítés,
SOHA nem állítottam ilyent. SŐT, felhívtam rá a figyelmet, hogy a QOI honlapja hazudik ez ügyben. Az én README-mben egész konkrétan ez áll: "slightly worse compression ratios than PNG".
a QOI 2-őt, meg hogy jobban tömörít
Ezt valóban állítottam (mármint hogy jobb, mint az eredeti QOI, nem azt, hogy jobb lenne, mint a PNG!!!), és azt is, hogy főleg transzparens képek esetén dolgozik jobban. Direkt írtam, fotó jellegű képeknél a tömörítési rátája közel azonos az eredeti QOI-val, egy icipicit jobb csak. (Fotó jellegű alatt azt értem, alfacsatorna mentes.)
- A hozzászóláshoz be kell jelentkezni
Hogy nagyon egyértelmű legyek:
Ez a topik nem a PNG és QOI viszonyáról szól, hanem a QOI és QOI 2.0 közötti különbségekről.
- A hozzászóláshoz be kell jelentkezni
A QOI-ban a pláne az, hogy nagyon gyors. A tömörítés teljesítménye nem jobb a PNG-nél, de sokkal gyorsabb. Legalábbis a libpng-nél biztosan - vannak optimalizáltabb png tömörítők is. Én olyat csináltam vele, hogy egy embedded device szimulátorban az összes kirajzolt képkockából "videót" csináltam vele - azaz az összes képkockát letároltam - és QOI-val megy real time-nál gyorsabban, libpng-vel meg real-time se ment.
Moddoltam is a QOI-t én is: azt, hogy a futamhossz nagyobb is lehessen én is megcsináltam. A képernyő képkockáinak diff alapú streameléséhez kellett, mert amikor a legtöbb pixel 0, akkor több kb helyett néhány bájt az eredmény. Egy VNC-hez és RRFB-hez hasonló remote desktop megoldást csináltam vele, ami meglepően jól működik böngészőben is. A másik mod amit csináltam, hogy a kitömörítés JavaScriptes megvalósítása egyből diff-ként tömöríti ki, azaz az előző kockához adja a pixel értéket. Ezáltal a képernyő differencia enkódolt sztreamjét sokkal kisebb RAM sávszélességgel lehet kikódolni és a kliens használható teljesítményt ad 1920x1080 felbontásban több mint 10 éves vason is.
- A hozzászóláshoz be kell jelentkezni
A tömörítés teljesítménye nem jobb a PNG-nél, de sokkal gyorsabb
Ezért írtam, hogy hazudik a honlapja, mert az valóban azt állítja, hogy a PNG szintjén van, és ezt szintetikus tesztfájlokkal igyekszik demonstrálni, amik között egyetlen transzparens sincs, és direkt olyanok, melyek tömörítésével küzködik a PNG. A sebessége (valamint hogy csak 60 SLoC a kicsomagoló) viszont valóban figyelemreméltó.
Moddoltam is a QOI-t én is: azt, hogy a futamhossz nagyobb is lehessen én is megcsináltam. A képernyő képkockáinak diff alapú streameléséhez kellett, mert amikor a legtöbb pixel 0, akkor több kb helyett néhány bájt az eredmény.
Nekem szprájtlapokhoz kellett, azokon is rengeteg a 0 pixel, mivel fix pozíciókon vannak a figurák rajta, pl ennél. A másik meg, hogy ezek mindig anti-aliasoltak, azaz tele vannak alfacsatorna átmenettel.
- A hozzászóláshoz be kell jelentkezni
Egy kis érdekesség: eredetileg úgy írtam meg, hogy a csomagokban az adatbitek mérete változó lehet (VBR, azaz nem biztos, hogy a csomagok mindig bájthatárra esnek). Ez lassít ugyan, de feltételeztem, sokkal jobb tömörítést jelent majd. Az overhead minimális volt, a bitkicsomagoló O(1)-es volt, a következő:
#define POP_BITS(v, n) do{ v = (*((uint32_t*)src) >> off) & ((1 << (n)) - 1); off += n; src += off >> 3; off &= 7; }while(0)
(Cserébe +3 bájtnyira kellett allokálni a buffert, hogy az utolsó bájtból is tudjon olvasni)
Kigeneráltam az összes lehetséges bitméretet preset-ekbe, majd ráeresztettem többezer példaképre (amit csak találtam a vinyómon, szprájtlapok, ikonok, családi fotók, háttérképek, stb.), és mindnél megnéztem, melyik preset tömörítette be a legjobban. Az eredmények:
preset 0 1821 is 6 hs 2 ds 2 gs 4 vs 2 preset 1 97 is 7 hs 2 ds 2 gs 4 vs 2 preset 2 77 is 8 hs 2 ds 2 gs 4 vs 2 preset 3 11 is 9 hs 2 ds 2 gs 4 vs 2 preset 4 10 is 6 hs 2 ds 3 gs 4 vs 2 preset 12 4 is 6 hs 2 ds 4 gs 4 vs 2 preset 14 1 is 8 hs 2 ds 4 gs 4 vs 2 preset 19 1 is 9 hs 4 ds 4 gs 4 vs 2 preset 20 16 is 6 hs 4 ds 4 gs 4 vs 2 preset 22 1 is 8 hs 4 ds 4 gs 4 vs 2 preset 28 35 is 6 hs 2 ds 2 gs 5 vs 3 preset 29 17 is 7 hs 2 ds 2 gs 5 vs 3 preset 36 2 is 6 hs 3 ds 3 gs 5 vs 3 preset 38 1 is 8 hs 3 ds 3 gs 5 vs 3 preset 40 35 is 6 hs 2 ds 4 gs 5 vs 3 preset 48 2 is 6 hs 4 ds 4 gs 5 vs 3 preset 52 1126 is 6 hs 2 ds 2 gs 6 vs 4 preset 53 151 is 7 hs 2 ds 2 gs 6 vs 4 preset 54 63 is 8 hs 2 ds 2 gs 6 vs 4 preset 55 1 is 9 hs 2 ds 2 gs 6 vs 4 preset 56 4 is 6 hs 2 ds 3 gs 6 vs 4 preset 57 2 is 7 hs 2 ds 3 gs 6 vs 4 preset 60 9 is 6 hs 3 ds 3 gs 6 vs 4 preset 61 14 is 7 hs 3 ds 3 gs 6 vs 4 preset 62 4 is 8 hs 3 ds 3 gs 6 vs 4 preset 64 14 is 6 hs 2 ds 4 gs 6 vs 4 preset 65 33 is 7 hs 2 ds 4 gs 6 vs 4 preset 67 1 is 9 hs 2 ds 4 gs 6 vs 4 preset 68 61 is 6 hs 3 ds 4 gs 6 vs 4 preset 69 13 is 7 hs 3 ds 4 gs 6 vs 4 preset 70 11 is 8 hs 3 ds 4 gs 6 vs 4 preset 71 7 is 9 hs 4 ds 4 gs 6 vs 4 preset 72 55 is 6 hs 4 ds 4 gs 6 vs 4 preset 73 28 is 7 hs 4 ds 4 gs 6 vs 4 preset 74 9 is 8 hs 4 ds 4 gs 6 vs 4
Magyarázat:
- is: hash tábla index méret, 6 és 10 bit között (QOI2_INDX csomag),
- hs: halfwidth diff méret, ds: diff méret 2 és 6 bit között (QOI2_DIF2 és QOI2_DIF3),
- gs: zöld diff 4 és 7 között (QOI2_DIFL),
- vs: rb zöld relatív diff méret 1 és 4 bit között (QOI2_DIFL),
- a QOI2_RUNS, QOI2_RUNL kimaradt a tesztből (túl sok lett volna a kombináció),
- a QOI2_RGBA pedig koncepcionálisan nem változó bitméretű. mivel egy csatorna fixen 8 bites.
Érdekes megfigyelni, hogy az eloszlásnak két lokális maximuma van: a kissebb bitméret a transzparens képek esetén, a második nagyobb bitméret a fotó jellegű képeknél. Ez utóbbinál mindössze egy bit a különbség (ds 3 az optimális 2 helyett) a mindig bájthatárra eső csomaghoz képest.
Ami viszont meglepett, hogy azt hittem, a "látott pixelek" hasítótábla méretének növelésével drasztikusan javulni fog a tömörítési arány, mert több lesz a rövidebb QOI2_INDX csomag, azonban ez nincs így. Lehet kevés volt a skótkockamintás tesztképem.
- A hozzászóláshoz be kell jelentkezni
szep ez a POP_BITS de azt ugye vagod hogy a mai cpu-k nagyon nem szeretik az unaligned memoria cimzest? raadasul ez igy erzekeny a byteorderre is, ami az ARM terhoditasaval ujra eloterbe kerult...
> a "látott pixelek" hasítótábla méretének növelésével drasztikusan javulni fog
miert? fotoknal nem nagyon tudja hasznalni (max a hatterszin lesz meg ha az fix), rajzoknal meg boven eleg a 2^6 tabla is... en inkabb lefele mennek, megneznem 4-5 bittel is.
fotokra azert erdemes lenne implementalni egy olyan filtert, ami az elozo pixel sorhoz kepest is nezi a diff-et. a png es anno az en ESP-m is ezt hasznalta, drasztikus javulast eredmenyezett. nem nagy cucc implementalni (se sloc se cpu hasznalat szempontbol), csak a feldolgozas elott kivonod (ill. dekodolasnal hozzaadod) az elozo sor pixel ertekeit (bar vszolszinu eleg a kep szelessege * bpp ertekkel vissza indexelni, nem kell minden sort kulon kezelni) az epp feldolgozottbol.
aztan persze lehet vadulni is hogy az elozo 2-3 pixelbol interpolalni valami masodfoku polinommal :)
- A hozzászóláshoz be kell jelentkezni
de azt ugye vagod hogy a mai cpu-k nagyon nem szeretik az unaligned memoria cimzest?
írj egyszerűbbet és jobbat! A feladat: a bytearray-re bitarrayként tekinteni, amiből a soronkövetkező n bitet kell kiolvasni v változóba.
(Egyébként meg de, pont hogy nincs semmi bajuk vele, amióta létezik L2 cache, az egymásutánni bájtokról olvasáshoz még csak a memóriát sem használja. Nem random elérés, hanem szekvenciális!)
raadasul ez igy erzekeny a byteorderre is, ami az ARM terhoditasaval ujra eloterbe kerult...
Tévedsz! Egyrészről az ARM is little-endian (konfigurálható ugyan big endian-re is, de a kutya se teszi), másrészről kit érdekel, amikor csak a gépemen lévő képeket mértem meg vele?
Harmadrészt meg, nem nagy kunszt, tessék, endianness független implementáció (ha az n sosem nagyobb 16-nál, elég a 3 bájt is):
#define POP_BITS(v, n) do{ v = ((src[0])|(src[1]<<8)|src[2]<<16)) >> off) & ((1 << (n)) - 1); off += n; src += off >> 3; off &= 7; }while(0)
miert?
Mert ha egy pixelt egy rövidebb csomaggal kódolsz, akkor rövidebb lesz a végeredmény is...
fotoknal nem nagyon tudja hasznalni (max a hatterszin lesz meg ha az fix)
Tévedsz, a fix háttérszínt nem is ilyen csomagokkal kódolja, hanem run-okkal!
rajzoknal meg boven eleg a 2^6 tabla is...
Tévedsz, a pixeleloszlástól függ! Nem jelentheted ki, hogy a rajzokon sosincs ismétlődő X hosszú minta!
en inkabb lefele mennek, megneznem 4-5 bittel is.
Én meg inkább másik hasítófüggvény felé nézelődnék. A mostani annyit csinál csak, hogy minden csatornát felszoroz rendre az első 4 prímmel, majd modulo táblaméret. Bár pofon egyszerű, de elég rossz a cache miss aránya.
Ha nem hasítót használunk az indextáblához, hanem keresést és push item-et, akkor lelassul a codec, viszont durván javul a tömörítési rátája. (Ezt is próbáltam, végül azért vetettem el, mert a keresés O(N) és nem O(1), a sebesség meg fontosabb volt).
fotokra azert erdemes lenne implementalni egy olyan filtert, ami az elozo pixel sorhoz kepest is nezi a diff-et. a png es anno az en ESP-m is ezt hasznalta
Próbáltam, nem érte meg. A plusz csomagok miatt nőtt a csomagprefix bitek száma, ezáltal a csomagok mérete, amivel drasztikusan leromlott a tömörítési ráta. Azaz a plusz prefixbitek többet rontottak, mint amennyit az UP filter javítani volt képes. Nem meglepő: a prefix növelése mindig, minden csomagon ront, míg az előző sorhoz képesti diff csak néha-néha alkalmazható.
- A hozzászóláshoz be kell jelentkezni
Na, ezt viszont eddig még nem próbáltam: a rövid ismétlő csomagot cseréltem le az előző sor különbsége csomaggal, így a prefixméretek nem változtak. Az előző sor különbsége csomag pontosan ugyanúgy néz ki, mint a QOI2_DIF3 csomag. Eredmények:
pnglogo lena sheet kurisu RAW 1920000 262144 4472832 3506616 QOI1 406573 137948 151412 828860 RUNS 377984 137566 150382 790669 DIFU 373673 136116 173831 781603 RUNS: 1101xxxx DIFU: 1101rrrgggbbbaaa
A legtöbb képen minimális volt a javulás (max 1%), a szprájtlapon viszont durva volt a romlás (-15%), így rosszabb lett a végeredménye, mint az eredeti QOI-é.
- A hozzászóláshoz be kell jelentkezni