Примерно месяц назад польский программист Доминик Шаблевски представил на суд публики новый графический формат QOI (Quite OK Image). Формат сжимает без потери качества, ориентируется на максимальную скорость кодирования/декодирования изображений, и по бенчмаркам значительно превосходит libpng и stbi. Разница в сжатии составляет 20−50 раз, в декомпрессии — 3−4 раза.

Кроме того, формат сжатия исключительно простой, закодирован буквально в 300 строчек кода, и работает по простым правилам типа кодирования повторов (RLE). Естественно, он не связан никакими лицензионными соглашениями и ограничениями.

И вот вчера после исправления всех недочётов наконец-то опубликованы финальные спецификации, так что теперь QOI документально забетонирован и его можно начинать использовать в продакшне. Что примечательно, полные спецификации QOI поместились на одной странице!

Собственно, вот эта страница, то есть спецификации формата целиком:



В спецификациях описан весь алгоритм кодирования. Доминик уже объяснял, что он обычный разработчик и не очень хорошо разбирается в сложных методах, которые используются в современных графических кодеках. Как программист он реализовал простые математические методы. Изображение кодируется в один проход, каждый пиксель считывается только один раз и кодируется одним из четырёх методов, по порядку:

  1. Если пиксель равен предыдущему, счётчик увеличивается на единицу. Если нет, то применяется метод 2, и так далее
  2. Пиксель равен элементу массива последних пикселей
  3. Записывается разница с предыдущим пикселем, если она небольшая
  4. Полное значение RGBA

Результирующие значения записываются в группы с указанием сначала тега (метод кодирования), после которого идут биты. Все группы выровнены по байтам для ускорения доступа в памяти.

За месяц автор получил более 500 комментариев, в том числе по оптимизации формата, так что теперь QOI стал ещё быстрее, а уровень сжатия вырос, см. бенчмарки на 2879 изображениях. Что самое удивительное, благодаря подсказкам коллег алгоритм сжатия стал ещё проще — автор удалил из формата заголовок size и некоторые лишние процедуры. Код референсного кодека и декодера опубликован на Github. Естественно, в него можно вносить любые изменения и дополнения, приспосабливая для своих нужд.

За последние несколько недель написаны реализации QOI для многих популярных языков программирования и библиотек, включая Zig, Rust, Rust, Rust, Go, TypeScript, Haskell, Ć, Python, C#, Elixir, Swift, Java и Pascal, обёртки (врапперы) для Python и Lua. Разработано нативное приложение для просмотра файлов QOI, плагины для Gimp, Paint.NET и XNView MP, планируется поддержка в SDL_Image.

Бенчмарки, база 2879 изображений

Декодер, мс Кодер, мс Декодер, mpps Кодер, mpps Размер, КБ Пропорция от оригинала
libpng 22,9 310,8 47,42 3,49 1799 56,6%
stbi 26,7 195,6 40,63 5,55 2498 78,6%
qoi 7,4 11,1 147,02 97,55 2102 66,2%
mpps — миллионов пикселей в секунду

QOI показывает разную эффективность на изображениях разных типов: скриншоты, текстуры, фотографии, иллюстрации из Википедии и т. д. На некоторых картинках он кодирует в 60 раз быстрее PNG, а на других только в 30.

Новый формат предназначен для задач с интенсивным кодированием/декодированием изображений, где важен не столько размер изображений, сколько нагрузка на CPU и скорость. Например, вычисления на облачном сервисе (с оплатой за CPU), обработка больших фотоколлекций, нагрузка headless-браузеров, скриншоты, веб-скрапинг и др. В наше время накопители очень дёшевы, так что скорость зачастую становится более важным фактором, чем экономия дискового пространства.