Guetzli – lepsza kompresja JPEG

Przedwczoraj Google ogłosiło na blogu nowe narzędzie do kompresji JPEG o nazwie Guetzli, wydawane na wolnej licencji (Apache License). Ma dawać lepsze optycznie rezultaty przy mniejszym rozmiarze wynikowym (mowa nawet o 35% mniejszych plikach). Cena? Oczywiście czas kompresji.

Postanowiłem przetestować na szybko, co mogło by się zmienić, gdybym wykorzystał grafiki skompresowane przy pomocy Guetzli na blogu. W tym celu sięgnąłem po obrazki z backupu bloga i uruchomiłem program (domyślne opcje kompilacji, domyślne ustawienia jakości, czyli 90%) na moim laptopie (CPU: Intel(R) Core(TM) i3 CPU M 380 @ 2.53GHz). Zdziwiło mnie to, że aż przy 12 plikach nie udało się ukończyć działania – program zgłosił błąd:

Invalid input JPEG fileGuetzli processing failed

Udało się przetworzyć 66 plików, całość trwała prawie 17 minut (sic!). Czyli jest bardzo wolno. Kompresor wykorzystywał tylko jeden rdzeń CPU. Efekty są obiecujące, zarówno wizualne, jaki i objętościowe. Mimo, że algorytm jest zaprojektowany z myślą o działaniu na możliwie nieprzetworzonych obrazach wejściowych, a te na blogu raczej są już zoptymalizowane, to łączny rozmiar udało się zmniejszyć o 14% (z ok. 3,3 MB do ok. 2,8 MB).

Jeśli wezmą się za wykorzystanie i optymalizację duże firmy, a jest na to szansa po uwolnieniu programu, może to oznaczać mniej przesyłanych danych po sieci, czyli szybsze ładowanie się stron, widoczne zwłaszcza na komórkach. Chwilowo główną barierą jest czas działania, który wygląda na zależny bezpośrednio od wielkości pliku wejściowego.

Zrobiłem jeszcze jeden test – plik JPG bezpośrednio z aparatu, rozmiar 2560×1440, rozmiar wejściowy 1,2 MB. Po kompresji (trwającej kilka minut) brak zauważalnych zmian jakości, natomiast rozmiar zmniejszony aż o 50% (614 kB).

Założenia i opis projektu abcc

Projekt abcc składa się z demona, napisanego w Pythonie, który czyta plik konfiguracyjny, a następnie na podstawie jego zawartości dokonuje cyklicznej kontroli jakości dostępnych łącz względem określonych w konfiguracji IP docelowych. Przeprowadzane operacje zapisywane są do logu (syslog?), podobnie jak oceny poszczególnych łącz.

Zakładam wykorzystanie Pythona w wersji 3, przestrzeganie PEP8 i programowanie funkcyjne. Całość ma być możliwie prosta koncepcyjnie i możliwie konfigurowalna przy pomocy pliku konfiguracyjnego za pomocą wag poszczególnych wskaźników, wag IP. Rozwiązanie ma też zapewniać użytkownikowi pełną przejrzystość działania, wybór poziomu logowania i możliwość uruchomienia w wersji „na sucho”, w celu przetestowania, jak uruchomienie z daną konfiguracją wpłynęłoby na zmiany routingu.

Aby to osiągnąć, zmienia na czas pomiaru routing do docelowych IP na dane łącze, dokonuje pomiaru jakości łącza, a następnie, po zebraniu danych dla wszystkich łącz, określa, które z nich jest najlepsze i – jeśli zachodzi taka potrzeba, dokonuje zmiany routingu.

Do zmiany routingu wykorzystywane są zewnętrzne skrypty bashowe – pozwala to na dostosowanie działania demona do różnych platform i potrzeb – np. dodanie zmiany NATowanaia, wywołanie zmian na zdalnym systemie (router sprzętowy) – bez zmian w samym silniku.

Teoretycznie można by to napisać w czystym Bashu i wywoływać z crona, ale po pierwsze, chcę potrenować Pythona, po drugie tak będzie łatwiej, bardziej elegancko i będzie otwarta droga np. do zwiększenia częstotliwości próbkowania przez zrównoleglenie pomiarów.

Z racji wymogów konkursowych dotyczących ilości postów, tworzenie projektu będzie trochę przegadane, i spowolnione, przynajmniej na początku. Zaleta jest taka, że będzie lepiej widać sposób rozumowania, gdyby ktoś chciał coś skomentować lub się przyłączyć. Commity kodu i dokumentacji będą się pojawiały w miarę równolegle z wpisami na blogu, pierwszy właśnie poszedł.

Geneza, nazwa i zastosowania

Projekt, który mam zamiar zrealizować w ramach DSP2017 nazywa się abcc (Automatic Best Connection Chooser). Pierwotnie miał się nazywać abpppcc i działać dla połączeń PPP, ale w sumie nie ma to sensu. Pomysł narodził się, gdy kiedyś znajomy z FB napisał, że jest w drodze, ma 2 czy 3 połączenia GSM i przełącza się między nimi, bo raz lepiej działa to, raz tamto. Oczywiście przełącza się ręcznie.

Stwierdziłem, że gdyby miał Linuksa, to uruchomienie wszystkich naraz, sprawdzanie automatem i przełączanie ruchu na najlepsze nie powinno być trudne. Sprawę wstępnie przemyślałem, zacząłem nawet zabawę z dwoma modemami GSM, ale wkrótce pojawiły się ważniejsze sprawy i projekt trafił do szuflady. Znaczy na dysk. Nawet nie tyle projekt, co krótko spisane wstępne założenia i wymyślona nazwa.

Potem stwierdziłem, że rozwiązanie można zastosować też w innych okolicznościach, nie tylko przy laptopie w podróży. Może służyć do przełączania ruchu na łącze zapasowe w przypadku sieci i routera na Linuksie i pogorszeniu parametrów łącza podstawowego, a nawet… do sterowania ruchem operatorskim.

W tym ostatnim zastosowaniu oczywiste jest podobieństwo do rozwiązania firmy Border6 omówionego na PLNOG13, przy czym to co zamierzam napisać jest o wiele bardziej prymitywne, więc mam nadzieję, że klientów nie odbierze. Choć IMO ma szansę być opensource’ową namiastką.