Спецификация контейнера WebP

Введение

WebP — это формат изображения, в котором используется либо (i) кодировка ключевого кадра VP8 для сжатия данных изображения с потерями, либо (ii) кодировка WebP без потерь (и, возможно, другие кодировки в будущем). Эти схемы кодирования должны сделать его более эффективным, чем используемые в настоящее время форматы. Он оптимизирован для быстрой передачи изображений по сети (например, для веб-сайтов). Формат WebP имеет паритет функций (цветовой профиль, метаданные, анимация и т. д.) с другими форматами. Этот документ описывает структуру файла WebP.

Контейнер WebP (т. е. контейнер RIFF для WebP) обеспечивает поддержку функций помимо основного варианта использования WebP (т. е. файла, содержащего одно изображение, закодированное как ключевой кадр VP8). Контейнер WebP обеспечивает дополнительную поддержку:

  • Сжатие без потерь. Изображение может быть сжато без потерь с использованием формата WebP Lossless Format.

  • Метаданные. Изображение может иметь метаданные, хранящиеся в форматах Exif или XMP.

  • Прозрачность. Изображение может иметь прозрачность, т. е. альфа-канал.

  • Цветовой профиль. Изображение может иметь встроенный профиль ICC, как описано Международным консорциумом по цвету .

  • Анимация. Изображение может иметь несколько кадров с паузами между ними, что делает его анимацией.

Ключевые слова «ДОЛЖЕН», «НЕ ДОЛЖЕН», «ТРЕБУЕТСЯ», «ДОЛЖЕН», «НЕ ДОЛЖЕН», «СЛЕДУЕТ», «НЕ ДОЛЖЕН», «РЕКОМЕНДУЕТСЯ», «НЕ РЕКОМЕНДУЕТСЯ», «МОЖЕТ» и «НЕОБЯЗАТЕЛЬНО». " в этом документе должны интерпретироваться, как описано в BCP 14 RFC 2119 RFC 8174 , когда и только тогда, когда они появляются во всех прописных буквах, как показано здесь.

Нумерация битов в диаграммах блоков начинается с 0 для старшего бита («MSB 0»), как описано в RFC 1166 .

Именование

РЕКОМЕНДУЕТСЯ использовать следующие типы при обращении к контейнеру WebP:

Имя формата контейнера WebP
Расширение имени файла .webp
MIME-тип изображение/веб-страница
Унифицированный идентификатор типа org.webmproject.webp

Терминология и основы

Файл WebP содержит либо неподвижное изображение (то есть закодированную матрицу пикселей), либо анимацию . При желании он также может содержать информацию о прозрачности, цветовой профиль и метаданные. В случае, если нам нужно обратиться только к матрице пикселей, мы будем называть ее холстом изображения.

Ниже приведены дополнительные термины, используемые в этом документе:

Читатель/Писатель
Код, который читает файлы WebP, называется средством чтения , а код, записывающий их, называется средством записи .
uint16
16-битное целое число без знака с прямым порядком байтов.
uint24
24-битное целое число без знака с прямым порядком байтов.
uint32
32-разрядное целое число без знака с прямым порядком байтов.
Четыре CC
FourCC (четырехсимвольный код) — это uint32 , созданный путем объединения четырех символов ASCII в порядке прямого байта. Это означает, что «aaaa» (%x61.61.61.61) и «AAAA» (%x41.41.41.41) рассматриваются как разные FourCC .
1 на основе
Целочисленное поле без знака, хранящее значения со смещением на -1 . например, такое поле будет хранить значение 25 как 24 .
Заголовок фрагмента ('ABCD')
Это используется для описания заголовков FourCC и Chunk Size отдельных фрагментов, где «ABCD» — это FourCC для фрагмента. Размер этого элемента составляет 8 байт.

Формат файла RIFF

Формат файла WebP основан на формате документа RIFF (формат файла обмена ресурсами).

Базовым элементом RIFF-файла является чанк . Это состоит из:

 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                         :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Чанк FourCC: 32 бита
Четырехсимвольный код ASCII, используемый для идентификации фрагмента.
Размер блока: 32 бита ( uint32 )
Размер фрагмента без учета этого поля, идентификатора фрагмента или заполнения.
Полезная нагрузка блока: Размер блока в байтах
Полезная нагрузка данных. Если размер фрагмента нечетный, добавляется один байт заполнения, который ДОЛЖЕН быть равен 0 , чтобы соответствовать RIFF. Приложения МОГУТ использовать другое значение, но программы чтения могут не проанализировать файл.

Примечание. В RIFF принято соглашение о том, что блоки FourCC с заглавными буквами являются стандартными блоками, применимыми к любому формату файла RIFF, в то время как все блоки FourCC, специфичные для формата файла, записываются строчными буквами. WebP не следует этому соглашению.

Заголовок файла 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'      |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
«РИФФ»: 32 бита
Символы ASCII «R», «I», «F», «F».
Размер файла: 32 бита ( uint32 )
Размер файла в байтах, начиная со смещения 8. Максимальное значение этого поля составляет 2^32 минус 10 байт, и, таким образом, размер всего файла составляет не более 4 ГБ минус 2 байта.
«WEBP»: 32 бита
Символы ASCII «W», «E», «B», «P».

Файл WebP ДОЛЖЕН начинаться с заголовка RIFF с «WEBP» FourCC. Размер файла в заголовке — это общий размер блоков, которые следуют, плюс 4 байта для «WEBP» FourCC. Файл НЕ ДОЛЖЕН содержать ничего после него. Читатели МОГУТ анализировать такие файлы, игнорируя конечные данные. Поскольку размер любого фрагмента четный, размер, указанный в заголовке RIFF, также является четным. Содержимое отдельных фрагментов будет описано в следующих разделах.

Простой формат файла (с потерями)

Этот макет СЛЕДУЕТ использовать, если изображение требует кодирования с потерями и не требует прозрачности или других дополнительных функций, предоставляемых расширенным форматом. Файлы с таким макетом меньше по размеру и поддерживаются старым программным обеспечением.

Простой формат файла 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:

 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                            :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Данные VP8: размер блока в байтах
Данные битового потока VP8.

Обратите внимание, что четвертый символ в «VP8» FourCC — это пробел ASCII (%x20).

Спецификацию формата битового потока VP8 можно найти в Руководстве по формату и декодированию данных VP8 . Обратите внимание, что заголовок кадра VP8 содержит ширину и высоту кадра VP8. Предполагается, что это ширина и высота холста.

Спецификация VP8 описывает, как декодировать изображение в формат Y'CbCr. Чтобы преобразовать в RGB, Rec. 601 СЛЕДУЕТ использовать. Приложения МОГУТ использовать другой метод преобразования, но визуальные результаты могут различаться в разных декодерах.

Простой формат файла (без потерь)

Примечание: старые версии ридеров могут не поддерживать файлы в формате без потерь.

Этот макет СЛЕДУЕТ использовать, если изображение требует кодирования без потерь (с дополнительным каналом прозрачности) и не требует расширенных функций, предоставляемых расширенным форматом.

Простой формат файла 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:

 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                           :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Данные VP8L: размер блока в байтах
Данные битового потока VP8L.

Текущую спецификацию битового потока VP8L можно найти на WebP Lossless Bitstream Format . Обратите внимание, что заголовок VP8L содержит ширину и высоту изображения VP8L. Предполагается, что это ширина и высота холста.

Расширенный формат файла

Примечание: старые версии могут не поддерживать файлы, использующие расширенный формат.

Файл расширенного формата состоит из:

  • Фрагмент 'VP8X' с информацией об используемых в файле функциях.

  • Необязательный блок ICCP с цветовым профилем.

  • Необязательный фрагмент ANIM с данными управления анимацией.

  • Данные изображения.

  • Необязательный фрагмент EXIF ​​с метаданными Exif.

  • Необязательный фрагмент «XMP» с метаданными XMP.

Для неподвижного изображения данные изображения состоят из одного кадра, состоящего из:

Для анимированного изображения данные изображения состоят из нескольких кадров. Подробнее о кадрах можно узнать в разделе Анимация .

Все фрагменты ДОЛЖНЫ быть размещены в том же порядке, как указано выше. Если фрагмент появляется в неправильном месте, файл недействителен, но читатели МОГУТ разобрать файл, игнорируя фрагменты, появившиеся слишком поздно.

Обоснование: установка порядка фрагментов должна позволять быстрее анализировать файлы. Например, если блок «ALPH» не появляется в требуемой позиции, декодер может остановить его поиск. Правило игнорирования поздних фрагментов должно заставить программы, которым необходимо выполнить полный поиск, давать те же результаты, что и те, которые останавливаются раньше.

Расширенный заголовок файла 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    |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Зарезервировано (Rsv): 2 бита
ДОЛЖЕН быть 0 .
Профиль ICC (I): 1 бит
Установите, если файл содержит профиль ICC.
Альфа (L): 1 бит
Установите, если какой-либо из кадров изображения содержит информацию о прозрачности ("альфа").
Метаданные Exif (E): 1 бит
Установите, если файл содержит метаданные Exif.
Метаданные XMP (X): 1 бит
Установите, если файл содержит метаданные XMP.
Анимация (A): 1 бит
Установите, если это анимированное изображение. Данные в чанках ANIM и ANMF должны использоваться для управления анимацией.
Зарезервировано (R): 1 бит
ДОЛЖЕН быть 0 .
Зарезервировано: 24 бита
ДОЛЖЕН быть 0 .
Ширина холста минус один: 24 бита
Ширина холста на основе 1 в пикселях. Фактическая ширина холста равна 1 + Canvas Width Minus One .
Высота холста минус один: 24 бита
1 высота холста в пикселях. Фактическая высота холста равна 1 + Canvas Height Minus One .

Произведение ширины холста и высоты холста ДОЛЖНО быть не более 2^32 - 1 .

Будущие спецификации МОГУТ добавить дополнительные поля.

Анимация

Анимация управляется фрагментами ANIM и ANMF.

Кусок АНИМ:

Для анимированного изображения этот фрагмент содержит глобальные параметры анимации.

 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           |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Цвет фона: 32 бита ( uint32 )
Цвет фона холста по умолчанию в порядке байтов [Синий, Зеленый, Красный, Альфа]. Этот цвет МОЖЕТ использоваться для заполнения неиспользуемого пространства на холсте вокруг кадров, а также прозрачных пикселей первого кадра. Цвет фона также используется, когда метод удаления равен 1 .

Примечание :

  • Цвет фона МОЖЕТ содержать значение прозрачности (альфа), даже если флаг Альфа в блоке VP8X не установлен.

  • Приложения-просмотрщики ДОЛЖНЫ рассматривать значение цвета фона как подсказку и не обязаны его использовать.

  • Холст очищается в начале каждого цикла. Для этого МОЖЕТ использоваться цвет фона.

Количество циклов: 16 бит ( uint16 )
Количество циклов анимации. 0 означает бесконечно.

Этот блок ДОЛЖЕН появиться, если установлен флаг анимации в блоке VP8X. Если флаг Animation не установлен и этот фрагмент присутствует, его СЛЕДУЕТ игнорировать.

Фрагмент ANMF:

Для анимированных изображений этот блок содержит информацию об одном кадре. Если флаг анимации не установлен, то этот фрагмент НЕ ДОЛЖЕН присутствовать.

 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                            :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Кадр X: 24 бита ( uint24 )
Координата X верхнего левого угла кадра равна Frame X * 2 .
Кадр Y: 24 бита ( uint24 )
Координата Y верхнего левого угла кадра равна Frame Y * 2 .
Ширина кадра минус один: 24 бита ( uint24 )
Ширина кадра , основанная на 1. Ширина кадра равна 1 + Frame Width Minus One .
Высота кадра минус один: 24 бита ( uint24 )
Высота фрейма на основе 1. Высота кадра равна 1 + Frame Height Minus One .
Продолжительность кадра: 24 бита ( uint24 )
Время ожидания перед отображением следующего кадра с шагом в 1 миллисекунду. Обратите внимание, что интерпретация длительности кадра 0 (и часто <= 10) определяется реализацией. Многие инструменты и браузеры назначают минимальную продолжительность, аналогичную GIF.
Зарезервировано: 6 бит
ДОЛЖЕН быть 0.
Метод смешивания (B): 1 бит

Указывает, как прозрачные пиксели текущего кадра должны смешиваться с соответствующими пикселями предыдущего холста:

  • 0 : Использовать альфа-смешение. После удаления предыдущего кадра визуализируйте текущий кадр на холсте с помощью альфа-смешивания (см. ниже). Если текущий кадр не имеет альфа-канала, примите значение альфа-канала равным 255, фактически заменив прямоугольник.

  • 1 : Не смешивать. После удаления предыдущего кадра визуализируйте текущий кадр на холсте, перезаписав прямоугольник, покрытый текущим кадром.

Метод утилизации (D): 1 бит

Указывает, как следует обрабатывать текущий кадр после его отображения (до рендеринга следующего кадра) на холсте:

  • 0 : Не утилизировать. Оставьте холст как есть.

  • 1 : Расположить по фоновому цвету. Заполните прямоугольник на холсте, покрываемый текущим кадром, цветом фона, указанным в чанке ANIM .

Примечания :

  • Удаление фрейма применяется только к прямоугольнику фрейма , то есть к прямоугольнику, определяемому Frame X , Frame Y , ширине и высоте кадра . Он может охватывать или не охватывать весь холст.

  • Альфа-смешение :

    Учитывая, что каждый из каналов R, G, B и A является 8-битным, а каналы RGB не умножаются предварительно на альфа-канал, формула наложения «dst» на «src» выглядит следующим образом:

    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
    
  • Альфа-смешивание СЛЕДУЕТ выполнять в линейном цветовом пространстве с учетом цветового профиля изображения. Если цветовой профиль отсутствует, предполагается sRGB. (Обратите внимание, что sRGB также необходимо линеаризовать из-за гаммы ~ 2,2).

Данные кадра: размер фрагмента16 байт.

Состоит из:

Примечание . Полезная нагрузка ANMF ( данные кадра выше) состоит из отдельных дополненных фрагментов, как описано в формате файла RIFF .

Альфа

 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...                        |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Зарезервировано (Rsv): 2 бита
ДОЛЖЕН быть 0 .
Предварительная обработка (P): 2 бита

Эти информативные биты используются для сигнализации предварительной обработки, которая была выполнена во время сжатия. Декодер может использовать эту информацию, например, для сглаживания значений или сглаживания градиентов перед отображением.

  • 0 : без предварительной обработки
  • 1 : снижение уровня
Метод фильтрации (F): 2 бита

Используемый метод фильтрации:

  • 0 : Нет.
  • 1 : Горизонтальный фильтр.
  • 2 : Вертикальный фильтр.
  • 3 : Градиентный фильтр.

Для каждого пикселя выполняется фильтрация с использованием следующих вычислений. Предположим, что альфа-значения, окружающие текущую позицию X , помечены как:

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

Мы пытаемся вычислить альфа-значение в позиции X Сначала делается прогноз в зависимости от метода фильтрации:

  • Метод 0 : предиктор = 0
  • Метод 1 : предиктор = A
  • Метод 2 : предиктор = B
  • Метод 3 : предсказатель = клип (A + B - C)

где clip(v) равно:

  • 0, если v < 0
  • 255, если v > 255
  • v иначе

Окончательное значение получается путем добавления распакованного значения X к предсказателю и использования арифметики по модулю-256 для переноса диапазона [256-511] в диапазон [0-255]:

alpha = (predictor + X) % 256

Существуют особые случаи для крайнего левого и самого верхнего положения пикселей:

  • Верхнее левое значение в местоположении (0,0) использует 0 в качестве значения предиктора. В противном случае,
  • Для методов горизонтальной или градиентной фильтрации самые левые пиксели в положении (0, y) прогнозируются с использованием положения (0, y-1) чуть выше.
  • Для методов вертикальной или градиентной фильтрации самые верхние пиксели в положении (x, 0) прогнозируются с использованием местоположения (x-1, 0) слева.

Декодеры не обязаны использовать эту информацию каким-либо определенным образом.

Метод сжатия (C): 2 бита

Используемый метод сжатия:

  • 0 : Без сжатия.
  • 1 : Сжато с использованием формата без потерь WebP.
Альфа-битовый поток: размер фрагмента1 байт.

Закодированный альфа-битовый поток.

Этот необязательный фрагмент содержит закодированные альфа-данные для этого кадра. Кадр, содержащий фрагмент 'VP8L', НЕ ДОЛЖЕН содержать этот фрагмент.

Обоснование : информация о прозрачности уже является частью фрагмента 'VP8L'.

Данные альфа-канала хранятся как несжатые необработанные данные (когда метод сжатия равен «0») или сжимаются с использованием формата без потерь (когда метод сжатия равен «1»).

  • Необработанные данные: состоят из последовательности байтов длины ширина * высота, содержащей все 8-битные значения прозрачности в порядке сканирования.

  • Сжатие формата без потерь: последовательность байтов представляет собой сжатый поток изображений (как описано в формате битового потока без потерь WebP ) с неявными размерами ширина x высота. То есть этот поток изображений НЕ содержит заголовков, описывающих размерность изображения.

    Обоснование : измерение уже известно из других источников, поэтому его повторное сохранение было бы избыточным и подверженным ошибкам.

    После декодирования потока изображения в значения цвета ARGB в соответствии с процессом, описанным в спецификации формата без потерь, информация о прозрачности должна быть извлечена из зеленого канала квадруплета ARGB.

    Обоснование : зеленый канал допускает дополнительные шаги преобразования в спецификации, в отличие от других каналов, которые могут улучшить сжатие.

Битовый поток (VP8/VP8L)

Этот фрагмент содержит сжатые данные битового потока для одного кадра.

Фрагмент битового потока может быть либо (i) фрагментом VP8 с использованием "VP8" (обратите внимание на значительный пробел в четвертом символе) в качестве тега, либо (ii) фрагментом VP8L с использованием "VP8L" в качестве тега.

Форматы фрагментов VP8 и 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('ICCP')                      |
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
:                       Color Profile                           :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Цветовой профиль: размер блока в байтах
ICC-профиль.

Этот фрагмент ДОЛЖЕН находиться перед данными изображения.

ДОЛЖЕН быть максимум один такой кусок. Если таких фрагментов больше, читатели МОГУТ игнорировать все, кроме первого. Подробнее см. в спецификации ICC .

Если этот фрагмент отсутствует, СЛЕДУЕТ использовать sRGB.

Метаданные

Метаданные могут храниться в блоках «EXIF» или «XMP».

ДОЛЖЕН быть не более одного фрагмента каждого типа («EXIF» и «XMP»). Если таких фрагментов больше, читатели МОГУТ игнорировать все, кроме первого. Кроме того, файл может содержать фрагменты «EXIF» и «XMP».

Фрагменты определяются следующим образом:

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                          :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Метаданные Exif: размер фрагмента в байтах
метаданные изображения в формате Exif.

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                           :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Метаданные XMP: размер фрагмента в байтах
метаданные изображения в формате XMP.

Обратите внимание, что четвертый символ в «XMP» FourCC — это пробел ASCII (%x20).

Дополнительные рекомендации по работе с метаданными можно найти в Руководстве по работе с метаданными Рабочей группы по метаданным .

Сборка холста из рамок

Здесь мы предоставляем обзор того, как читатель должен собрать холст в случае анимированного изображения. Обозначение VP8X.field означает поле в блоке 'VP8X' с таким же описанием.

Отображение холста с анимированным изображением ДОЛЖНО быть эквивалентно следующему псевдокоду:

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 ← ANIM.disposeMethod
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 dispose method dispose_method.
    canvas contains the decoded image.
    Show the contents of the canvas for
    frame_params.frameDuration * 1ms.

Примеры макетов файлов

Закодированное с потерями изображение с альфа-каналом может выглядеть следующим образом:

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

Изображение, закодированное без потерь, может выглядеть следующим образом:

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

Изображение без потерь с профилем ICC и метаданными XMP может выглядеть следующим образом:

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

Анимированное изображение с метаданными Exif может выглядеть следующим образом:

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)