semmixkolor i percepcja

Opis ekranu logicznego

Zaraz po nagłówku idzie 7 bajtów opisujących "ekran logiczny": obszar, na którym rysuje się wszystkie obrazy z pliku. Ten blok mówi też, czy plik ma paletę globalną i jak jest duża.

Budowa

BajtyPolePrzykład
0-1szerokość ekranu (little-endian)04 00 = 4
2-3wysokość ekranu02 00 = 2
4flagiF1
5indeks koloru tła00
6proporcje pikseli00

Bajt flag

bit 7 jest paleta globalna (1) albo nie (0) bity 6-4 rozdzielczość kolorów - 1 bit 3 paleta posortowana od najczęstszych kolorów bity 2-0 N: paleta ma 2^(N+1) kolorów F1 = 11110001 │└┬┘│└┬┘ │ │ │ └─ N = 1 → 2^2 = 4 kolory, 12 bajtów palety │ │ └─── 0: nieposortowana │ └───── 7: oryginał miał 8 bitów na składową └─────── 1: paleta globalna jest
NKolorówBajtów paletyMinimalna długość kodu LZW
0262
14122
28243
316484
72567688

Paleta ma zawsze potęgę dwójki pozycji. Obraz w 5 kolorach musi mieć paletę 8-kolorową, a 3 pozycje zostają nieużywane. Ostatnia kolumna dotyczy bloku obrazu: dla palet 2-kolorowych minimalna długość kodu i tak wynosi 2, bo GIF nie pozwala na 1.

Pole rozdzielczości kolorów (bity 6-4) jest informacyjne i praktycznie nieużywane (zob. rozdzielczość kolorów). Flaga sortowania pomagała kiedyś dekoderom z mniejszą liczbą kolorów wybrać najważniejsze.

Kolor tła i proporcje

Kolor tła to numer z palety globalnej, którym należy wypełnić ekran tam, gdzie żaden obraz nie sięga. Przeglądarki internetowe zwykle go ignorują i pokazują w tych miejscach przezroczystość.

Proporcje pikseli: 0 oznacza "nie podano", inna wartość N daje (N + 15) / 64. Opisuje to strona o proporcjach punktów.

Paleta globalna

Jeśli bit 7 jest ustawiony, zaraz za opisem ekranu idą kolory palety: po 3 bajty (R, G, B) na kolor, bez żadnych separatorów. W przykładzie 4 kolory zajmują 12 bajtów:

C8 50 28 indeks 0 (200, 80, 40) FF FF FF indeks 1 (255, 255, 255) 00 00 00 indeks 2 (0, 0, 0) 1B 98 E0 indeks 3 (27, 152, 224)

Paleta globalna obowiązuje dla każdego obrazu, który nie ma własnej palety lokalnej. Wartości są zapisane bez informacji o przestrzeni barw, więc w praktyce traktuje się je jako sRGB.

function readScreen(b, pos) {                      // pos: zaraz po nagłówku
  const w = b[pos] | (b[pos + 1] << 8), h = b[pos + 2] | (b[pos + 3] << 8);
  const flags = b[pos + 4];
  const hasGct = (flags & 0x80) !== 0;
  const gctSize = 2 << (flags & 0x07);            // 2^(N+1)
  return { w, h, hasGct, gctSize, bg: b[pos + 5], aspect: b[pos + 6] };
}