nibnib: فرمت تصویری که برای سرعت باز شدن ساخته شده
خلاصهٔ کاملتر
nibnib یه فرمت تصویره که Raph Levien به عنوان یه آزمایش ساخته تا ببینه روی میکروکنترلر RP2350 برای خروجی DVI چه کیفیت و سرعتی میشه گرفت. طبق توضیح پروژه، روی این دستگاهها برای هر پیکسل فقط حدود ۶ سیکل پردازنده وقت هست. این برای خوندن پیکسل، پیدا کردنش توی پالت و نوشتنش توی بافر خط کافیه، ولی جای اضافهای نمیمونه.
ایدهی اصلی اینه: به جای اینکه پالت خود رنگ رو نگه داره، یه delta (یعنی اختلاف نسبت به پیکسل قبلی) رو نگه میداره. اینطوری قسمتهای نرم تصویر، مثل گرادیانها، خیلی بهتر از تصویرهای پالتی معمولی درمیان. هر بایت ورودی دو پیکسل میسازه، یعنی فشردهسازی ۴ بیت به ازای هر پیکسل.
بازکردنش سادهست. آخرین پیکسل دو برابر میشه، یه بایت از ورودی خونده میشه و توی پالت پیدا میشه. اون مقدار ۳۲ بیتی به پیکسلِ دوبرابرشده اضافه میشه و دو پیکسل ۱۶ بیتی با فرمت RGB 565 به دست میاد. حلقهی اصلی توی Rust اینطوریه:
for x in 1..(width / 2) {
let inp = src[x + 3];
pix = ((pix >> 16) * 0x10001).wrapping_add(pal[inp as usize]);
out[x * 2] = pix & 0xffff;
out[x * 2 + 1] = pix >> 16;
}برعکس بازکردن، ساختن فایل یه جستوجوی کُند هست و encoder فعلی چند مرتبه کندتر از decoder کار میکنه. پالت از یه مکعب از deltaهای کوچیک و یه سری مقدار تصادفی با توزیع گاوسی ساخته میشه. مکعب لازمه تا رنگهای نزدیک صفر و حداکثر بدون سرریز به دست بیان، وگرنه خطاهای بدی توی تصویر دیده میشه. فعلاً پالت بر اساس خود تصویر انتخاب نمیشه.
encoder هر ۲۵۶ ورودی پالت رو امتحان میکنه و اونی که کمترین خطا رو داره انتخاب میکنه. بعد خطا رو با وزنهای Floyd-Steinberg (یعنی پخش کردن خطا بین پیکسلهای همسایه) پخش میکنه. فرقش با روش معمول اینه که برای دو پیکسل با هم تصمیم میگیره و به مجموعشون وزن بیشتری میده، چون چشم آدم به تغییرات کمفرکانس حساستره.
به گفتهی نویسنده، با پالت بهینه و جستوجوی عمیقتر کیفیت خیلی بهتر میشه، بدون اینکه decoder عوض بشه. فعلاً خطاها سمت راست لبههای تیز دیده میشن، که میشه با encode از راست به چپ کمش کرد. خود فایل خیلی سادهست: دو بایت برای عرض و ارتفاع، ۲۵۶ ورودی پالت ۳۲ بیتی، بعد ردیفها. پروژه با لایسنس Apache 2.0 یا MIT منتشر شده.
نکات کلیدی:
- روی RP2350 برای هر پیکسل حدود ۶ سیکل پردازنده وقت هست.
- هر بایت ورودی دو پیکسل RGB 565 میسازه، یعنی ۴ بیت به ازای پیکسل.
- پالت ۲۵۶ ورودی ۳۲ بیتی داره که به جای رنگ، اختلاف رنگ رو نگه میداره.
- encoder از Floyd-Steinberg استفاده میکنه و خیلی کندتر از decoder هست.
- فرمت هیچ متادیتایی نداره و برای آرشیو کردن ساخته نشده.