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 cepat melalui jaringan (misalnya, untuk situs). Format WebP memiliki paritas fitur (profil warna, metadata, animasi, dll.) dengan format lain juga. Dokumen ini menjelaskan struktur file WebP.
Penampung WebP (yaitu, penampung RIFF untuk WebP) memungkinkan dukungan fitur di atas dan di atas kasus penggunaan dasar WebP (yaitu, file yang berisi satu gambar yang dienkode sebagai frame kunci VP8). Penampung WebP memberikan dukungan tambahan untuk:
Kompresi lossless. Gambar dapat dikompresi secara lossless, menggunakan Format lossless WebP.
Metadata. Gambar mungkin memiliki metadata yang disimpan dalam format Exif atau XMP.
Transparansi. Gambar mungkin memiliki transparansi, yaitu saluran alfa.
Profil Warna. Gambar mungkin memiliki profil ICC yang disematkan seperti yang dijelaskan oleh Konsorsium Warna Internasional.
Animasi. Sebuah gambar mungkin memiliki beberapa frame dengan jeda di antara keduanya, sehingga menjadikannya animasi.
Kata kunci "HARUS", "TIDAK PERLU", "DIPERLUKAN", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "recommended", "NOT recommended", "MAY", dan "OPTIONAL" dalam dokumen ini harus ditafsirkan seperti yang dijelaskan dalam BCP 14 RFC 2119 RFC 8174 jika, dan hanya jika, semuanya muncul dalam huruf kapital.
Penomoran bit dalam diagram potongan dimulai dari 0
untuk bit yang paling signifikan
(MSB 0') seperti yang dijelaskan di RFC 1166.
Penamaan
DIREKOMENDASIKAN untuk menggunakan jenis berikut saat merujuk ke penampung WebP:
Nama Format Penampung | WebP |
Ekstensi Nama File | .webp |
Jenis MIME | gambar/webp |
ID Jenis Seragam | org.webmproject.webp |
Terminologi & Dasar-Dasar
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. Kami menyebut matriks piksel sebagai kanvas gambar.
Berikut istilah tambahan yang digunakan di seluruh dokumen ini:
- Pembaca/Penulis
- Kode yang membaca file WebP disebut pembaca, sedangkan kode yang menulisnya disebut sebagai penulis.
- uint16
- Integer 16-bit, small-endian, tanpa tanda tangan.
- uint24
- Integer 24-bit, small-endian, tanpa tanda tangan.
- uint32
- Bilangan bulat 32-bit, small-endian, tanpa tanda tangan.
- FCCCC
- FourCC (kode empat karakter) adalah uint32 yang dibuat dengan menggabungkan empat karakter ASCII dalam urutan small-endian. Artinya, 'aaaa' (0x61616161) dan 'AAAA' (0x41414141) diperlakukan sebagai FourCC yang berbeda.
- Berbasis 1
- Misalnya, kolom bilangan bulat tanpa tanda tangan yang menyimpan nilai offset, misalnya
-1
, misalnya, kolom tersebut akan menyimpan nilai 25 sebagai 24. - ChunkHeader('ABCD')
- Ini digunakan untuk mendeskripsikan header FourCC dan Chunk Size dari setiap bagian, dengan 'ABCD' adalah FourCC untuk potongan 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 bagian. 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.
- Potongan Ukuran: 32 bit (uint32)
- Ukuran potongan dalam byte, tidak termasuk kolom ini, ID potongan atau padding.
- Payload Chunk: Byte Ukuran Chunk
- Payload data. Jika Chunk Size ganjil, satu byte padding -- yang HARUS
0
agar sesuai dengan RIFF -- akan ditambahkan.
Catatan: RIFF memiliki konvensi bahwa potongan empat huruf besar di atas adalah FourCCs yang berlaku untuk format file RIFF apa pun, sedangkan FourCCs 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 mulai dari offset 8. Nilai maksimum kolom ini adalah 2^32 dikurangi 10 byte, sehingga ukuran keseluruhan file adalah maksimum 4 GiB dikurangi 2 byte.
- 'WEBP': 32 bit
- Karakter ASCII 'W' 'E' 'B' 'P'.
File WebP HARUS dimulai dengan header RIFF dengan FourCC 'WEBP'. Ukuran file dalam header adalah ukuran total potongan yang mengikuti ditambah 4
byte untuk 'WEBP' FourCC. File TIDAK HARUS berisi data apa pun setelah data
ditentukan oleh Ukuran File. Pembaca MUNGKIN mengurai file tersebut, dengan mengabaikan data
di akhir. Ukuran potongan apa pun adalah genap, ukuran yang diberikan oleh header RIFF juga genap. Konten setiap potongan dijelaskan di bagian
berikut.
Format File Sederhana (Hilang)
Tata letak ini SEBAIKNYA 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 yang lebih lama.
Format file WebP (lossy) sederhana:
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 :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Potongan 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 Chunk byte
- Data bitstream VP8.
Perhatikan bahwa karakter keempat dalam 'VP8 ' FourCC adalah spasi ASCII (0x20).
Spesifikasi format bitstream VP8 dapat ditemukan di Panduan Format Data dan VP8. Perhatikan bahwa header frame VP8 berisi lebar dan tinggi frame VP8. Hal ini diasumsikan sebagai lebar dan tinggi kanvas.
Spesifikasi VP8 menjelaskan cara mendekode gambar ke dalam format Y'CbCr. Untuk mengonversi ke RGB, Rec. 601 SEBAIKNYA digunakan. Aplikasi MUNGKIN menggunakan metode konversi lain, tetapi hasil visual mungkin berbeda di antara dekoder.
Format File Sederhana (Hilang)
Catatan: Pembaca lama mungkin tidak mendukung file 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 (lossless):
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 :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Potongan 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: Chunk Size byte
- Data bitstream VP8L.
Spesifikasi bitstream VP8L saat ini dapat ditemukan di Format Bitstream Lossless WebP. Perhatikan bahwa header VP8L berisi lebar dan tinggi gambar VP8L. Hal ini diasumsikan sebagai lebar dan tinggi kanvas.
Format File yang Diperluas
Catatan: Pembaca lama mungkin tidak mendukung file menggunakan format yang diperluas.
File format yang diperluas terdiri dari:
Potongan 'VP8X' dengan informasi tentang fitur yang digunakan dalam file.
Potongan 'ICCP' opsional dengan profil warna.
Potongan 'ANIM' opsional dengan data kontrol animasi.
Data gambar.
Potongan 'EXIF' opsional dengan metadata Exif.
Potongan 'XMP ' opsional dengan metadata XMP.
Daftar opsional potongan tidak diketahui.
Untuk gambar diam, data gambar terdiri dari satu frame, yang terdiri dari:
Subchunk alfa opsional.
Untuk gambar animasi, data gambar terdiri dari beberapa frame. Detail selengkapnya tentang frame dapat ditemukan di bagian Animasi.
Semua potongan HARUS ditempatkan dalam urutan yang sama seperti yang tercantum di atas. Jika potongan muncul di tempat yang salah, file tersebut tidak valid, tetapi pembaca DAPAT menguraikan file tersebut, dan mengabaikan potongan yang tidak berurutan.
Rasional: Menetapkan urutan potongan akan memungkinkan penguraian file lebih cepat. Misalnya, jika potongan 'ALPH' tidak muncul di posisi yang diperlukan, dekoder dapat memilih untuk berhenti menelusurinya. Aturan mengabaikan potongan terlambat harus membuat program yang perlu melakukan penelusuran penuh memberikan hasil yang sama dengan program yang berhenti lebih awal.
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 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- Reserved (Rsv): 2 bit
- HARUS
0
. Pembaca HARUS mengabaikan kolom ini. - Profil ICC (I): 1 bit
- Tetapkan apakah file berisi profil ICC.
- Alfa (L): 1 bit
- Tetapkan jika salah satu frame gambar berisi informasi transparansi ("alfa").
- Metadata Exif (E): 1 bit
- Tetapkan apakah file berisi metadata Exif atau tidak.
- Metadata XMP (X): 1 bit
- Tetapkan apakah file berisi metadata XMP.
- Animasi (A): 1 bit
- Tetapkan jika ini adalah gambar animasi. Data dalam potongan 'ANIM' dan 'ANMF' harus digunakan untuk mengontrol animasi.
- Dicadangkan (R): 1 bit
- HARUS
0
. Pembaca HARUS mengabaikan kolom ini. - Disimpan: 24 bit
- HARUS
0
. Pembaca HARUS mengabaikan kolom ini. - Lebar Kanvas Minus One: 24 bit
- Lebar kanvas berbasis 1 dalam piksel.
Lebar kanvas yang sebenarnya adalah
1 + Canvas Width Minus One
. - Ketinggian Kanvas Minus One: 24 bit
- Tinggi kanvas berbasis 1 dalam piksel.
Tinggi kanvas yang sebenarnya adalah
1 + Canvas Height Minus One
.
Produk Lebar Kanvas dan Tinggi Kanvas TIDAK boleh lebih dari 2^32 - 1
.
Spesifikasi mendatang dapat menambahkan lebih banyak kolom. Kolom yang TIDAK diketahui HARUS diabaikan.
Animasi
Animasi dikontrol oleh potongan ANIM dan ANMF.
Potongan ANIM:
Untuk gambar animasi, potongan 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 [Biru, Hijau, Merah, Alfa]. Warna ini DAPAT digunakan untuk mengisi ruang yang tidak digunakan pada kanvas
di sekitar frame, serta piksel transparan dari frame pertama.
Warna latar belakang juga digunakan jika metode pembuangannya adalah
1
.
Catatan:
Warna latar belakang MUNGKIN berisi nilai alfa nonburam, meskipun tanda Alfa di bagian VP8X tidak ditetapkan.
Aplikasi penampil HARUS memperlakukan nilai warna latar belakang sebagai petunjuk, dan tidak diperlukan untuk menggunakannya.
Kanvas dihapus di awal setiap loop. Warna latar belakang DAPAT digunakan untuk mencapai hal ini.
- Jumlah Loop: 16 bit (uint16)
- Frekuensi pengulangan animasi.
0
berarti tanpa batas.
Potongan ini HARUS muncul jika tanda Animasi di potongan VP8X ditetapkan. Jika tanda Animation tidak disetel dan potongan ini ada, tanda ini HARUS diabaikan.
Bagian ANMF:
Untuk gambar animasi, potongan ini berisi informasi tentang satu frame. Jika Flag animasi tidak ditetapkan, potongan ini TIDAK BOLEH 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 pojok kiri atas bingkai adalah
Frame X * 2
. - Frame Y: 24 bit (uint24)
- Koordinat Y dari pojok kiri atas frame adalah
Frame Y * 2
. - Lebar Bingkai Minus One: 24 bit (uint24)
- Lebar frame berbasis 1.
Lebar bingkai adalah
1 + Frame Width Minus One
. - Tinggi Bingkai Minus One: 24 bit (uint24)
- Tinggi berbasis 1.
Tinggi frame 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 serupa dengan GIF.
- Disimpan: 6 bit
- HARUS
0
. Pembaca HARUS mengabaikan kolom ini. - Metode penggabungan (B): 1 bit
Menunjukkan bagaimana piksel transparan dari frame saat ini akan digabungkan dengan piksel kanvas sebelumnya yang sesuai:
0
: Menggunakan penggabungan alfa. Setelah membuang frame sebelumnya, render frame saat ini di kanvas menggunakan penggabungan alfa (lihat di bawah). Jika frame saat ini tidak memiliki saluran alfa, asumsikan nilai alfa 255, yang secara efektif menggantikan persegi panjang.1
: Jangan mencampur. Setelah membuang frame sebelumnya, render frame saat ini di kanvas dengan menimpa persegi panjang yang tertutup frame saat ini.
- Metode pembuangan (D): 1 bit
Menunjukkan cara frame saat ini diperlakukan setelah ditampilkan (sebelum merender frame berikutnya) di kanvas:
0
: Jangan buang. Biarkan kanvas sebagaimana adanya.1
: Buang ke warna latar belakang. Isi persegi panjang pada kanvas yang dicakup oleh frame saat ini dengan warna latar belakang yang ditentukan dalam potongan ANIM.
Catatan:
Pembuangan frame hanya berlaku untuk persegi panjang frame, yaitu persegi panjang yang ditentukan oleh Frame X, Frame Y, lebar frame, dan tinggi frame. Mungkin menutupi seluruh kanvas atau tidak.
Pencampuran alfa:
Mengingat bahwa setiap saluran R, G, B, dan A berukuran 8 bit, dan saluran RGB tidak diperkalikan sebelumnya oleh alfa, rumus 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
Pencampuran alfa SEBAIKNYA dilakukan dalam ruang warna linear, dengan mempertimbangkan profil warna gambar. Jika profil warna tidak ada, sRGB akan diasumsikan. (Perhatikan bahwa sRGB juga perlu dilinearisasi karena gamma ~2,2).
- Data Bingkai: Ukuran Chunk -
16
byte Terdiri dari:
Subchunk alfa opsional untuk frame.
Subchunk bitstream untuk frame.
Daftar opsional potongan tidak diketahui.
Catatan: Payload 'ANMF', Frame Data di atas, terdiri dari masing-masing potongan dengan 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... |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- Reserved (Rsv): 2 bit
- HARUS
0
. Pembaca HARUS mengabaikan kolom ini. - Pra-pemrosesan (P): 2 bit
Bit informatif ini digunakan untuk menandakan pra-pemrosesan yang telah dilakukan selama kompresi. Decoder dapat menggunakan informasi ini untuk misalnya, membagi nilai atau memperhalus gradien sebelum ditampilkan.
0
: Tidak ada pemrosesan awal.1
: Pengurangan level.
- Metode pemfilteran (F): 2 bit
Metode pemfilteran yang digunakan:
0
: Tidak ada.1
: Filter horizontal.2
: Filter vertikal.3
: Filter gradien.
Untuk setiap piksel, pemfilteran dilakukan menggunakan penghitungan berikut.
Asumsikan nilai alfa di sekitar posisi X
saat ini diberi label sebagai:
C | B |
---+---+
A | X |
Kami berusaha menghitung nilai alfa di posisi X
. Pertama, prediksi dibuat berdasarkan metode pemfilteran:
- Metode
0
: prediktor = 0 - Metode
1
: prediktor = A - Metode
2
: prediktor = B - Metode
3
: prediktor = clip(A + B - C)
dengan clip(v)
sama dengan:
- 0 jika v < 0
- 255 jika v > 255
- v jika tidak
Nilai akhir diperoleh dengan menambahkan nilai yang didekompresi X
ke
prediktor dan menggunakan aritmetika modulo-256 untuk menggabungkan rentang [256..511] ke dalam [0..255]:
alpha = (predictor + X) % 256
Ada kasus khusus untuk posisi piksel paling kiri dan paling atas:
- Nilai kiri atas di lokasi (0, 0) menggunakan 0 sebagai nilai prediktor. Jika tidak,
- 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 paling atas di lokasi (x, 0) diprediksi menggunakan lokasi (x-1, 0) di sebelah kiri.
Dekoder tidak diwajibkan untuk menggunakan informasi ini dengan cara apa pun yang ditentukan.
- Metode kompresi (C): 2 bit
Metode kompresi yang digunakan:
0
: Tidak ada kompresi.1
: Dikompresi menggunakan format lossless WebP.
- Bitstream alfa: Ukuran Chunk -
1
byte Bitstream alfa yang dienkode.
Potongan opsional ini berisi data alfa yang dienkode untuk frame ini. Frame yang berisi potongan 'VP8L' TIDAK HARUS berisi potongan ini.
Rationale: Informasi transparansi sudah menjadi bagian dari 'VP8L'.
Data saluran alfa disimpan sebagai data mentah yang tidak dikompresi (saat metode kompresi '0') atau dikompresi menggunakan format lossless (jika metode kompresi '1').
Data mentah: terdiri dari urutan byte dengan lebar * tinggi, yang berisi semua nilai transparansi 8 bit dalam urutan pemindaian.
Kompresi format lossless: urutan byte adalah aliran gambar terkompresi (seperti yang dijelaskan dalam Format Bitstream Lossless WebP) dengan lebar x tinggi dimensi implisit. Artinya, aliran gambar ini TIDAK berisi header yang menjelaskan dimensi gambar.
Rasional: dimensi sudah diketahui dari sumber lain, sehingga menyimpan lagi akan menjadi redundan dan rentan error.
Setelah aliran gambar di-dekode ke dalam nilai warna ARGB, dengan mengikuti proses yang dijelaskan dalam spesifikasi format lossless, informasi transparansi harus diekstrak dari saluran hijau dari kuadruplet ARGB.
Rationale: saluran hijau diizinkan untuk melakukan langkah transformasi tambahan dalam spesifikasi, tidak seperti saluran lain, yang dapat meningkatkan kompresi.
Bitstream (VP8/VP8L)
Potongan ini berisi data bitstream terkompresi untuk satu frame.
Potongan bitstream dapat berupa (i) potongan VP8, menggunakan "VP8 " (perhatikan ruang karakter keempat yang signifikan) sebagai tagnya atau (ii) potongan VP8L, menggunakan "VP8L" sebagai tag.
Format potongan VP8 dan VP8L adalah seperti yang dijelaskan di bagian Format File Sederhana (Hilang) dan Format File Sederhana (Hilang).
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.
Potongan ini HARUS muncul sebelum data gambar.
Minimal HARUS ada satu potongan seperti itu. Jika ada lebih banyak potongan seperti itu, pembaca YANG boleh mengabaikan semuanya, kecuali yang pertama. Lihat Spesifikasi ICC untuk mengetahui detailnya.
Jika potongan ini tidak ada, SRGB HARUS DIasumsikan.
Metadata
Metadata dapat disimpan dalam potongan 'EXIF' atau 'XMP '.
HARUS ada maksimal satu potongan dari setiap jenis ('EXIF' dan 'XMP '). Jika ada potongan lainnya, pembaca MUNGKIN mengabaikan semua selain yang pertama.
Potongan ditentukan sebagai berikut:
Bagian 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.
Potongan 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: Byte Ukuran Chunk
- Metadata gambar dalam format XMP.
Perhatikan bahwa karakter keempat dalam 'XMP ' FourCC adalah spasi ASCII (0x20).
Panduan tambahan tentang penanganan metadata dapat ditemukan di Panduan Penanganan Metadata pada Grup Kerja Metadata.
Potongan Tidak Diketahui
Potongan RIFF (dijelaskan di bagian ini) yang tag bagian berbeda dari potongan apa pun yang dijelaskan dalam dokumen ini, dianggap sebagai potongan tidak diketahui.
Rasional: Mengizinkan potongan yang tidak diketahui akan memberikan penyediaan untuk ekstensi format di masa mendatang, dan juga memungkinkan penyimpanan data khusus aplikasi.
File MUNGKIN berisi potongan yang tidak diketahui:
- Di akhir file, seperti yang dijelaskan di bagian Header file WebP yang diperluas.
- Di akhir potongan ANMF seperti yang dijelaskan di bagian Animasi.
Pembaca HARUS mengabaikan potongan ini. Penulis harus mempertahankannya dalam urutan yang asli (kecuali jika mereka secara khusus bermaksud untuk mengubah potongan tersebut).
Merakit Kanvas dari Bingkai
Di sini kami menyediakan ringkasan tentang cara pembaca HARUS merakit kanvas untuk 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 potongan 'ANIM' mengontrol berapa kali proses animasi diulang. Ini adalah Loop Count - 1
untuk
nilai Loop Count
bukan nol atau tanpa batas jika Loop Count
adalah nol.
Di awal setiap iterasi loop, kanvas akan diisi menggunakan warna latar belakang dari potongan 'ANIM' atau warna yang ditentukan aplikasi.
Potongan 'ANMF' berisi masing-masing bingkai yang diberikan dalam urutan tampilan. Sebelum merender
setiap frame, Disposal method
frame sebelumnya akan diterapkan.
Rendering frame yang didekode dimulai pada koordinat Kartesius (2 *
Frame X
, 2 * Frame Y
) menggunakan sudut kiri atas kanvas sebagai asal.
Lebar Frame Width Minus One + 1
piksel kali tinggi Frame Height Minus One + 1
piksel
dirender ke kanvas menggunakan Blending method
.
Kanvas ditampilkan selama Frame Duration
milidetik. Hal ini akan berlanjut hingga
semua frame yang diberikan oleh potongan 'ANMF' ditampilkan. Iterasi loop baru kemudian dimulai atau kanvas dibiarkan dalam status akhir jika semua iterasi telah selesai.
Kode semu berikut menggambarkan proses rendering. Notasi VP8X.field berarti kolom dalam potongan 'VP8X' dengan deskripsi yang sama.
assert VP8X.flags.hasAnimation
canvas ← new image of size VP8X.canvasWidth x VP8X.canvasHeight with
background color ANIM.background_color.
loop_count ← ANIM.loopCount
dispose_method ← Dispose to background color
if loop_count == 0:
loop_count = ∞
frame_params ← nil
assert next chunk in image_data is ANMF
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
assert VP8X.canvasWidth >= frame_right
assert VP8X.canvasHeight >= frame_bottom
for subchunk in 'Frame Data':
if subchunk.tag == "ALPH":
assert alpha subchunks not found in 'Frame Data' earlier
frame_params.alpha = alpha_data
else if subchunk.tag == "VP8 " OR subchunk.tag == "VP8L":
assert bitstream subchunks not found in 'Frame Data' earlier
frame_params.bitstream = bitstream_data
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 * 1ms.
dispose_method = frame_params.disposeMethod
Contoh Tata Letak File
Gambar berenkode lossy dengan alfa mungkin terlihat sebagai berikut:
RIFF/WEBP
+- VP8X (descriptions of features used)
+- ALPH (alpha bitstream)
+- VP8 (bitstream)
Gambar yang dienkode secara lossless mungkin terlihat seperti berikut:
RIFF/WEBP
+- VP8X (descriptions of features used)
+- XYZW (unknown chunk)
+- VP8L (lossless bitstream)
Gambar lossless dengan profil ICC dan metadata XMP mungkin 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)