Specyfikacja kontenera WebP

Wprowadzenie

WebP to format obrazu wykorzystujący (i) kodowanie klatki klucza VP8 do kompresować dane obrazów w sposób stratny lub (ii) za pomocą bezstratnego kodowania WebP. Te schematy kodowania powinny sprawić, że będzie wydajniejszy niż starsze formaty, takie jak JPEG GIF i PNG. Jest zoptymalizowany pod kątem szybkiego przesyłania obrazu przez sieć (na np. witryn). Format WebP charakteryzuje się parzystością cech (profil kolorów, metadanych, animacji itp.) oraz innymi formatami. Ten dokument opisuje określa strukturę pliku WebP.

Kontener WebP (czyli kontener RIFF dla WebP) umożliwia obsługę funkcji ponad podstawowy przypadek użycia WebP (czyli plik zawierający obraz zakodowany jako ramka klucza VP8). Kontener WebP zapewnia dodatkowe uzyskasz pomoc w zakresie następujących zagadnień:

  • Kompresja bezstratna: obraz można kompresować bezstratnie za pomocą Format bezstratny WebP.

  • Metadane: metadane mogą być przechowywane w pliku Exchangeable Image File Format (Exif) lub format Extensible Metadata Platform (XMP).

  • Przezroczystość: obraz może mieć przezroczystość, czyli kanał alfa.

  • Profil kolorów: obraz może mieć osadzony profil ICC zgodnie z opisem przez International Color Consortium.

  • Animacja: obraz może mieć wiele klatek z przerwami między nimi, w animację.

Nazwa

W odniesieniu do WebP zalecamy korzystanie z następujących typów kontener:

Nazwa formatu konteneraWebP
Rozszerzenie nazwy pliku.webp
Typ MIMEimage/webp
Jednolity identyfikator typuorg.webmproject.webp

Terminologia i Podstawy

słowa kluczowe „MUSISZ”, „NIE MOŻE”, „WYMAGANE”, „MUSZĄ”, „NIE POWINNY”, „POWINNO”, „NIE POWINNO”, „ZALECANE”, „NIEZALECANA”, „MOŻE” i „OPCJONALNIE” tego procesu dokument należy interpretować zgodnie z opisem w BCP 14 RFC 2119 RFC 8174. kiedy i tylko gdy są pisane wielkimi literami, jak pokazano tutaj.

Plik WebP zawiera nieruchomy obraz (zakodowaną macierz pikseli). lub animację. Opcjonalnie może też zawierać przezroczystość. informacje, profil kolorów i metadane. Macierz pikseli nazywamy płótno obrazu.

Numerowanie bitów na diagramach fragmentów rozpoczyna się od 0 dla najbardziej istotnego bitu („MSB 0”), zgodnie z opisem w RFC 1166.

Poniżej przedstawiono dodatkowe terminy używane w niniejszym dokumencie:

Odczytujący/zapisujący
Kod, który odczytuje pliki WebP, jest nazywany czytnikiem, a kod, który w których je pisze, nazywamy zapisem.
uint16
16-bitowa liczba całkowita bez znaku, little-endian.
uint24
24-bitowa liczba całkowita bez znaku.
uint32
32-bitowa liczba całkowita bez znaku, little-endian.
FourCC
Czteroznakowy kod (FourCC) to ciąg uint32 utworzony przez połączenie czterech znaków Znaki ASCII w kolejności little-endian. To znaczy „aaaa”. (0x61616161) i „AAAA” (0x41414141) są traktowane jako różne FourCCs.
na podstawie 1,
Pole liczby całkowitej bez znaku, w którym przechowywane są wartości przesunięcia o wartość -1, takie jak będzie zapisywać wartość 25 jako 24.
ChunkHeader('ABCD')
Używane do opisania nagłówków FourCC i Chunk Size (Rozmiar fragmentu) poszczególnych fragmentów, gdzie „ABCD” to FourCC dla fragmentu. Rozmiar tego elementu to 8 bajtów.

Format pliku RIFF

Format pliku WebP jest oparty na RIFF (Resource Interchange File Format) .

Podstawowym elementem pliku RIFF jest fragment. Oto elementy składowe:

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                         Chunk FourCC                          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                          Chunk Size                           |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
:                         Chunk Payload                         :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Fragment FourCC: 32 bity
4-znakowy kod ASCII używany do identyfikacji fragmentów.
Rozmiar fragmentu: 32 bity (uint32)
Rozmiar fragmentu w bajtach bez uwzględnienia tego pola (fragmentu). identyfikatora lub dopełnienia.
Ładunek fragmentu: rozmiar fragmentu w bajtach
ładunek danych, Jeśli Rozmiar fragmentu jest nieparzysty, pojedynczy bajt dopełnienia, który MUSI wynosi 0, aby dostosować ją do RIFF – został dodany.

Uwaga: w RIFF obowiązuje konwencja, że znaki FourCC pisane tylko wielkimi literami są standardem fragmenty dotyczące dowolnego formatu pliku RIFF, a FourCC odnosi się tylko do pliku. są zapisane małymi literami. WebP nie przestrzega tej konwencji.

Nagłówek pliku WebP

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|      'R'      |      'I'      |      'F'      |      'F'      |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                           File Size                           |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|      'W'      |      'E'      |      'B'      |      'P'      |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
„RIFF”: 32 bity
Znaki ASCII: „R”, „I”, „F”, „F”.
Rozmiar pliku: 32 bity (uint32)
Rozmiar pliku w bajtach, począwszy od przesunięcia 8. Wartość maksymalna to pole ma 2^32 minus 10 bajtów, więc cały plik wynosi 4 GiB minus 2 bajty.
„WEBP”: 32 bity
Znaki ASCII: „W”, „E”, „B” i „P”.

Plik WebP MUSI zaczynać się od nagłówka RIFF z nagłówkiem „WEBP” FourCC. Rozmiar pliku w nagłówku to łączny rozmiar kolejnych fragmentów plus 4 bajtów dla „WEBP” FourCC. Plik NIE POWINNO zawierać żadnych danych po danych określona przez Rozmiar pliku. Czytelnicy MOGĄ przeanalizować takie pliki, ignorując zakończenie i skalowalnych danych. Ponieważ rozmiar dowolnego fragmentu jest parzysty, rozmiar podany w nagłówku RIFF to i równomierny. Zawartość poszczególnych fragmentów została opisana poniżej sekcji.

Prosty format pliku (strata)

Tego układu NALEŻY użyć, jeśli obraz wymaga kodowania stratnego i nie wymagają przejrzystości lub innych zaawansowanych funkcji udostępnianych przez format rozszerzony. Pliki z tym układem są mniejsze i obsługiwane przez starsze oprogramowanie.

Prosty format pliku (stratny): WebP:

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                               |
|                    WebP file header (12 bytes)                |
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
:                        'VP8 ' Chunk                           :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

„VP8” Fragment:

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                      ChunkHeader('VP8 ')                      |
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
:                           VP8 data                            :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Dane VP8: rozmiar fragmentu (w bajtach)
Strumień danych VP8.

Pamiętaj, że czwarty znak w polu „VP8 ” FourCC jest spacją ASCII (0x20).

Specyfikacja formatu strumienia bitowego VP8 została opisana w sekcji Format danych VP8 i Przewodnik po dekodowaniu. Zwróć uwagę, że nagłówek ramki VP8 zawiera ramkę VP8. szerokości i wysokości. Zakładamy, że jest to szerokość i wysokość obszaru roboczego.

Specyfikacja VP8 opisuje, jak zdekodować obraz do formatu Y'CbCr. Do konwersji na RGB, należy stosować rekomendację BT.601. Zgłoszenia – MAJ innej metody konwersji, ale wyniki wizualne mogą się różnić w zależności od dekoderów.

Prosty format pliku (bezstratny)

Uwaga: starsze czytniki mogą nie obsługiwać plików w formacie bezstratnym.

Tego układu NALEŻY użyć, jeśli obraz wymaga kodowania bezstratnego (z tagiem opcjonalny kanał przejrzystości) i nie wymaga udostępniania funkcji zaawansowanych. w formacie rozszerzonym.

Prosty format pliku (bezstratny) WebP:

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                               |
|                    WebP file header (12 bytes)                |
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
:                         'VP8L' Chunk                          :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

„VP8L” Fragment:

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                      ChunkHeader('VP8L')                      |
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
:                           VP8L data                           :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Dane VP8L: rozmiar fragmentu (w bajtach)
Strumień danych VP8L.

Aktualną specyfikację strumienia bitowego VP8L można znaleźć na stronie Bezstratny format transmisji bitów WebP. Pamiętaj, że nagłówek VP8L zawiera szerokość i wysokość obrazu VP8L. Zakładamy, że jest to szerokość, i wysokość płótna.

Rozszerzony format pliku

Uwaga: starsze wersje czytników mogą nie obsługiwać plików w formacie rozszerzonym.

Plik w rozszerzonym formacie składa się z tych elementów:

  • „VP8X” Fragment z informacjami o funkcjach używanych w pliku.

  • Opcjonalny „ICCP” Fragment z profilem kolorów.

  • Opcjonalny tag „ANIM” Fragment z danymi kontrolnymi animacji.

  • Dane obrazu.

  • Opcjonalny plik „EXIF” Fragment z metadanymi Exif.

  • Opcjonalny „XMP ” Fragment z metadanymi XMP.

  • Opcjonalna lista nieznanych fragmentów.

W przypadku zdjęcia dane zdjęcia składają się z pojedynczej klatki, do:

W przypadku animowanego zdjęcia dane obrazu składają się z wielu klatek. Więcej szczegółowe informacje o klatkach można znaleźć w sekcji Animacje.

Wszystkie fragmenty niezbędne do rekonstrukcji i korekcji kolorów, czyli „VP8X”, „ICCP”, „ANIM”, „ANMF”, „ALPH”, „VP8” i „VP8L”, MUSZĄ pojawić się w kolejności omówiono to wcześniej. Czytelnicy POWINNY BYĆ, gdy fragmenty są niezbędne do odbudowy i korekcja kolorów.

Metadane i nieznane fragmenty MOGĄ pojawić się poza zamówienie.

Uzasadnienie: fragmenty niezbędne do rekonstrukcji powinny pojawić się na początku który umożliwia czytelnikowi rozpoczęcie dekodowania obrazu przed otrzymaniem wszystkich danych. Dla aplikacji korzystne może być ustawienie różnej kolejności metadanych na niestandardowe fragmenty, które pasują do implementacji.

Rozszerzony nagłówek pliku WebP:

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                               |
|                   WebP file header (12 bytes)                 |
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                      ChunkHeader('VP8X')                      |
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|Rsv|I|L|E|X|A|R|                   Reserved                    |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|          Canvas Width Minus One               |             ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
...  Canvas Height Minus One    |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Zarezerwowana (RSv): 2 bity
MUSI być 0. Czytelnicy MUSZĄ ignorować to pole.
Profil ICC (I): 1 bit
Ustaw, jeśli plik zawiera „ICCP” Kawałek.
Alfa (L): 1 bit
Ustaw, czy którakolwiek z klatek obrazu zawiera informacje przezroczystości („alfa”).
Metadane Exif (E): 1 bit
Ustaw, jeśli plik zawiera metadane Exif.
Metadane XMP (X): 1 bit
Ustaw, czy plik zawiera metadane XMP.
Animacja (A): 1 bit
Ustaw, jeśli jest to obraz animowany. Dane w pliku „ANIM” i „ANMF” Fragmenty powinny być do sterowania animacją.
Zarezerwowana (R): 1 bit
MUSI być 0. Czytelnicy MUSZĄ ignorować to pole.
Zarezerwowana: 24 bity
MUSI być 0. Czytelnicy MUSZĄ ignorować to pole.
Szerokość obszaru roboczego minus jeden: 24 bity
Szerokość od 1 do obszaru roboczego w pikselach. Rzeczywista szerokość obszaru roboczego to 1 + Canvas Width Minus One.
Wysokość obszaru roboczego minus One: 24 bity
Od 1 do wysokości obszaru roboczego w pikselach. Rzeczywista wysokość obszaru roboczego to 1 + Canvas Height Minus One.

Iloczyn wartości Szerokość płótna i Wysokość płótna MUSI mieć maksymalnie 2^32 - 1.

W przyszłości możemy dodać więcej pól. Nieznane pola MUSZĄ być ignorowane.

Animacja

Animacją zarządza „ANIM” i „ANMF” Kawałki.

„ANIM” Fragment:

W przypadku animowanego obrazu ten fragment zawiera parametry globalne komponentu animację.

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                      ChunkHeader('ANIM')                      |
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                       Background Color                        |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|          Loop Count           |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Kolor tła: 32 bity (uint32)
Domyślny kolor tła odbitki na płótnie w kolorach [niebieskim, zielonym, czerwonym, alfa] kolejność bajtów. Ten kolor MOŻE być używany do wypełnienia nieużywanego miejsca na płótnie wokół ramek, a także przezroczyste piksele pierwszej klatki. Kolor tła jest używany również, gdy metoda utylizacji to 1.

Uwaga:

  • Kolor tła MOŻE zawierać nieprzezroczystą wartość alfa, nawet jeśli Flaga alfa w VP8X Fragment nie jest ustawiony.

  • Aplikacje przeglądające POWINNY traktować wartość koloru tła jako wskazówkę nie są wymagane.

  • Obszar roboczy zostanie wyczyszczony na początku każdej pętli. Kolor tła MOŻE być wykorzystane do osiągnięcia tego celu.

Liczba pętli: 16 bitów (uint16)
Liczba zapętleń animacji. Jeśli to 0, oznacza to, że bez końca.

Ten fragment MUSI być widoczny, jeśli w „VP8X” flaga Animacja Fragment został ustawiony. Jeśli flaga Animacja nie jest ustawiona, a ten fragment jest obecny, MUSI być zignorowano.

„ANMF” Fragment:

W przypadku animowanych obrazów ten fragment zawiera informacje o pojedynczej klatce. Jeśli flaga animacji nie jest ustawiona, ten fragment NIE POWINNO być obecny.

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                      ChunkHeader('ANMF')                      |
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                        Frame X                |             ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
...          Frame Y            |   Frame Width Minus One     ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
...             |           Frame Height Minus One              |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                 Frame Duration                |  Reserved |B|D|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
:                         Frame Data                            :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Ramka X: 24 bity (uint24)
Współrzędna X lewego górnego rogu klatki to Frame X * 2.
Ramka Y: 24 bity (uint24)
Współrzędna Y lewego górnego rogu klatki to Frame Y * 2.
Szerokość ramki minus jeden: 24 bity (uint24)
Szerokość klatki, obliczana od 1. Szerokość ramki wynosi 1 + Frame Width Minus One.
Wysokość ramki minus jeden: 24 bity (uint24)
Wysokość klatki, obliczana na podstawie 1. Wysokość klatki wynosi 1 + Frame Height Minus One.
Czas trwania klatki: 24 bity (uint24)
Czas oczekiwania przed wyświetleniem następnej klatki w jednostkach 1 milisekundy. Pamiętaj, że interpretacja wartości Frame Duration 0 (i często <= 10) jest więc jest definiowana przez implementację. Wiele narzędzi i przeglądarek przypisuje jak w przypadku GIF-a.
Zarezerwowana: 6 bitów
MUSI być 0. Czytelnicy MUSZĄ ignorować to pole.
Metoda łączenia (B): 1 bit

Wskazuje, jak przezroczyste mają być przezroczyste piksele bieżącej klatki. z odpowiednimi pikselami poprzedniego obszaru roboczego:

  • 0: korzystaj z łączenia alfa. Po usunięciu poprzedniej klatki wyrenderuj tag bieżącej ramce na obszarze roboczym z użyciem połączenia alfa (patrz poniżej). Jeśli bieżąca ramka nie ma kanału alfa, załóżmy, że wartość alfa wynosi 255, skutecznie zastępując prostokąt.

  • 1: nie mieszaj. Po usunięciu poprzedniej klatki wyrenderuj tag bieżącej ramki na obszarze roboczym przez zastąpienie prostokąta pokrytego w bieżącej ramce.

Metoda utylizacji (D): 1 bit

Wskazuje, jak ma być traktowana bieżąca klatka po jej wyświetleniu. wyświetlone (przed wyrenderowaniem następnej klatki) w obszarze roboczym:

  • 0: nie wyrzucać. Pozostaw obszar roboczy bez zmian.

  • 1: wybierz kolor tła. Wypełnij prostokąt na obszarze roboczym. jest zasłonięta bieżącą klatką, której kolor tła jest określony w tagu „ANIM” Kawałek.

Uwagi:

  • Usuwanie ramki ma zastosowanie tylko do prostokąta ramki, czyli prostokąt zdefiniowany przez wymiary klatka X, klatka Y, szerokość ramki i ramka wysokość. Może ono obejmować cały obszar roboczy, ale nie musi.

  • Mieszanie alfa:

    Biorąc pod uwagę, że każdy kanał R, G, B i A jest 8-bitowy, a kanał RGB kanały nie są wstępnie mnożone przez kanał alfa, czyli wzór mieszania „dst” na „src” to:

    blend.A = src.A + dst.A * (1 - src.A / 255)
    if blend.A = 0 then
      blend.RGB = 0
    else
      blend.RGB =
          (src.RGB * src.A +
           dst.RGB * dst.A * (1 - src.A / 255)) / blend.A
    
  • Mieszanie alfa POWINNY być przeprowadzane w liniowej przestrzeni kolorów, biorąc pod uwagę profil kolorów obrazu. Jeśli profil kolorów to nie ma, należy przyjąć standardową paletę RGB (sRGB). (Pamiętaj, że sRGB też musi być linearna z powodu gamma około 2,2).

Dane ramki: rozmiar fragmentu16 B

Składa się z tych elementów:

Uwaga: plik „ANMF” ładunek, Frame Data, składa się z osobnych dodane fragmenty zgodnie z formatem pliku RIFF.

Alfa

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                      ChunkHeader('ALPH')                      |
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|Rsv| P | F | C |     Alpha Bitstream...                        |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Zarezerwowana (RSv): 2 bity
MUSI być 0. Czytelnicy MUSZĄ ignorować to pole.
Wstępne przetwarzanie (P): 2 bity

Te informacyjne bity są używane do sygnalizowania wstępnego przetwarzania danych, które podczas kompresji. Dekoder może wykorzystać te informacje do: na przykład skorygować wartości lub wygładzić gradienty przed wyświetleniem.

  • 0: bez wstępnego przetwarzania.
  • 1: obniżenie poziomu.

Dekodery nie muszą używać tych informacji w żaden sposób.

Metoda filtrowania (F): 2 bity

Poniżej opisujemy używane metody filtrowania:

  • 0: brak.
  • 1: filtr poziomy.
  • 2: filtr pionowy.
  • 3: filtr gradientu.

Dla każdego piksela filtr wykonuje się według poniższych obliczeń. Załóżmy, że wartości alfa otaczające bieżącą pozycję w polu X są oznaczone w następujący sposób:

 C | B |
---+---+
 A | X |

Staramy się obliczyć wartość alfa dla pozycji X. Po pierwsze: w zależności od metody filtrowania:

  • Metoda 0: prognoza = 0
  • Metoda 1: prognoza = A
  • Metoda 2: prognoza = B
  • Metoda 3: prognoza = klip(A + B - C)

gdzie clip(v) jest równe:

  • 0, jeśli v < 0,
  • 255, jeśli v > 255 lub
  • W przeciwnym razie

Ostateczną wartość uzyskuje się przez dodanie wartości zdekompresowanej X do prognozy i użycie arytmetyki modulo-256 do obcięcia zakresu [256..511] do [0..255]:

alpha = (predictor + X) % 256

Szczególnie zdarza się, że piksel znajduje się skrajnie od lewej lub od góry. Dla: na przykład wartość w lewym górnym rogu lokalizacji (0, 0) używa 0 jako wartości prognozy. W innym przypadku:

  • W przypadku metod filtrowania poziomego lub gradientowego piksele po lewej stronie w jest prognozowana lokalizacja (0, y) na podstawie lokalizacji (0, y-1) tuż powyżej.
  • W przypadku metod filtrowania pionowego lub gradientowego najwyższe piksele w lokalizacja (x, 0) jest prognozowana na podstawie lokalizacji (x-1, 0) po lewej stronie.
Metoda kompresji (C): 2 bity

Zastosowana metoda kompresji:

  • 0: brak kompresji.
  • 1: skompresowany w bezstratnym formacie WebP.
Strumień alfa: rozmiar fragmentu1 bajtów

Zakodowany strumień bitowy w wersji alfa.

Ten opcjonalny fragment zawiera zakodowane dane alfa dla tej ramki. Ramka zawiera ciąg „VP8L” Fragment NIE POWINIEN zawierać tego fragmentu.

Uzasadnienie: informacje o przejrzystości są już uwzględnione w „VP8L”. Kawałek.

Dane kanału alfa są przechowywane jako nieskompresowane nieprzetworzone dane (gdy metoda kompresji „0”) lub skompresowana przy użyciu formatu bezstratnego (gdy metoda kompresji ma wartość „1”).

  • Nieprzetworzone dane: składają się z sekwencji bajtów o długości = szerokość * wysokość, zawierający wszystkie 8-bitowe wartości przezroczystości w kolejności skanowania.

  • Kompresja bezstratna formatu: sekwencja bajtów jest skompresowana image-stream (jak opisano w sekcji „WebP Lossless Bitstream Format” w formacie WebP) o niejawnych wymiarach szerokość x wysokość. Oznacza to, że image-stream NIE zawiera żadnych nagłówków opisujących wymiary obrazu.

    Uzasadnienie: wymiary są już znane z innych źródeł, dlatego ich ponowne przechowywanie byłoby zbędne i zwiększyło się ryzyko błędów.

    Po zdekodowaniu strumienia obrazów na kolor alfa, czerwony, zielony, niebieski (ARGB) zgodnie z procesem opisanym w formacie bezstratnym specyfikacji, informacje o przejrzystości muszą zostać wyodrębnione z zielony kanał czworoboku ARGB.

    Uzasadnienie: zielony kanał jest dopuszczalny do dodatkowej transformacji. podane w specyfikacji – w przeciwieństwie do innych kanałów – które mogą i zwiększyć kompresję.

Strumień bitów (VP8/VP8L)

Ten fragment zawiera skompresowane dane strumienia bitowego dla pojedynczej klatki.

Fragmentem bitów strumienia może być (i) „VP8” Fragment, używający „VP8” (zwróć uwagę na znacznej spacji z czterema znakami) jako jej ciąg FourCC lub (ii) „VP8L” Kawałek, przy użyciu „VP8L” jako firma FourCC.

Formaty plików „VP8” i „VP8L” Fragmenty są opisane w sekcjach Prosty format pliku (strata) i Prosty format plików (bezstratny).

Profil kolorów

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                      ChunkHeader('ICCP')                      |
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
:                       Color Profile                           :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Profil kolorów: rozmiar fragmentu (w bajtach)
Profil ICC.

Ten fragment MUSI pojawić się przed danymi obrazu.

POWINIEN musi istnieć co najmniej jeden taki fragment. Jeśli jest więcej takich fragmentów, MOŻE ignorować wszystkie oprócz pierwszego. Szczegóły znajdziesz w specyfikacji ICC.

Jeśli ten fragment nie jest dostępny, należy założyć sRGB.

Metadane

Metadane mogą być przechowywane w pliku „EXIF” lub „XMP ” Kawałki.

Może istnieć tylko jeden fragment każdego typu („EXIF” i „XMP ”). Jeśli więcej takich fragmentów, czytelnicy MOGĄ zignorować wszystkie z wyjątkiem pierwszego.

Fragmenty są zdefiniowane w ten sposób:

„EXIF” Fragment:

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                      ChunkHeader('EXIF')                      |
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
:                        Exif Metadata                          :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Metadane Exif: rozmiar fragmentu (w bajtach)
Metadane obrazu w formacie Exif.

„XMP” Fragment:

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                      ChunkHeader('XMP ')                      |
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
:                        XMP Metadata                           :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Metadane XMP: rozmiar fragmentu (w bajtach)
Metadane obrazu w formacie XMP.

Pamiętaj, że czwarty znak w polu „XMP ” FourCC jest spacją ASCII (0x20).

Dodatkowe wskazówki na temat obsługi metadanych znajdziesz w „Wytyczne dotyczące obsługi metadanych” w grupie roboczej ds. metadanych.

Nieznane fragmenty

Fragment RIFF (opisany w sekcji Format pliku RIFF) którego FourCC różni się od któregokolwiek z fragmentów opisanych w tym dokumencie, uznaliśmy za nieznany fragment.

Uzasadnienie: zezwolenie na nieznane fragmenty zapewnia możliwość przedłużenia terminu w przyszłości. formatu, a także umożliwia przechowywanie dowolnych danych dotyczących aplikacji.

Plik MOŻE zawierać nieznane fragmenty:

Czytelnicy powinni ignorować te fragmenty. Autorzy powinni zachować w swoich w pierwotnej kolejności (chyba że rzeczywiście chcą zmodyfikować te fragmenty).

Montaż odbitek na płótnie z ramek

Tutaj dowiesz się, jak czytelnik MUSI złożyć odbitkę na płótnie w takim przypadku: animowanego obrazu.

Proces zaczyna się od utworzenia obszaru roboczego o wymiarach podanych w tagu „VP8X” Fragment o szerokości Canvas Width Minus One + 1 piks. i wysokości Canvas Height Minus One + 1 piks. Pole Loop Count z tabeli „ANIM” Kawałek kontroluje sposób wiele razy proces animacji. To jest Loop Count - 1 dla niezerowe wartości Loop Count lub nieskończona, jeśli Loop Count wynosi zero.

Na początku każdej iteracji w pętli obszar roboczy jest wypełniany za pomocą atrybutu kolor tła z obrazu „ANIM” Kawałek lub kolor zdefiniowany przez aplikację.

„ANMF” Fragmenty zawierają pojedyncze klatki podane w kolejności wyświetlania. Przed wyrenderowaniem w przypadku każdej klatki stosowany jest atrybut Disposal method poprzedniej klatki.

Renderowanie zdekodowanej klatki rozpoczyna się od współrzędnych kartezjańskich (2 * Frame X, 2 * Frame Y), a punktem początkowym jest lewy górny róg obszaru roboczego. Frame Width Minus One + 1 piks. szerokości na Frame Height Minus One + 1 piks. są renderowane na obszarze roboczym za pomocą Blending method.

Obszar roboczy jest wyświetlany przez Frame Duration ms. Proces ten trwa do wszystkie klatki podane przez „ANMF” Fragmenty zostały wyświetlone. Nowa iteracja w pętli to lub obszar roboczy pozostaje w stanie końcowym, jeśli wszystkie iteracje zostały .

Poniższy pseudokod ilustruje proces renderowania. Zapis VP8X.field oznacza pole w ciągu „VP8X” Fragment z tym samym opisem.

VP8X.flags.hasAnimation MUST be TRUE
canvas ← new image of size VP8X.canvasWidth x VP8X.canvasHeight with
         background color ANIM.background_color or
         application-defined color.
loop_count ← ANIM.loopCount
dispose_method ← Dispose to background color
if loop_count == 0:
  loop_count = ∞
frame_params ← nil
next chunk in image_data is ANMF MUST be TRUE
for loop = 0..loop_count - 1
  clear canvas to ANIM.background_color or application-defined color
  until eof or non-ANMF chunk
    frame_params.frameX = Frame X
    frame_params.frameY = Frame Y
    frame_params.frameWidth = Frame Width Minus One + 1
    frame_params.frameHeight = Frame Height Minus One + 1
    frame_params.frameDuration = Frame Duration
    frame_right = frame_params.frameX + frame_params.frameWidth
    frame_bottom = frame_params.frameY + frame_params.frameHeight
    VP8X.canvasWidth >= frame_right MUST be TRUE
    VP8X.canvasHeight >= frame_bottom MUST be TRUE
    for subchunk in 'Frame Data':
      if subchunk.tag == "ALPH":
        alpha subchunks not found in 'Frame Data' earlier MUST be
          TRUE
        frame_params.alpha = alpha_data
      else if subchunk.tag == "VP8 " OR subchunk.tag == "VP8L":
        bitstream subchunks not found in 'Frame Data' earlier MUST
          be TRUE
        frame_params.bitstream = bitstream_data
    apply dispose_method.
    render frame with frame_params.alpha and frame_params.bitstream
      on canvas with top-left corner at (frame_params.frameX,
      frame_params.frameY), using Blending method
      frame_params.blendingMethod.
    canvas contains the decoded image.
    Show the contents of the canvas for
    frame_params.frameDuration * 1 ms.
    dispose_method = frame_params.disposeMethod

Przykładowe układy plików

Obraz z kodowaniem stratnym w wersji alfa może wyglądać tak:

RIFF/WEBP
+- VP8X (descriptions of features used)
+- ALPH (alpha bitstream)
+- VP8 (bitstream)

Obraz zakodowany bezstratnie może wyglądać tak:

RIFF/WEBP
+- VP8X (descriptions of features used)
+- VP8L (lossless bitstream)
+- XYZW (unknown chunk)

Obraz w formacie bezstratnym z profilem ICC i metadanymi XMP może wyglądają tak:

RIFF/WEBP
+- VP8X (descriptions of features used)
+- ICCP (color profile)
+- VP8L (lossless bitstream)
+- XMP  (metadata)

Animowany obraz z metadanymi Exif może wyglądać tak:

RIFF/WEBP
+- VP8X (descriptions of features used)
+- ANIM (global animation parameters)
+- ANMF (frame1 parameters + data)
+- ANMF (frame2 parameters + data)
+- ANMF (frame3 parameters + data)
+- ANMF (frame4 parameters + data)
+- EXIF (metadata)