07.08.2026 09:34

Opcje zapisu dla dokumentów — i nagrania, które schudły 64 razy

⏱️ 6 min read
Share:

Poprzednim razem opisywaliśmy filtr predykcyjny — sztuczkę starą jak formaty obrazu, dzięki której gradient zamiast ciągu różnych liczb staje się ciągiem prawie samych zer, a kompresja robi z tym porządek. Ten wpis jest o dwóch rzeczach, które tamten zostawił niedomknięte, i o jednej rzeczy, którą przy okazji trzeba było powiedzieć wprost.

Sceny miały okno opcji. Dokumenty nie miały

Zapisując scenę, można było zdecydować: pełna dokładność czy szesnaście bitów, jak mocno kompresować, czy trzymać materiały w środku pliku, czy zapisywać miniaturę podglądu. Zapisując dokument — nic. Szło zawsze tak samo.

Nie było ku temu żadnego powodu poza kolejnością, w jakiej te rzeczy powstawały. Pytania są identyczne. Więc dokumenty dostały te opcje — ale nie drugie takie samo okno. Dostały to samo, jedno. Różnice między formatami (jak oszacować rozmiar, jak zrobić zapis próbny, czy „materiały w pliku" w ogóle coś tu znaczy) wchodzą do niego jako parametr.

To brzmi jak drobiazg architektoniczny, ale ma bardzo praktyczny skutek: dwa osobne okna rozjechałyby się przy pierwszej poprawce sformułowania. Ktoś poprawiłby zdanie o tym, co się traci przy szesnastu bitach, w jednym z nich — i od tego dnia scena i dokument mówiłyby o tej samej rzeczy dwoma różnymi językami.

Okno pokazuje się tylko wtedy, kiedy plik zapisujesz pod nazwą, której jeszcze nie miał — przy pierwszym zapisie i przy „Zapisz jako". Nigdy przy Ctrl+S. Nigdy przy autozapisie. I nigdy przy zapisach, których nie wywołujesz ręcznie — kiedy program sam odkłada ilustrację do folderu projektu komiksu albo robi to skrypt, żadne okno się nie otwiera. Modalne pytanie w ścieżce, przy której nikt nie stoi, to nie jest opcja, tylko zawieszony program.

Wybór zapisuje się w samym pliku, nie w ustawieniach programu. To opis tego pliku, a nie tej sesji. Plik zapisany jako szesnastobitowy zostaje szesnastobitowy do końca życia, bez powtarzania pytania — a osoba, która go od Ciebie dostanie, dostaje go dokładnie takim, jakim go zapisano.

Rzecz, którą wyłapał dopiero audyt

Pierwsza wersja tego mechanizmu pytała: „czy pod tą ścieżką już coś leży?". Wygląda rozsądnie i jest kompletnie błędne. Bo znaczy to tyle: wskazujesz w „Zapisz jako" istniejący, cudzy plik zapisany kiedyś jako szesnastobitowy — okno się nie pokazuje, a Twój dokument po cichu przejmuje jego dokładność. Czyli jedyna decyzja, dla której to okno w ogóle powstało — ta z akapitem „tej straty nie da się cofnąć" — zapada bez Ciebie.

Warunek dotyczy teraz dokumentu, nie pliku. Pytamy, kiedy to ten dokument nie ma jeszcze swojej nazwy albo kiedy jawnie prosisz o „Zapisz jako". Tak, jak od początku działały sceny.

Druga rzecz z tej samej rundy: skoro opcje można zmienić przy „Zapisz jako" na własny plik, to zmiana dokładności musi przepisać cały plik, a nie dopisać do niego łatkę zapisaną inaczej niż wiersze, które już tam są. Jeden plik z dwiema odpowiedziami na to samo pytanie to nie jest plik, którym chce się dzielić.

I rzecz, którą trzeba było odebrać

Okazało się, że opcja „szesnaście bitów" na dokumencie ośmiobitowym działałaby dokładnie odwrotnie, niż obiecuje: plik byłby większy, a zajętość pamięci po ponownym otwarciu podwoiłaby się i już nie wróciła. Bo osiem bitów jest węższe niż szesnaście, a nie szersze. „Mniejszy plik", który jest większy w obu miejscach, to nie wybór — to błąd z checkboxem. Więc tam ta opcja się po prostu nie pokazuje.

Przy okazji: plik zapisany w szesnastu bitach mówi teraz o sobie, że jest szesnastobitowy. Wcześniej deklarował w nagłówku pełną dokładność, więc po otwarciu program pokazywał „32 bity na kanał" nad pikselami, które nią już nie były — i odmawiał poszerzenia, bo uważał, że jest już poszerzony.

Nagrania: 36 kilobajtów na 566 bajtów

Poprzedni wpis stwierdzał uczciwie, że nagrania sesji z filtra predykcyjnego nie korzystają. To była prawda i była to diagnoza, nie stan docelowy.

Powód był taki: nagranie zapisywało pojedynczy kafel obrazu tak, jak wysyła się go do drugiej osoby przy wspólnej pracy nad rysunkiem — jako tekstowy pakiecik z pikselami zakodowanymi w base64. To była rozsądna decyzja, bo nie dublowała kodu. Kosztowała jednak potrójnie:

  • base64 rozdyma skompresowane bajty o jedną trzecią, którą kompresja pliku musi potem odzyskiwać — praca wykonywana wyłącznie po to, żeby cofnąć inną pracę;
  • ten sposób zapisu domyślnie wysyła piksele w najszerszej możliwej postaci, bo po drugiej stronie łącza może stać starsza wersja programu — więc dokument szesnastobitowy nagrywał się w dwukrotnie szerszej;
  • i nie zna filtra predykcyjnego w ogóle.

Tyle że nagranie nie ma drugiej strony. Jedynym czytelnikiem tego pliku jest ten program, otwierający coś, co sam przed chwilą zapisał. Płaciliśmy za zgodność z kimś, kogo nie ma.

Nagrania zapisują więc teraz kafel dokładnie tak, jak robią to dokumenty i sceny. Zmierzone na jednym kaflu gradientu — czyli na tym, co zostawia po sobie miękki pędzel, więc na przypadku najzupełniej codziennym:

36 090 bajtów → 566 bajtów. Sześćdziesiąt cztery razy mniej.

Dokument szesnastobitowy nagrywa się w szesnastu bitach. Przewijanie nagrania w tył i w przód zrobiło się przy okazji tańsze, bo sprawdzenie „czy ręka doszła już do tego kafla" nie wymaga już rozpakowywania kafla, żeby zaraz go wyrzucić.

Stare nagrania grają dalej i nie decyduje o tym żaden przełącznik ani flaga — obie postacie zapisu rozróżnia pierwszy bajt pliku. W drugą stronę zgodności nie ma i tu podjęliśmy decyzję, która na pierwszy rzut oka wygląda nieprzyjaźnie: starsza wersja programu odmówi otwarcia nowego nagrania, zamiast pokazać je z dziurami. Odtwarzanie pomija kafel, którego nie umie odczytać, po cichu — a plik, który gra „prawie dobrze" i nikomu o tym nie mówi, jest gorszy od pliku, który uczciwie się nie otwiera. Zwłaszcza nagranie, którego nie da się powtórzyć, bo sesja, którą zarejestrowało, dawno się skończyła.

Na koniec: dlaczego piszemy o audycie

Cztery z rzeczy opisanych wyżej nie były planowane — wyszły z adwersaryjnego przeglądu własnego kodu, robionego z założeniem „znajdź, gdzie to się psuje", a nie „sprawdź, czy działa". Jedna z nich cicho odbierała użytkownikowi decyzję o nieodwracalnej stracie dokładności.

Trzymamy tę kolejność świadomie: zbudować, zmierzyć, a potem osobno spróbować to obalić. Wpisy takie jak ten są łatwiejsze do napisania, kiedy najgorsze zdania w nich brzmią „a to znaleźliśmy i naprawiliśmy", a nie „a tego nie zauważyliśmy".

📚 Related posts

27.08.2026 20:55

Data, której nie cofniemy nawet my

Każdy certyfikat autorstwa dostaje datę zapisaną w blockchainie Bitcoina — takiej nie podważy nikt, my też nie. Sprawdzisz ją bez konta i bez Moonligh...
Continue reading →
27.08.2026 19:35

Twój kolor, wszędzie

Trzy tryby i siedem akcentów, wspólnych dla strony i Moonlight Animate. Motyw jedzie z kontem, profil pokazuje gościom Twoje kolory, a harmonogram sam...
Continue reading →
27.08.2026 18:31

Kto moderuje i na jakiej podstawie

Moderator to teraz osobna rola z własnym zakresem, a nie administrator w przebraniu. Odrzucenie treści wymaga powodu, który trafia do autora razem z d...
Continue reading →

📧 Stay up to date!

Join the waitlist to get notified about new Dev Blog posts and Moonlight platform launch.