Spesifikasi Penampung WebP

Pengantar

WebP adalah format gambar yang menggunakan (i) encoding frame kunci VP8 untuk mengompresi data gambar dengan cara lossy atau (ii) encoding lossless WebP. Skema encoding ini akan membuatnya lebih efisien daripada format lama, seperti JPEG, GIF, dan PNG. Dioptimalkan untuk transfer gambar yang cepat melalui jaringan (misalnya, untuk situs). Format WebP juga memiliki paritas fitur (profil warna, metadata, animasi, dll.) dengan format lainnya. Dokumen ini menjelaskan struktur file WebP.

Penampung WebP (yaitu, penampung RIFF untuk WebP) memungkinkan dukungan fitur di atas dan di luar kasus penggunaan dasar WebP (yaitu, file yang berisi satu gambar yang dienkode sebagai frame kunci VP8). Penampung WebP memberikan dukungan tambahan untuk hal berikut:

  • Kompresi Lossless: Gambar dapat dikompresi secara lossless, menggunakan Format WebP Lossless.

  • Metadata: Gambar mungkin memiliki metadata yang disimpan dalam format Format File Gambar yang Dapat Ditukar (Exif) atau Platform Metadata yang Dapat Diperluas (XMP).

  • Transparansi: Gambar dapat memiliki transparansi, yaitu saluran alfa.

  • Profil Warna: Gambar mungkin memiliki profil ICC tersemat seperti yang dijelaskan oleh International Color Consortium.

  • Animasi: Gambar mungkin memiliki beberapa frame dengan jeda di antaranya, sehingga menjadikannya animasi.

Penamaan

Sebaiknya gunakan jenis berikut saat merujuk ke penampung WebP:

Nama Format ContainerWebP
Ekstensi Nama File.webp
Jenis MIMEimage/webp
Uniform Type Identifierorg.webmproject.webp

Terminologi & Dasar-Dasar

Kata kunci "HARUS", "TIDAK BOLEH", "DIBUTUHKAN", "SHALL", "TIDAK BOLEH", "HARUSKAN", "TIDAK BOLEH", "DIREKOMENDASIKAN", "TIDAK DIREKOMENDASIKAN", "DAPAT", dan "OPSIONAL" dalam dokumen ini akan ditafsirkan sebagaimana dijelaskan dalam BCP 14 RFC 2119 RFC 8174, seperti yang ditampilkan dalam huruf besar semua, dan hanya jika, ditampilkan di sini.

File WebP berisi gambar diam (yaitu, matriks piksel yang dienkode) atau animasi. Secara opsional, file ini juga dapat berisi informasi transparansi, profil warna, dan metadata. Kita menyebut matriks piksel sebagai kanvas gambar.

Penomoran bit dalam diagram bagian dimulai dari 0 untuk bit yang paling signifikan ('MSB 0'), seperti yang dijelaskan dalam RFC 1166.

Berikut adalah istilah tambahan yang digunakan di seluruh dokumen ini:

Pembaca/Penulis
Kode yang membaca file WebP disebut sebagai pembaca, sedangkan kode yang menulisnya disebut sebagai writer.
uint16
Bilangan bulat 16-bit, little-endian, tanpa tanda.
uint24
Bilangan bulat 24-bit, little-endian, tanpa tanda.
uint32
Bilangan bulat 32-bit, little-endian, tanpa tanda.
FourCC
Kode empat karakter (FourCC) adalah uint32 yang dibuat dengan menggabungkan empat karakter ASCII dalam urutan little-endian. Ini berarti 'aaaa' (0x61616161) dan 'AAAA' (0x41414141) diperlakukan sebagai FourCCs yang berbeda.
Berbasis 1
Bidang bilangan bulat tanpa tanda tangan yang menyimpan nilai yang diimbangi dengan -1, misalnya, kolom tersebut akan menyimpan nilai 25 sebagai 24.
ChunkHeader('ABCD')
Digunakan untuk mendeskripsikan header FourCC dan Chunk Size dari setiap bagian, dengan 'ABCD' adalah FourCC untuk bagian tersebut. Ukuran elemen ini adalah 8 byte.

Format File RIFF

Format file WebP didasarkan pada format dokumen RIFF (Resource Interchange File Format).

Elemen dasar file RIFF adalah chunk. Fitur ini terdiri dari:

 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                         :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Chunk FourCC: 32 bit
Kode empat karakter ASCII yang digunakan untuk identifikasi potongan.
Ukuran Chunk: 32 bit (uint32)
Ukuran potongan dalam byte, tidak termasuk kolom ini, ID potongan, atau padding.
Payload Chunk: Ukuran Chunk byte
Payload data. Jika Chunk Size ganjil, byte padding tunggal -- yang HARUS berupa 0 agar sesuai dengan RIFF -- akan ditambahkan.

Catatan: RIFF memiliki konvensi bahwa FourCC chunk huruf besar semua adalah chunk standar yang berlaku untuk format file RIFF apa pun, sedangkan FourCC khusus untuk format file semuanya huruf kecil. WebP tidak mengikuti konvensi ini.

Header File 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 bit
Karakter ASCII 'R', 'I', 'F', 'F'.
Ukuran File: 32 bit (uint32)
Ukuran file dalam byte, dimulai dari offset 8. Nilai maksimum kolom ini adalah 2^32 dikurangi 10 byte sehingga ukuran seluruh file maksimal 4 GiB dikurangi 2 byte.
'WEBP': 32 bit
Karakter ASCII 'W', 'E', 'B', 'P'.

File WebP HARUS diawali dengan header RIFF dengan FourCC 'WEBP'. Ukuran file di header adalah total ukuran potongan yang mengikuti ditambah 4 byte untuk FourCC 'WEBP'. File TIDAK BOLEH berisi data apa pun setelah data yang ditentukan oleh Ukuran File. Pembaca DAPAT mengurai file tersebut, dengan mengabaikan data akhir. Karena ukuran setiap bagian genap, ukuran yang diberikan oleh header RIFF juga genap. Isi setiap potongan dijelaskan di bagian berikut.

Format File Sederhana (Lossy)

Tata letak ini HARUS digunakan jika gambar memerlukan encoding lossy dan tidak memerlukan transparansi atau fitur lanjutan lainnya yang disediakan oleh format yang diperluas. File dengan tata letak ini lebih kecil dan didukung oleh software lama.

Format file WebP sederhana (lossy):

 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                           :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Chunk 'VP8 ':

 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                            :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Data VP8: Ukuran Potongan byte
Data bitstream VP8.

Perhatikan bahwa karakter keempat dalam FourCC 'VP8 ' adalah spasi ASCII (0x20).

Spesifikasi format bitstream VP8 dijelaskan dalam Panduan Format Data dan Dekode VP8. Perhatikan bahwa header frame VP8 berisi lebar dan tinggi frame VP8. Nilai ini diasumsikan sebagai lebar dan tinggi kanvas.

Spesifikasi VP8 menjelaskan cara mendekode gambar ke dalam format Y'CbCr. Untuk mengonversi ke RGB, Rekomendasi BT.601 HARUS digunakan. Aplikasi DAPAT menggunakan metode konversi lain, tetapi hasil visual dapat berbeda di antara dekoder.

Format File Sederhana (Tanpa Kompresi)

Catatan: Pembaca lama mungkin tidak mendukung file yang menggunakan format lossless.

Tata letak ini HARUS digunakan jika gambar memerlukan encoding lossless (dengan saluran transparansi opsional) dan tidak memerlukan fitur lanjutan yang disediakan oleh format yang diperluas.

Format file WebP sederhana (tanpa kompresi):

 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                          :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Chunk 'VP8L':

 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                           :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Data VP8L: byte Ukuran Chunk
Data aliran bit VP8L.

Spesifikasi bitstream VP8L saat ini dapat ditemukan di Format Bitstream Lossless WebP. Perhatikan bahwa header VP8L berisi lebar dan tinggi gambar VP8L. Nilai ini diasumsikan sebagai lebar dan tinggi kanvas.

Format File yang Diperluas

Catatan: Pembaca lama mungkin tidak mendukung file yang menggunakan format yang diperluas.

File format yang diperluas terdiri dari:

  • Chunk 'VP8X' dengan informasi tentang fitur yang digunakan dalam file.

  • Chunk 'ICCP' opsional dengan profil warna.

  • Chunk 'ANIM' opsional dengan data kontrol animasi.

  • Data gambar.

  • Potongan 'EXIF' opsional dengan metadata Exif.

  • Chunk 'XMP ' opsional dengan metadata XMP.

  • Daftar opsional potongan yang tidak diketahui.

Untuk gambar diam, data gambar terdiri dari satu frame, yang terdiri dari:

Untuk gambar animasi, data gambar terdiri dari beberapa frame. Detail selengkapnya tentang frame dapat ditemukan di bagian Animasi.

Semua bagian yang diperlukan untuk rekonstruksi dan koreksi warna, yaitu 'VP8X', 'ICCP', 'ANIM', 'ANMF', 'ALPH', 'VP8 ', dan 'VP8L', HARUS muncul dalam urutan yang dijelaskan sebelumnya. Pembaca HARUS gagal jika bagian yang diperlukan untuk rekonstruksi dan koreksi warna tidak berurutan.

Metadata dan chunk tidak dikenal DAPAT muncul dalam urutan yang salah.

Alasan: Bagian yang diperlukan untuk rekonstruksi harus muncul terlebih dahulu dalam file agar pembaca dapat mulai mendekode gambar sebelum menerima semua data. Aplikasi dapat memperoleh manfaat dari memvariasikan urutan metadata dan bagian kustom agar sesuai dengan penerapan.

Header file WebP yang diperluas:

 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    |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Dicadangkan (Rsv): 2 bit
HARUS berupa 0. Pembaca HARUS mengabaikan kolom ini.
Profil ICC (I): 1 bit
Tetapkan jika file berisi Chunk 'ICCP'.
Alfa (L): 1 bit
Tetapkan jika salah satu frame gambar berisi informasi transparansi ("alfa").
Metadata Exif (E): 1 bit
Tetapkan jika file berisi metadata Exif.
Metadata XMP (X): 1 bit
Tetapkan jika file berisi metadata XMP.
Animasi (A): 1 bit
Setel jika ini adalah gambar animasi. Data dalam Chunk 'ANIM' dan 'ANMF' harus digunakan untuk mengontrol animasi.
Dicadangkan (R): 1 bit
HARUS berupa 0. Pembaca HARUS mengabaikan kolom ini.
Direservasi: 24 bit
HARUS berupa 0. Pembaca HARUS mengabaikan kolom ini.
Lebar Kanvas Minus Satu: 24 bit
Lebar kanvas berbasis 1 dalam piksel. Lebar kanvas sebenarnya adalah 1 + Canvas Width Minus One.
Tinggi Kanvas Minus Satu: 24 bit
Tinggi kanvas
berbasis 1 dalam piksel. Tinggi kanvas sebenarnya adalah 1 + Canvas Height Minus One.

Produk Lebar Kanvas dan Tinggi Kanvas HARUS maksimal 2^32 - 1.

Spesifikasi mendatang mungkin menambahkan lebih banyak kolom. Kolom tidak dikenal HARUS diabaikan.

Animasi

Animasi dikontrol oleh Chunk 'ANIM' dan 'ANMF'.

Potongan 'ANIM':

Untuk gambar animasi, bagian ini berisi parameter global animasi.

 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           |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Warna Latar Belakang: 32 bit (uint32)
Warna latar belakang default kanvas dalam urutan byte [Blue, Green, Red, Alpha]. Warna ini MUNGKIN digunakan untuk mengisi ruang yang tidak digunakan di kanvas di sekitar bingkai, serta piksel transparan dari bingkai pertama. Warna latar belakang juga digunakan saat metode Disposal adalah 1.

Catatan:

  • Warna latar belakang DAPAT berisi nilai alfa yang tidak buram, meskipun tanda Alpha di Chunk'VP8X' tidak ditetapkan.

  • Aplikasi penampil HARUS memperlakukan nilai warna latar belakang sebagai petunjuk dan tidak diwajibkan untuk menggunakannya.

  • Kanvas dibersihkan di awal setiap loop. Warna latar belakang DAPAT digunakan untuk mencapai hal ini.

Jumlah Loop: 16 bit (uint16)
Frekuensi untuk mengulang animasi. Jika 0, artinya tanpa batas.

Bagian ini HARUS muncul jika tanda Animation di Bagian 'VP8X' ditetapkan. Jika tanda Animation tidak ditetapkan dan potongan ini ada, tanda ini HARUS diabaikan.

Bagian 'ANMF':

Untuk gambar animasi, potongan ini berisi informasi tentang satu frame. Jika Flag Animation tidak disetel, potongan ini SEHARUSNYA TIDAK ada.

 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                            :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Frame X: 24 bit (uint24)
Koordinat X dari sudut kiri atas bingkai adalah Frame X * 2.
Frame Y: 24 bit (uint24)
Koordinat Y dari sudut kiri atas bingkai adalah Frame Y * 2.
Lebar Frame Minus Satu: 24 bit (uint24)
Lebar frame berbasis 1. Lebar bingkai adalah 1 + Frame Width Minus One.
Tinggi Frame Minus Satu: 24 bit (uint24)
Tinggi bingkai berbasis 1. Tinggi bingkai adalah 1 + Frame Height Minus One.
Durasi Frame: 24 bit (uint24)
Waktu tunggu sebelum menampilkan frame berikutnya, dalam satuan 1 milidetik. Perhatikan bahwa interpretasi Durasi Frame 0 (dan sering kali <= 10) ditentukan oleh implementasi. Banyak alat dan browser menetapkan durasi minimum yang mirip dengan GIF.
Direservasi: 6 bit
HARUS berupa 0. Pembaca HARUS mengabaikan kolom ini.
Metode penggabungan (B): 1 bit

Menunjukkan cara menggabungkan piksel transparan frame saat ini dengan piksel yang sesuai dari kanvas sebelumnya:

  • 0: Menggunakan penggabungan alfa. Setelah membuang frame sebelumnya, render frame saat ini di kanvas menggunakan pencampuran alfa (lihat di bawah). Jika bingkai saat ini tidak memiliki saluran alfa, asumsikan nilai alfa adalah 255, yang secara efektif menggantikan persegi panjang.

  • 1: Jangan gabungkan. Setelah membuang frame sebelumnya, render frame saat ini di kanvas dengan menimpa persegi panjang yang tercakup oleh frame saat ini.

Metode pembuangan (D): 1 bit

Menunjukkan cara frame saat ini akan diperlakukan setelah ditampilkan (sebelum merender frame berikutnya) di kanvas:

  • 0: Jangan hapus. Biarkan kanvas apa adanya.

  • 1: Menghapus ke warna latar belakang. Isi persegi panjang pada kanvas yang tercakup dalam bingkai saat ini dengan warna latar belakang yang ditentukan dalam Chunk'ANIM'.

Catatan:

  • Pembuangan frame hanya berlaku untuk bingkai persegi panjang, yaitu, persegi panjang yang ditentukan oleh Frame X, Frame Y, lebar bingkai, dan tinggi frame. Gambar mungkin mencakup seluruh kanvas atau tidak.

  • Penggabungan alfa:

    Mengingat bahwa setiap saluran R, G, B, dan A adalah 8 bit, dan saluran RGB tidak dihitung sebelumnya dengan alfa, formula untuk menggabungkan 'dst' ke 'src' adalah:

    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
    
  • Penggabungan alfa HARUS dilakukan dalam ruang warna linear, dengan mempertimbangkan profil warna gambar. Jika profil warna tidak ada, RGB standar (sRGB) akan digunakan. (Perhatikan bahwa sRGB juga perlu dilinearisasi karena gamma ~2,2.)

Data Frame: Chunk Size byte - 16

Terdiri dari:

Catatan: Payload 'ANMF', Frame Data, terdiri dari setiap segmen yang ditambahkan padding, seperti yang dijelaskan oleh format file 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...                        |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Dicadangkan (Rsv): 2 bit
HARUS 0. Pembaca HARUS mengabaikan kolom ini.
Prapemrosesan (P): 2 bit

Bit informatif ini digunakan untuk memberikan sinyal prapemrosesan yang telah dilakukan selama kompresi. Decoder dapat menggunakan informasi ini, misalnya untuk menguraikan nilai atau memperhalus gradien sebelum ditampilkan.

  • 0: Tidak ada prapemrosesan.
  • 1: Pengurangan level.

Decoder tidak diperlukan untuk menggunakan informasi ini dengan cara yang ditentukan.

Metode pemfilteran (F): 2 bit

Metode pemfilteran yang digunakan dijelaskan sebagai berikut:

  • 0: Tidak ada.
  • 1: Filter horizontal.
  • 2: Filter vertikal.
  • 3: Filter gradien.

Untuk setiap piksel, pemfilteran dilakukan dengan menggunakan penghitungan berikut. Asumsikan nilai alfa yang mengelilingi posisi X saat ini diberi label sebagai:

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

Kita ingin menghitung nilai alfa pada posisi X. Pertama, prediksi dibuat bergantung pada metode pemfilteran:

  • Metode 0: predictor = 0
  • Metode 1: predictor = A
  • Metode 2: prediktor = B
  • Metode 3: predictor = clip(A + B - C)

dengan clip(v) sama dengan:

  • 0 jika v < 0,
  • 255 jika v > 255, atau
  • v sebaliknya

Nilai akhir diperoleh dengan menambahkan nilai X yang didekompresi ke prediktor dan menggunakan aritmetika modulo-256 untuk menggabungkan rentang [256..511] ke dalam rentang [0..255]:

alpha = (predictor + X) % 256

Ada kasus khusus untuk posisi piksel paling kiri dan paling atas. Misalnya, nilai kiri atas di lokasi (0, 0) menggunakan 0 sebagai nilai prediktor. Atau:

  • Untuk metode pemfilteran horizontal atau gradien, piksel paling kiri di lokasi (0, y) diprediksi menggunakan lokasi (0, y-1) tepat di atas.
  • Untuk metode pemfilteran vertikal atau gradien, piksel teratas pada lokasi (x, 0) diprediksi menggunakan lokasi (x-1, 0) di sebelah kiri.
Metode kompresi (C): 2 bit

Metode kompresi yang digunakan:

  • 0: Tanpa kompresi.
  • 1: Dikompresi menggunakan format lossless WebP.
Bitstream alfa: Chunk Size byte - 1

Bitstream alfa yang dienkode.

Bagian opsional ini berisi data alfa yang dienkode untuk frame ini. Frame yang berisi Chunk 'VP8L' TIDAK BOLEH berisi chunk ini.

Alasan: Informasi transparansi sudah menjadi bagian dari 'VP8L' Chunk.

Data saluran alfa disimpan sebagai data mentah yang tidak dikompresi (jika metode kompresinya adalah '0') atau dikompresi menggunakan format lossless (jika metode kompresinya adalah '1').

  • Data mentah: Ini terdiri dari urutan byte dengan panjang = lebar * tinggi, yang berisi semua nilai transparansi 8-bit dalam urutan pemindaian.

  • Kompresi format lossless: Urutan byte adalah streaming gambar yang dikompresi (seperti yang dijelaskan dalam "Format Bitstream Lossless WebP") dari dimensi implisit lebar x tinggi. Artinya, streaming gambar ini TIDAK berisi header yang menjelaskan dimensi gambar.

    Alasan: Dimensi sudah diketahui dari sumber lain, sehingga menyimpannya lagi akan berlebihan dan rentan terhadap error.

    Setelah aliran gambar didekode menjadi nilai warna Alfa, Merah, Hijau, Biru (ARGB), dengan mengikuti proses yang dijelaskan dalam spesifikasi format lossless, informasi transparansi harus diekstrak dari saluran hijau pada kuadrat ARGB.

    Alasan: Channel hijau diizinkan untuk melakukan langkah transformasi tambahan dalam spesifikasi -- tidak seperti channel lainnya -- yang dapat meningkatkan kompresi.

Bitstream (VP8/VP8L)

Potongan ini berisi data bitstream terkompresi untuk satu {i>frame<i}.

Potongan bitstream dapat berupa (i) Potongan 'VP8', menggunakan 'VP8' (perhatikan ruang karakter keempat yang signifikan) sebagai FourCC-nya, atau (ii) Bagian 'VP8L', menggunakan 'VP8L' sebagai FourCC-nya.

Format Chunk 'VP8 ' dan 'VP8L' dijelaskan masing-masing di bagian Format File Sederhana (Lossy) dan Format File Sederhana (Lossless).

Profil Warna

 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 Warna: Chunk Size byte
Profil ICC.

Bagian ini HARUS muncul sebelum data gambar.

HARUS ada maksimal satu bagian tersebut. Jika ada lebih banyak bagian tersebut, pembaca DAPAT mengabaikan semua kecuali yang pertama. Lihat Spesifikasi ICC untuk mengetahui detailnya.

Jika bagian ini tidak ada, sRGB HARUS diasumsikan.

Metadata

Metadata dapat disimpan dalam Potongan 'EXIF' atau 'XMP '.

HARUS ada maksimal satu bagian dari setiap jenis ('EXIF' dan 'XMP '). Jika ada lebih banyak bagian tersebut, pembaca DAPAT mengabaikan semua kecuali yang pertama.

Potongan didefinisikan sebagai berikut:

Chunk 'EXIF':

 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                          :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Metadata Exif: byte Ukuran Chunk
Metadata gambar dalam format Exif.

Chunk 'XMP ':

 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                           :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Metadata XMP: Ukuran Chunk byte
Metadata gambar dalam format XMP.

Perhatikan bahwa karakter keempat dalam FourCC 'XMP ' adalah spasi ASCII (0x20).

Panduan tambahan tentang penanganan metadata dapat ditemukan di "Panduan untuk Menangani Metadata" dari Metadata Working Group.

Potongan Tidak Diketahui

Chunk RIFF (dijelaskan di bagian Format File RIFF) yang FourCC-nya berbeda dengan chunk apa pun yang dijelaskan dalam dokumen ini, dianggap sebagai chunk yang tidak diketahui.

Alasan: Mengizinkan potongan yang tidak diketahui akan memberikan penyediaan untuk ekstensi format di masa mendatang dan juga memungkinkan penyimpanan data khusus aplikasi.

File DAPAT berisi potongan yang tidak dikenal:

Pembaca HARUS mengabaikan potongan-potongan ini. Penulis HARUS mempertahankannya dalam urutan awalnya (kecuali jika mereka secara khusus bermaksud memodifikasi potongan ini).

Perakitan Kanvas dari Bingkai

Di sini, kami memberikan ringkasan tentang cara pembaca HARUS menyusun kanvas dalam kasus gambar animasi.

Prosesnya dimulai dengan membuat kanvas menggunakan dimensi yang diberikan dalam Potongan 'VP8X', dengan lebar Canvas Width Minus One + 1 piksel dan tinggi Canvas Height Minus One + 1 piksel. Kolom Loop Count dari Chunk 'ANIM' mengontrol berapa kali proses animasi diulang. Nilai ini Loop Count - 1 untuk nilai Loop Count yang bukan nol atau tak terbatas jika Loop Count adalah nol.

Pada awal setiap iterasi loop, kanvas diisi menggunakan warna latar belakang dari Bagian 'ANIM' atau warna yang ditentukan aplikasi.

Potongan 'ANMF' berisi setiap frame yang diberikan dalam urutan tampilan. Sebelum merender setiap frame, Disposal method frame sebelumnya diterapkan.

Rendering frame yang didekode dimulai pada koordinat Kartesius (2 * Frame X, 2 * Frame Y), menggunakan sudut kiri atas kanvas sebagai titik asal. Lebar Frame Width Minus One + 1 piksel dan tinggi Frame Height Minus One + 1 piksel dirender ke kanvas menggunakan Blending method.

Kanvas ditampilkan selama Frame Duration milidetik. Hal ini berlanjut hingga semua frame yang diberikan oleh Chunk 'ANMF' telah ditampilkan. Iterasi loop baru kemudian dimulai, atau kanvas dibiarkan dalam status akhirnya jika semua iterasi telah selesai.

Pseudocode berikut menggambarkan proses rendering. Notasi VP8X.field berarti kolom dalam Chunk 'VP8X' dengan deskripsi yang sama.

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

Contoh Tata Letak File

Gambar yang dienkode dengan lossy dan alfa mungkin terlihat seperti berikut:

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

Gambar yang dienkode dengan lossless mungkin akan terlihat seperti berikut:

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

Gambar lossless dengan profil ICC dan metadata XMP dapat terlihat sebagai berikut:

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

Gambar animasi dengan metadata Exif mungkin terlihat seperti berikut:

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)