Mivel több HUP-os fórumtárs is mikrokontrollerezik, ezért gondoltam megosztom, hátha másnak is hasznos lesz.
Összedobtam egy minimalista QR kód generálót ANSI C-ben, kifejezetten URL-ek kódolására:
- Szabad és Nyílt Forráskódú, MIT licenszű
- irtó kicsi (kb. 150 SLoC), egyetlen egy függvény csak
- nincs semmi függősége (még libc se, de még csak libc fejlécek sem kellenek neki)
- nem foglal memóriát egyáltalán
- csak pár bájtot eszik a veremből
- pofon egyszerű használni, nem kell konfigurálni
- egy 53 x 53 pixeles szürkeárnyalatos képet köp ki (csak 0 (előtér) ill. 255 (háttér) színekkel)
- a bemenete egy legfeljebb 128 bájtos URL (vagy hát bármilyen UTF-8 sztring igazából)
Példa használatra (csak példa, semmilyen domain sem query paraméter nincs a függvénykönyvtárban, bármi lehet):
#define NANOQR_IMPLEMENTATION #include "nanoqr.h" uint8_t image[53][53]; nanoqr(image, "https://gitlab.com/bztsrc/nanoqr?errcode=1234&errpos=1234&when=1234");
Ennyi. Aztán a megadott URL-re lehet rakni egy JavaScriptet, ami megcsócsálja és ember számára érthető hibaüzenetekké formálja az URL paraméterében megadott kódokat.
Technikai részletek: QR version 9-et generál (mert a 128 bájtos tárhely elfogadhatónak tűnt, a 53 x 53 pixeles méret meg elég kicsi ahhoz, hogy elférjen LCD-kre, de akár LED-es kijezlőkre is). A hibajavító kód QUARTILE (eggyel rosszabb csak, mint a legjobb opció), a maszkszint fixen 1-es, az adathalmaza pedig bájt (mert az alfanumerikusból hiányzik a ?, &, =, szóval nemigazán kódolható vele URL). Ezeket bedrótoztam az egyszerűség kedvéért, hogy ne kelljen semmit állítgatni. Ha valakinek ez nem felelne meg, akkor nekik ott a Nayuki QR kódgeneráló, de az többet eszik és bonyibb használni is.
- 235 megtekintés
Hozzászólások
Szep :) Tenyleg teljesen warning-mentesen fordul 4 architekturan is, olyan 1.5k-2k koruli kod lesz minden esetben.
Hm... az mennyire bonyolitana el a kodot hogyha 2809 bytenyi 0-255 kep helyett ~352 ... ~371 bytenyi bitmaszkot allitana elo?
- A hozzászóláshoz be kell jelentkezni
Szep :)
Kösz! :)
Hm... az mennyire bonyolitana el a kodot hogyha 2809 bytenyi 0-255 kep helyett ~352 ... ~371 bytenyi bitmaszkot allitana elo?
Nem annyira vészes. A képet két lépcsőben állítja elő:
1. először 255-el tölti fel (133. sor), majd bizonyos pixeleket 0-ára állít, hogy a jól ismert alap mintázat rákerüljön (134.-150. sor).
2. az adatpixelek berakásakor (153.-191. sor) szintén csak 0-ra állítás van, illetve itt előfordul még XOR.
Ezek triviálisan átírhatók bitenkénti "dst &= ~x" és "dst ^= x" utasításokra, ez nem okoz problémát.
A gond inkább azzal van, hogy az 53 nem osztható 8-cal, így nem egyértelmű, mennyire kéne venni a sorhosszt. Lehet 56-ra (azaz 7 bájtra), de az az alignment miatt gondot okoz sok helyen (pl. ha BMP-be akarod menteni), vagy még több paddinggal 64-re, aminél meg lehetne akár uint64_t-t is használni egy sorra (mondjuk mikrokontrollereknél ritkán van 64 bites szó, de nem kizárt). Viszont az is gond még ennél, hogy minden rendszer máshogy veszi, balra vagy jobbra legyen-e a legalacsonyabb bit, mármint az endianess problémán túl (a PNG és a BMP pl. eltérő sorrendet használ). Bájtoknál nincs ilyen probléma, annál mindenki balról jobbra olvassa a sort, és az endianess is tök mindegy.
Aztán meg az is van, hogy macerás egy bitmapből kirakni a képet. Ha fájlba akarod menteni, akkor grayscale-nek simán megy így bájtokkal egy-az-egyben, ha indexelt palettás a formátumod, akkor elég minden pixelre gondolkodás nélkül &1-et nyomni és meg is vagy (az indexméret úgyis 8 bit), és RGB-re konvertálni is triviális (csak megismétled 3szor a bájtot ha true-color, vagy kétszer, ha hi-color), stb. Bitmapet sokkal több kóddal és macerávan lehetne csak átalakítani a cél pixelformátumra, ráadásul mint említettem volt, annál folyamatos probléma, hogy mi is a bitsorrend és hogy mennyi legyen a padding, meg még endianess függő is, mert nemcsak 1 bájt egy sor.
Szóval mindezeket megfontolva jutottam arra, hogy jobb, ha bájt alapú a kép, tisztább, szárazabb érzés.
- A hozzászóláshoz be kell jelentkezni
Meg egy gyors szakmai kerdes :) Ez a kod mennyire altalanosithato, akar #define-okkal, akar mint fuggvenyparameterrel hogy ne csak Version 9-et tudjon hanem (akar) kisebbet is? Igen, az biztos ront a hatekonysagan hogyha fuggvenyparameterrel adod at a negyzet meretet, de a forditaskor ismert meret mint megoldas is erdekes/hasznos lehet. Akkor masok a GF(2^8) parameterek?
- A hozzászóláshoz be kell jelentkezni
Nagyon szép munka! Respekt!
- A hozzászóláshoz be kell jelentkezni
Gratulálok, szép munka!
A detektálhatóság miatt nem kétszínűnek kellene lennie az eredményképnek? Jó kontrasztos, fekete-fehér?
- A hozzászóláshoz be kell jelentkezni
WAT?
Egyetlen fuggveny, ami a parameterul kapott 2D tombbe beteszi a parameterul kapott stringbol generalt QR kodot. Aztan hogy a 0-at es 255-ot hogy jelenited meg, rad van bizva. Azt is leirta, miert nem 1 bit egy pixel 1 byte helyett.
Ha 0 es 255 van benne, mi nem ketszinu? Az meg, hogy hopapiros nyomtato vagy kisnyuszik csinalnak belole a vegen beolvashato kepet, nem ezen a szinten dol el. Ha ott nem eleg kontrasztos, az baj ugyan, de nem a C kod hibaja.
A strange game. The only winning move is not to play. How about a nice game of chess?
- A hozzászóláshoz be kell jelentkezni