Thông số kỹ thuật của vùng chứa WebP

Giới thiệu

WebP là một định dạng hình ảnh sử dụng (i) phương thức mã hoá khung hình chính VP8 để nén dữ liệu hình ảnh theo cách có tổn hao hoặc (ii) phương thức mã hoá không tổn hao WebP. Các lược đồ mã hoá này sẽ giúp hình ảnh hiệu quả hơn so với các định dạng cũ, chẳng hạn như JPEG, GIF và PNG. Định dạng này được tối ưu hoá để chuyển hình ảnh nhanh qua mạng (ví dụ: cho trang web). Định dạng WebP có tính năng tương đương (hồ sơ màu sắc, siêu dữ liệu, ảnh động, v.v.) với các định dạng khác. Tài liệu này mô tả cấu trúc của tệp WebP.

Vùng chứa WebP (tức là vùng chứa RIFF cho WebP) cho phép hỗ trợ tính năng ngoài trường hợp sử dụng cơ bản của WebP (tức là một tệp chứa một hình ảnh được mã hoá dưới dạng khung hình chính VP8). Vùng chứa WebP cung cấp thêm hỗ trợ các tính năng sau:

  • Nén không tổn hao: Có thể nén hình ảnh không tổn hao bằng cách sử dụng Định dạng WebP không tổn hao.

  • Siêu dữ liệu: Hình ảnh có thể có siêu dữ liệu được lưu trữ ở định dạng Tệp hình ảnh có thể trao đổi (Exif) hoặc Nền tảng siêu dữ liệu mở rộng (XMP).

  • Độ trong suốt: Hình ảnh có thể có trong suốt, tức là kênh alpha.

  • Cấu hình màu: Hình ảnh có thể nhúng cấu hình ICC như mô tả do National Color Consortium (Hiệp hội màu sắc quốc tế) thực hiện.

  • Ảnh động: Một hình ảnh có thể có nhiều khung hình với các điểm tạm dừng giữa các khung hình đó, biến video thành hoạt ảnh.

Đặt tên

Bạn NÊN sử dụng các loại sau khi tham chiếu đến WebP vùng chứa:

Tên định dạng vùng chứaWebP
Phần mở rộng tên tệp.webp
Loại MIMEimage/webp
Giá trị nhận dạng loại thống nhấtorg.webmproject.webp

Thuật ngữ và Thông tin cơ bản

Các từ khóa "PHẢI", "KHÔNG ĐƯỢC", "BẮT BUỘC", "SÁNG", "KHÔNG ĐƯỢC", "NÊN", "KHÔNG NÊN", "NÊN DÙNG", "KHÔNG NÊN DÙNG", "CÓ THỂ" và "KHÔNG BẮT BUỘC" trong nội dung này tài liệu được diễn giải theo mô tả trong BCP 14 RFC 2119 RFC 8174 khi nào và chỉ khi nào chúng xuất hiện ở tất cả các chữ viết hoa, như được trình bày ở đây.

Tệp WebP chứa một hình ảnh tĩnh (tức là một ma trận pixel được mã hoá) hoặc một ảnh động. Tệp này cũng có thể chứa thông tin về độ trong suốt, hồ sơ màu và siêu dữ liệu (không bắt buộc). Chúng tôi gọi ma trận pixel là canvas của hình ảnh.

Việc đánh số bit trong sơ đồ phân đoạn bắt đầu từ 0 cho bit quan trọng nhất ('MSB 0'), theo mô tả trong RFC 1166.

Dưới đây là các thuật ngữ bổ sung được sử dụng trong toàn bộ tài liệu này:

Đọc/Ghi
Mã đọc tệp WebP được gọi là trình đọc, còn mã ghi tệp WebP được gọi là trình ghi.
uint16
Một số nguyên 16 bit có đuôi nhỏ, chưa ký.
uint24
Một số nguyên 24 bit, little-endian, chưa ký.
uint32
Một số nguyên 32 bit có đuôi nhỏ và chưa ký.
FourCC
Mã gồm bốn ký tự (FourCC) là một uint32 được tạo bằng cách nối bốn ký tự Ký tự ASCII theo thứ tự Little-endian. Điều này có nghĩa là "aaaa" (0x61616161) và "AAAA" (0x41414141) được coi là các FourCC khác nhau.
Dựa trên 1
Một trường số nguyên không dấu lưu trữ các giá trị được bù bằng -1, ví dụ: trường như vậy sẽ lưu trữ giá trị 25 dưới dạng 24.
ChunkHeader('ABCD')
Dùng để mô tả tiêu đề FourCCChunk size của từng phần, trong đó "ABCD" là FourCC cho phân đoạn. Kích thước của phần tử này là 8 byte.

Định dạng tệp RIFF

Định dạng tệp WebP dựa trên định dạng tài liệu RIFF (Định dạng tệp trao đổi tài nguyên).

Phần tử cơ bản của tệp RIFF là mảnh. Bộ công cụ này bao gồm:

 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
Mã ASCII gồm 4 ký tự dùng để nhận dạng đoạn.
Kích thước đoạn: 32 bit (uint32)
Kích thước của đoạn dữ liệu tính bằng byte, không bao gồm trường này, giá trị nhận dạng đoạn dữ liệu hoặc khoảng đệm.
Trọng tải phân đoạn: Kích thước phân đoạn byte
Tải trọng dữ liệu. Nếu Phân đoạn Kích thước là số lẻ, một byte khoảng đệm duy nhất – PHẢI 0 để tuân thủ RIFF -- sẽ được thêm vào.

Lưu ý: RIFF có quy ước là các FourCC của đoạn toàn chữ hoa là các đoạn tiêu chuẩn áp dụng cho mọi định dạng tệp RIFF, trong khi các FourCC dành riêng cho một định dạng tệp đều là chữ thường. WebP không tuân theo quy ước này.

Tiêu đề tệp 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
Các ký tự ASCII "R", "I", "F", "F".
Kích thước tệp: 32 bit (uint32)
Kích thước của tệp tính bằng byte, bắt đầu tại giá trị bù 8. Giá trị tối đa của trường này là 2^32 trừ 10 byte, do đó kích thước của toàn bộ tệp tối đa là 4 GiB trừ 2 byte.
"WEBP": 32 bit
Các ký tự ASCII "W", "E", "B", "P".

Tệp WebP PHẢI bắt đầu bằng tiêu đề RIFF có FourCC "WEBP". Kích thước tệp trong tiêu đề là tổng kích thước của các phần theo sau cộng với 4 byte cho 'WEBP' FourCC. Tệp KHÔNG ĐƯỢC chứa bất kỳ dữ liệu nào sau dữ liệu được chỉ định bởi Kích thước tệp. Trình đọc CÓ THỂ phân tích cú pháp các tệp như vậy, bỏ qua dữ liệu theo sau. Vì kích thước của bất kỳ phần nào đều là số chẵn, nên kích thước do tiêu đề RIFF cung cấp cũng là số chẵn. Phần sau đây mô tả nội dung của từng phần riêng lẻ .

Định dạng tệp đơn giản (Mất dữ liệu)

Bố cục này NÊN được sử dụng nếu hình ảnh yêu cầu mã hoá mất dữ liệu và không yêu cầu tính năng trong suốt hoặc các tính năng nâng cao khác do định dạng mở rộng cung cấp. Các tệp có bố cục này có kích thước nhỏ hơn và được phần mềm cũ hỗ trợ.

Định dạng tệp WebP (bị mất) đơn giản:

 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" Phân đoạn:

 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                            :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Dữ liệu VP8: Kích thước phân đoạn byte
Dữ liệu luồng bit của VPN.

Xin lưu ý rằng ký tự thứ tư trong FourCC "VP8" là một khoảng trắng ASCII (0x20).

Thông số kỹ thuật của định dạng luồng bit VP8 được mô tả trong phần Định dạng dữ liệu VP8 và Hướng dẫn giải mã. Xin lưu ý rằng tiêu đề khung VP8 chứa khung VP8 chiều rộng và chiều cao. Giá trị này được giả định là chiều rộng và chiều cao của canvas.

Quy cách VP8 mô tả cách giải mã hình ảnh sang định dạng Y'CbCr. Người nhận chuyển đổi thành RGB, thì bạn NÊN sử dụng Đề xuất BT.601. Các ứng dụng CÓ THỂ sử dụng một phương thức chuyển đổi khác, nhưng kết quả hình ảnh có thể khác nhau giữa các bộ giải mã.

Định dạng tệp đơn giản (Không suy hao)

Lưu ý: Các đầu đọc cũ có thể không hỗ trợ các tệp sử dụng định dạng không suy hao.

BẠN NÊN sử dụng bố cục này nếu hình ảnh yêu cầu mã hoá không suy hao (có kênh độ trong suốt không bắt buộc) và không yêu cầu các tính năng nâng cao do định dạng mở rộng cung cấp.

Định dạng tệp WebP đơn giản (không suy hao):

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

Mảnh "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                           :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Dữ liệu VP8L: Kích thước phân đoạn byte
Dữ liệu luồng bit VP8L.

Bạn có thể tìm thấy thông số kỹ thuật hiện tại của luồng bit VP8L tại Định dạng luồng bit không tổn hao trên WebP. Lưu ý rằng tiêu đề VP8L chứa thông số chiều rộng và chiều cao của hình ảnh là VP8L. Giả định là chiều rộng và chiều cao của canvas.

Định dạng tệp mở rộng

Lưu ý: Người đọc lớn tuổi có thể không hỗ trợ các tệp sử dụng định dạng mở rộng.

Tệp định dạng mở rộng bao gồm:

  • Một Mảnh "VP8X" chứa thông tin về các tính năng được sử dụng trong tệp.

  • "ICCP" không bắt buộc Phân đoạn có cấu hình màu.

  • Một Mảnh "ANIM" không bắt buộc có dữ liệu điều khiển ảnh động.

  • Dữ liệu hình ảnh.

  • Giá trị 'EXIF' không bắt buộc Phân đoạn bằng siêu dữ liệu Exif.

  • Phần "XMP" không bắt buộc có siêu dữ liệu XMP.

  • Danh sách đoạn không xác định (không bắt buộc).

Đối với ảnh tĩnh, dữ liệu hình ảnh chỉ bao gồm một khung duy nhất được tạo lên trong số:

Đối với hình ảnh động, dữ liệu hình ảnh bao gồm nhiều khung hình. Bạn có thể xem thêm thông tin chi tiết về khung hình trong phần Ảnh động.

Tất cả các đoạn cần thiết cho việc tái cấu trúc và chỉnh màu, tức là "VP8X", "ICCP", "ANIM", "ANMF", "ALPH", "VP8" và "VP8L", PHẢI xuất hiện trong thứ tự được mô tả trước đó. Trình đọc NÊN không thành công khi các đoạn cần thiết để tái tạo và chỉnh màu bị lộn thứ tự.

Siêu dữ liệucác đoạn không xác định CÓ THỂ xuất hiện không theo thứ tự.

Rationale: Các đoạn cần thiết để tái tạo sẽ xuất hiện đầu tiên trong tệp để cho phép người đọc bắt đầu giải mã hình ảnh trước khi nhận được tất cả dữ liệu. Một ứng dụng có thể hưởng lợi từ việc thay đổi thứ tự của siêu dữ liệu và các đoạn tuỳ chỉnh để phù hợp với việc triển khai.

Tiêu đề tệp WebP mở rộng:

 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    |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Dành riêng (Rsv): 2 bit
PHẢI là 0. Độc giả PHẢI bỏ qua trường này.
Cấu hình ICC (I): 1 bit
Đặt nếu tệp chứa một Mảnh "ICCP".
Alpha (L): 1 bit
Đặt xem có khung nào của hình ảnh chứa thông tin trong suốt ("alpha").
Siêu dữ liệu Exif (E): 1 bit
Đặt xem tệp có chứa siêu dữ liệu Exif hay không.
Siêu dữ liệu XMP (X): 1 bit
Đặt nếu tệp chứa siêu dữ liệu XMP.
Ảnh động (A): 1 bit
Đặt nếu đây là ảnh động. Bạn nên sử dụng dữ liệu trong các Mảnh "ANIM" và "ANMF" để kiểm soát ảnh động.
Dành riêng (R): 1 bit
PHẢI 0. Trình đọc PHẢI bỏ qua trường này.
Đã đặt trước: 24 bit
PHẢI là 0. Trình đọc PHẢI bỏ qua trường này.
Chiều rộng canvas trừ 1: 24 bit
Chiều rộng dựa trên 1 của canvas tính bằng pixel. Chiều rộng thực tế của canvas là 1 + Canvas Width Minus One.
Chiều cao canvas trừ 1: 24 bit
Chiều cao dựa trên 1 của canvas tính bằng pixel. Chiều cao thực tế của canvas là 1 + Canvas Height Minus One.

Hệ số của Chiều rộng canvasChiều cao canvas PHẢI là tối đa 2^32 - 1.

Các thông số kỹ thuật trong tương lai có thể thêm nhiều trường hơn. BẠN PHẢI bỏ qua các trường không xác định.

Hoạt ảnh

Ảnh động được kiểm soát bằng các Mảnh "ANIM" và "ANMF".

Mảnh "ANIM":

Đối với hình ảnh động, đoạn này chứa các thông số toàn cục của ảnh động.

 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           |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Màu nền: 32 bit (uint32)
Màu nền mặc định của canvas theo thứ tự byte [Blue, Green, Red, Alpha]. Bạn CÓ THỂ sử dụng màu này để lấp đầy không gian không sử dụng trên canvas xung quanh các khung, cũng như các pixel trong suốt của khung đầu tiên. Màu nền cũng được dùng khi phương thức Xử lý là 1.

Lưu ý:

  • Màu nền CÓ THỂ chứa giá trị alpha không mờ, ngay cả khi bạn không đặt cờ Alpha trong Mảnh "VP8X".

  • Ứng dụng trình xem PHẢI coi giá trị màu nền là gợi ý và không bắt buộc phải sử dụng giá trị này.

  • Canvas được xoá ở đầu mỗi vòng lặp. Màu nền CÓ THỂ là dùng để đạt được mục tiêu này.

Số vòng lặp: 16 bit (uint16)
Số lần lặp lại ảnh động. Nếu giá trị là 0, điều này có nghĩa là vô hạn.

Phân đoạn này PHẢI xuất hiện nếu cờ Animation (Ảnh động) trong "VP8X" Đã đặt phân đoạn. Nếu bạn không đặt cờ Animation (Ảnh động) và có khối này, thì bạn PHẢI bỏ qua khối này.

"ANMF" Phân đoạn:

Đối với hình ảnh động, đoạn này chứa thông tin về một khung hình. Nếu Cờ ảnh động chưa được đặt, thì phân đoạn này KHÔNG NÊN hiển thị.

 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                            :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Khung hình X: 24 bit (uint24)
Tọa độ X của góc trên bên trái khung hình là Frame X * 2.
Khung hình Y: 24 bit (uint24)
Tọa độ Y của góc trên bên trái khung hình là Frame Y * 2.
Chiều rộng khung hình trừ đi 1: 24 bit (uint24)
Chiều rộng dựa trên 1 của khung. Chiều rộng khung là 1 + Frame Width Minus One.
Chiều cao khung hình trừ đi 1: 24 bit (uint24)
Chiều cao dựa trên 1 của khung. Chiều cao khung hình là 1 + Frame Height Minus One.
Thời lượng khung hình: 24 bit (uint24)
Thời gian chờ trước khi hiển thị khung tiếp theo, tính bằng đơn vị 1 mili giây. Lưu ý rằng việc diễn giải Thời lượng khung hình là 0 (và thường <= 10) là được xác định bởi quá trình triển khai. Nhiều công cụ và trình duyệt quy định giá trị tối thiểu tương tự như ảnh GIF.
Đã đặt trước: 6 bit
PHẢI là 0. Trình đọc PHẢI bỏ qua trường này.
Phương pháp trộn (B): 1 bit

Cho biết cách pha trộn các pixel trong suốt của khung hình hiện tại bằng pixel tương ứng của canvas trước đó:

  • 0: Sử dụng tính năng kết hợp alpha. Sau khi loại bỏ khung trước đó, hãy kết xuất khung hiện tại trên canvas bằng cách sử dụng tính năng kết hợp alpha (xem bên dưới). Nếu khung hình hiện tại không có kênh alpha, hãy giả định giá trị alpha là 255, thay thế hình chữ nhật một cách hiệu quả.

  • 1: Không kết hợp. Sau khi loại bỏ khung trước, hãy kết xuất khung hiện tại trên canvas bằng cách ghi đè hình chữ nhật được bao phủ bởi khung hiện tại.

Phương thức xử lý (D): 1 bit

Cho biết cách xử lý khung hình hiện tại sau khi khung hình đó được hiển thị (trước khi kết xuất khung hình tiếp theo) trên canvas:

  • 0: Không huỷ bỏ. Giữ nguyên ảnh in trên vải canvas.

  • 1: Chuyển sang màu nền. Điền thông tin vào hình chữ nhật trên canvas được phủ bởi khung hiện tại bằng màu nền được chỉ định trong "ANIM" Phân đoạn.

Lưu ý:

  • Thao tác loại bỏ khung chỉ áp dụng cho hình chữ nhật khung, tức là hình chữ nhật được xác định bằng Khung X, Khung Y, chiều rộng khungkhung chiều cao. Hình ảnh này có thể bao phủ toàn bộ canvas hoặc không.

  • Hỗn hợp alpha:

    Giả sử mỗi kênh R, G, B và A là 8 bit và RGB kênh không được nhân trước với alpha, công thức để kết hợp "dst" vào 'src' là:

    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
    
  • Phối hợp alpha PHẢI được thực hiện trong hệ màu tuyến tính, có tính đến hồ sơ màu của hình ảnh. Nếu cấu hình màu là không có, RGB (sRGB) chuẩn sẽ được giả định. (Xin lưu ý rằng sRGB cũng cần được tuyến tính hóa do gamma ~ 2.2.)

Dữ liệu khung: Kích thước phân đoạn byte - 16

Bao gồm:

Lưu ý: Trọng tải "ANMF", Dữ liệu khung, bao gồm các đoạn đã thêm khoảng đệm riêng lẻ, như mô tả trong định dạng tệp RIFF.

Alpha

 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...                        |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Dành riêng (Rsv): 2 bit
PHẢI là 0. Độc giả PHẢI bỏ qua trường này.
Tiền xử lý (P): 2 bit

Các bit thông tin này được dùng để báo hiệu quá trình xử lý trước được thực hiện trong quá trình nén. Bộ giải mã có thể sử dụng thông tin này để ví dụ: hoà màu các giá trị hoặc làm mịn các gradient trước khi hiển thị.

  • 0: Không xử lý trước.
  • 1: Giảm cấp.

Bộ giải mã không bắt buộc phải sử dụng thông tin này theo bất kỳ cách nào được chỉ định.

Phương thức lọc (F): 2 bit

Sau đây là các phương pháp lọc được sử dụng:

  • 0: Không có.
  • 1: Bộ lọc ngang.
  • 2: Bộ lọc dọc.
  • 3: Bộ lọc chuyển màu.

Đối với mỗi điểm ảnh, việc lọc được thực hiện bằng cách sử dụng các phép tính sau. Giả sử các giá trị alpha xung quanh vị trí X hiện tại được gắn nhãn là:

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

Chúng ta tìm cách tính toán giá trị alpha tại vị trí X. Trước tiên, hệ thống sẽ đưa ra một dự đoán tuỳ thuộc vào phương thức lọc:

  • Phương thức 0: công cụ dự đoán = 0
  • Phương thức 1: predictor = A
  • Phương thức 2: công cụ dự đoán = B
  • Phương thức 3: predictor = clip(A + B - C)

trong đó clip(v) bằng:

  • 0 nếu v < 0,
  • 255 nếu v > 255 hoặc
  • so với ngược lại

Giá trị cuối cùng được lấy bằng cách thêm giá trị đã giải nén X vào trình dự đoán và sử dụng phép tính modulo-256 để gói dải [256..511] vào dải [0..255]:

alpha = (predictor + X) % 256

Có những trường hợp đặc biệt cho vị trí pixel xa nhất bên trái và trên cùng. Ví dụ: giá trị trên cùng bên trái tại vị trí (0, 0) sử dụng 0 làm giá trị dự đoán. Nếu không thì:

  • Đối với phương pháp lọc theo chiều ngang hoặc độ dốc, pixel ngoài cùng bên trái tại vị trí (0, y) được dự đoán bằng cách sử dụng vị trí (0, y-1) ngay ở trên.
  • Đối với các phương thức lọc theo chiều dọc hoặc độ dốc, các pixel trên cùng tại vị trí (x, 0) được dự đoán bằng cách sử dụng vị trí (x-1, 0) ở bên trái.
Phương pháp nén (C): 2 bit

Phương thức nén được sử dụng:

  • 0: Không nén.
  • 1: Được nén bằng định dạng WebP không suy hao.
Luồng bit alpha: Kích thước phân đoạn byte – 1

Luồng bit alpha đã mã hoá.

Phân đoạn không bắt buộc này chứa dữ liệu alpha được mã hoá cho khung này. Khung có chứa "VP8L" Phân đoạn KHÔNG ĐƯỢC chứa phân đoạn này.

Lý do: Thông tin về độ trong suốt đã có trong Phân đoạn "VP8L".

Dữ liệu kênh alpha được lưu trữ dưới dạng dữ liệu thô không nén (khi phương thức nén là "0") hoặc được nén bằng định dạng không tổn hao (khi phương thức nén là "1").

  • Dữ liệu thô: Dữ liệu này bao gồm một chuỗi byte dài = chiều rộng * chiều cao, chứa tất cả giá trị độ trong suốt 8 bit theo thứ tự quét.

  • Nén định dạng không tổn hao: Chuỗi byte là một chuỗi nén luồng hình ảnh (như mô tả trong "Định dạng luồng bit không tổn hao WebP") của kích thước ngầm ẩn: chiều rộng x chiều cao. Tức là, image-stream KHÔNG chứa bất kỳ tiêu đề nào mô tả kích thước hình ảnh.

    Lý do: Các phương diện đã được biết từ các nguồn khác, vì vậy, việc lưu trữ lại các phương diện này sẽ là thừa và dễ xảy ra lỗi.

    Sau khi luồng hình ảnh được giải mã thành các giá trị màu Alpha, Đỏ, Xanh lục, Xanh lam (ARGB), theo quy trình được mô tả trong quy cách định dạng không suy hao, thông tin về độ trong suốt phải được trích xuất từ kênh xanh lục của bộ tứ ARGB.

    Rationale: Kênh màu xanh lục được phép biến đổi thêm các bước trong thông số kỹ thuật -- không giống như các kênh khác -- có thể cải thiện độ nén.

Luồng Bit (VP8/VP8L)

Phân đoạn này chứa dữ liệu luồng bit được nén cho một khung.

Một đoạn luồng bit có thể là (i) Đoạn "VP8", sử dụng "VP8" (lưu ý khoảng trắng ký tự thứ tư quan trọng) làm FourCC, hoặc (ii) Đoạn "VP8L", sử dụng "VP8L" làm FourCC.

Định dạng của các Mảnh "VP8" và "VP8L" được mô tả tương ứng trong các phần Định dạng tệp đơn giản (Mất dữ liệu)Định dạng tệp đơn giản (Không mất dữ liệu).

Hồ sơ màu

 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                           :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Hồ sơ màu: Kích thước đoạn (byte)
Hồ sơ ICC.

Phần này PHẢI xuất hiện trước dữ liệu hình ảnh.

Chỉ được có nhiều nhất một đoạn như vậy. Nếu có nhiều phân đoạn như vậy, độc giả CÓ THỂ bỏ qua tất cả, ngoại trừ mục đầu tiên. Hãy xem Quy cách ICC để biết thông tin chi tiết.

Nếu không có đoạn này, bạn PHẢI giả định là sRGB.

Metadata

Siêu dữ liệu có thể được lưu trữ trong "EXIF" hoặc 'XMP' Viên nhỏ.

TỐI ĐA mỗi loại ('EXIF' và 'XMP') chỉ nên có một đoạn. Nếu có nhiều đoạn như vậy, thì trình đọc CÓ THỂ bỏ qua tất cả trừ đoạn đầu tiên.

Các đoạn được xác định như sau:

Mảnh "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                          :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Siêu dữ liệu Exif: Kích thước khối tính bằng byte
Siêu dữ liệu hình ảnh ở định dạng Exif.

Mảnh "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                           :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Siêu dữ liệu XMP: Kích thước phân đoạn byte
Siêu dữ liệu hình ảnh ở định dạng XMP.

Lưu ý rằng ký tự thứ tư trong "XMP" FourCC là không gian ASCII (0x20).

Bạn có thể xem thêm hướng dẫn về cách xử lý siêu dữ liệu trong "Hướng dẫn xử lý siêu dữ liệu" của Nhóm làm việc về siêu dữ liệu.

Mảnh không xác định

Một đoạn RIFF (mô tả trong phần Định dạng tệp RIFF) có FourCC khác với bất kỳ đoạn nào được mô tả trong tài liệu này được coi là đoạn không xác định.

Lý do: Việc cho phép các đoạn không xác định sẽ cung cấp một điều khoản để mở rộng định dạng trong tương lai và cũng cho phép lưu trữ mọi dữ liệu dành riêng cho ứng dụng.

Tệp CÓ THỂ chứa các đoạn không xác định:

Người đọc NÊN bỏ qua các phần này. Người viết NÊN giữ nguyên các phần này theo thứ tự ban đầu (trừ phi họ có ý định sửa đổi các phần này).

Lắp ráp Canvas từ Khung

Ở đây, chúng tôi cung cấp thông tin tổng quan về cách độc giả PHẢI tập hợp canvas trong trường hợp của một hình ảnh động.

Quy trình này bắt đầu bằng việc tạo một canvas sử dụng các kích thước có sẵn trong "VP8X" Phân đoạn, rộng Canvas Width Minus One + 1 pixel, cao Canvas Height Minus One + 1 pixel. Trường Loop Count trong trường "ANIM" Phân đoạn kiểm soát cách nhiều lần quá trình tạo ảnh động lặp lại. Đây là Loop Count - 1 đối với các giá trị Loop Count khác 0 hoặc vô hạn nếu Loop Count bằng 0.

Ở đầu mỗi lần lặp lại, canvas được lấp đầy bằng cách sử dụng màu nền từ 'ANIM' Phân đoạn hoặc màu do ứng dụng xác định.

"ANMF" Các phân đoạn chứa từng khung hình được đưa ra theo thứ tự trưng bày. Trước khi kết xuất từng khung hình, Disposal method của khung hình trước đó sẽ được áp dụng.

Quá trình hiển thị khung được giải mã bắt đầu tại toạ độ Descartes (2 * Frame X, 2 * Frame Y), sử dụng góc trên cùng bên trái của canvas làm điểm gốc. rộng Frame Width Minus One + 1 pixel x Frame Height Minus One + 1 pixel cao sẽ được hiển thị trên canvas bằng Blending method.

Canvas sẽ hiển thị trong Frame Duration mili giây. Quá trình này sẽ tiếp tục cho đến tất cả khung hình do 'ANMF' cung cấp Đã hiển thị các phân đoạn. Một vòng lặp mới là sau đó bắt đầu hoặc canvas sẽ ở trạng thái cuối cùng nếu tất cả các lần lặp đã hoàn tất.

Mã giả sau minh hoạ quá trình kết xuất. Ký hiệu VP8X.field nghĩa là trường trong "VP8X" Phân đoạn có cùng nội dung mô tả.

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

Bố cục tệp mẫu

Hình ảnh được mã hoá có tổn hao với alpha có thể có dạng như sau:

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

Hình ảnh được mã hoá không tổn hao có thể có dạng như sau:

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

Hình ảnh không suy hao có hồ sơ ICC và siêu dữ liệu XMP có thể có dạng như sau:

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

Hình ảnh động có siêu dữ liệu Exif có thể có dạng như sau:

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)