WebP 컨테이너 사양

소개

WebP는 (i) VP8 키 프레임 인코딩을 사용하여 이미지 데이터를 손실 방식으로 압축하거나 (ii) WebP 무손실 인코딩을 사용하는 이미지 형식입니다. 이러한 인코딩 체계는 JPEG, GIF, PNG와 같은 이전 형식보다 더 효율적이어야 합니다. 네트워크를 통한 빠른 이미지 전송 (예: 웹사이트)에 최적화되어 있습니다. WebP 형식은 다른 형식과 동일한 기능 (색상 프로필, 메타데이터, 애니메이션 등)을 가지고 있습니다. 이 문서에서는 WebP 파일의 구조를 설명합니다.

WebP 컨테이너 (즉, WebP용 RIFF 컨테이너)는 WebP의 기본 사용 사례 (즉, VP8 키 프레임으로 인코딩된 단일 이미지를 포함하는 파일) 이상의 기능 지원을 허용합니다. WebP 컨테이너는 다음에 관한 추가 지원을 제공합니다.

  • 무손실 압축: 이미지를 WebP 손실 없는 형식을 사용하여 무손실 압축할 수 있습니다.

  • 메타데이터: 이미지에는 Exif (Exchangeable Image File Format) 또는 XMP (Extensible Metadata Platform) 형식으로 저장된 메타데이터가 있을 수 있습니다.

  • 투명도: 이미지에는 투명도, 즉 알파 채널이 있을 수 있습니다.

  • 색상 프로필: International Color Consortium에서 설명한 대로 이미지에 ICC 프로필이 삽입되어 있을 수 있습니다.

  • 애니메이션: 이미지는 여러 프레임 사이에 일시중지가 있어 애니메이션으로 만들 수 있습니다.

이름 지정

WebP 컨테이너를 참조할 때는 다음 유형을 사용하는 것이 좋습니다(RECOMMENDED).

컨테이너 형식 이름WebP
파일 이름 확장자.webp
MIME 유형이미지/webp
유니폼 유형 식별자org.webmproject.webp

용어 및 기본사항

이 문서의 핵심 단어 'MUST', 'MUST NOT', 'REQUIRED', 'SHALL', 'SHALL NOT', 'SHOULD', 'SHOULD NOT', 'RECOMMENDED', 'NOT RECOMMENDED', 'MAY', 'OPTIONAL'은 모두 BCP 14 RFC 2119, RFC 817에 모두 설명된 대로 모두 대문자로 해석되어야 합니다.

WebP 파일에는 정지 이미지 (즉, 인코딩된 픽셀 매트릭스) 또는 애니메이션이 포함됩니다. 선택적으로, 투명도 정보, 색상 프로필, 메타데이터를 포함할 수도 있습니다. 픽셀 행렬을 이미지의 캔버스라고 합니다.

청크 다이어그램의 비트 번호 지정은 RFC 1166에 설명된 대로 최상위 비트('MSB 0')의 0에서 시작됩니다.

다음은 이 문서 전체에서 사용되는 추가 용어입니다.

독자/작성자
WebP 파일을 읽는 코드를 리더라고 하며, 이 파일을 쓰는 코드를 작성기라고 합니다.
uint16
부호 없는 16비트 little-endian 정수입니다.
uint24
부호 없는 24비트 bit-endian 정수입니다.
uint32
부호 없는 32비트 little-endian 정수입니다.
FourCC
4자리 코드 (FourCC)는 ASCII 문자 4개를 little-endian 순서로 연결하여 만든 uint32입니다. 즉, 'aaaa' (0x61616161)와 'AAAA' (0x41414141)는 서로 다른 FourCCs로 취급됩니다.
1기반
-1로 오프셋 값을 저장하는 부호 없는 정수 필드입니다. 예를 들어 이러한 필드는 값 2524로 저장합니다.
ChunkHeader('ABCD')
개별 청크의 FourCC청크 크기 헤더를 설명하는 데 사용됩니다. 여기서 'ABCD'는 청크의 FourCC입니다. 이 요소의 크기는 8바이트입니다.

RIFF 파일 형식

WebP 파일 형식은 RIFF (Resource Interchange File Format) 문서 형식을 기반으로 합니다.

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 4자리 코드입니다.
청크 크기: 32비트 (uint32)
바이트 단위의 청크 크기이며 이 필드, 청크 식별자 또는 패딩은 포함되지 않습니다.
청크 페이로드: 청크 크기 바이트
데이터 페이로드입니다. 청크 크기가 홀수인 경우 단일 패딩 바이트(RIFF를 준수하려면 0이어야 함)가 추가됩니다.

참고: 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'      |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
'RIFF': 32비트
ASCII 문자 'R', 'I', 'F', 'F'입니다.
파일 크기: 32비트 (uint32)
바이트 단위의 파일 크기이며 오프셋 8에서 시작합니다. 이 필드의 최댓값은 2^32에서 10바이트를 뺀 값이므로 전체 파일의 크기는 최대 4GiB에서 2바이트를 뺀 값입니다.
'WEBP': 32비트
ASCII 문자 'W', 'E', 'B', 'P'입니다.

WebP 파일은 FourCC 'WEBP'가 있는 RIFF 헤더로 시작해야 합니다. 헤더의 파일 크기는 뒤에 오는 청크의 총 크기에 'WEBP' FourCC의 4바이트를 더한 값입니다. 파일은 File Size에 의해 지정된 데이터 이후의 데이터를 포함하면 안 됩니다(SHOULD NOT). 리더는 후행 데이터를 무시하고 이러한 파일을 파싱할 수 있습니다(MAY). 청크의 크기는 짝수이므로 RIFF 헤더에 지정된 크기도 짝수입니다. 개별 청크의 콘텐츠는 다음 섹션에서 설명합니다.

단순 파일 형식 (손실)

이미지에 손실이 있는 인코딩이 필요하고 투명도 또는 확장 형식에서 제공하는 기타 고급 기능이 필요하지 않은 경우 이 레이아웃을 사용해야 합니다(SHOULD). 이 레이아웃의 파일은 크기가 더 작으며 이전 소프트웨어에서 지원됩니다.

단순 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 공백 (0x20)입니다.

VP8 비트스트림 형식 사양은 VP8 데이터 형식 및 디코딩 가이드에 설명되어 있습니다. VP8 프레임 헤더에는 VP8 프레임 너비와 높이가 포함됩니다. 이 값은 캔버스의 너비와 높이로 간주됩니다.

VP8 사양은 이미지를 Y'CbCr 형식으로 디코딩하는 방법을 설명합니다. RGB로 변환하려면 권장사항 BT.601을 사용해야 합니다(SHOULD). 애플리케이션은 다른 변환 메서드를 사용할 수 있지만(MAY) 시각적 결과는 디코더 간에 다를 수 있습니다.

단순 파일 형식 (무손실)

참고: 고학년 아동의 경우 무손실 형식을 사용하는 파일을 지원하지 않을 수 있습니다.

이미지에 무손실 인코딩(선택사항인 투명도 채널 포함)이 필요하고 확장 형식에서 제공하는 고급 기능이 필요하지 않은 경우 이 레이아웃을 사용해야 합니다(SHOULD).

단순 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 무손실 비트스트림 형식에서 확인할 수 있습니다. VP8L 헤더에는 VP8L 이미지 너비와 높이가 포함됩니다. 이 값은 캔버스의 너비와 높이로 간주됩니다.

확장 파일 형식

참고: 고학년 아동 독자는 확장 형식을 사용한 파일을 지원하지 않을 수 있습니다.

확장 형식 파일은 다음으로 구성됩니다.

  • 파일에서 사용된 기능에 대한 정보가 포함된 'VP8X' 청크입니다.

  • 색상 프로필이 있는 'ICCP' 청크(선택사항)입니다.

  • 애니메이션 컨트롤 데이터가 포함된 'ANIM' 청크(선택사항)입니다.

  • 이미지 데이터입니다.

  • Exif 메타데이터가 포함된 'EXIF' 청크(선택사항)

  • XMP 메타데이터가 포함된 'XMP ' 청크(선택사항)

  • 알 수 없는 청크의 선택적 목록입니다.

스틸 이미지의 경우 이미지 데이터는 다음으로 구성된 단일 프레임으로 구성됩니다.

애니메이션 이미지의 경우 이미지 데이터는 여러 프레임으로 구성됩니다. 프레임에 관한 자세한 내용은 애니메이션 섹션을 참고하세요.

재구성 및 색상 보정에 필요한 모든 청크('VP8X', 'ICCP', 'ANIM', 'ANMF', 'ALPH', 'VP8', 'VP8L')는 앞에서 설명한 순서대로 표시되어야 합니다(MUST). 판독기는 재구성 및 색상 보정에 필요한 청크의 순서가 잘못된 경우 실패해야 합니다(SHOULD).

메타데이터알 수 없는 청크는 순서가 잘못되어 표시될 수 있습니다(MAY).

사유: 리더가 모든 데이터를 수신하기 전에 이미지 디코딩을 시작할 수 있도록 재구성에 필요한 청크가 파일에서 먼저 나타나야 합니다. 애플리케이션은 구현에 맞게 메타데이터와 커스텀 청크의 순서를 다르게 하는 것이 유용할 수 있습니다.

확장 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여야 합니다. 독자는 이 필드를 무시해야 합니다(MUST).
ICC 프로필 (I): 1비트
파일에 'ICCP' 청크가 포함되어 있는 경우 설정합니다.
알파 (L): 1비트
이미지 프레임 중 하나라도 투명도 정보('알파')를 포함하는 경우 설정합니다.
Exif 메타데이터 (E): 1비트
파일에 Exif 메타데이터가 포함되어 있는지 설정합니다.
XMP 메타데이터 (X): 1비트
파일에 XMP 메타데이터가 포함되어 있는지 설정합니다.
애니메이션 (A): 1비트
애니메이션 이미지인 경우 설정합니다. 'ANIM' 및 'ANMF' 덩어리의 데이터를 사용하여 애니메이션을 제어해야 합니다.
예약됨 (R): 1비트
0여야 합니다. 독자는 이 필드를 무시해야 합니다(MUST).
예약됨: 24비트
0여야 합니다. 독자는 이 필드를 무시해야 합니다(MUST).
캔버스 너비에서 1을 뺀 값: 24비트
1부터 시작하는 캔버스 너비입니다(단위: 픽셀). 실제 캔버스 너비는 1 + Canvas Width Minus One입니다.
캔버스 높이에서 1을 뺀 값: 24비트
1부터 시작하는 캔버스 높이입니다(단위: 픽셀). 실제 캔버스 높이는 1 + Canvas Height Minus One입니다.

캔버스 너비캔버스 높이의 곱은 2^32 - 1 이하여야 합니다(MUST).

향후 사양에 따라 필드가 더 추가될 수 있습니다. 알 수 없는 필드는 무시해야 합니다(MUST).

애니메이션

애니메이션은 '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)
캔버스의 기본 배경 색상을 [파란색, 녹색, 빨간색, 알파] 바이트 순서로 표시합니다. 이 색상은 프레임 주변 캔버스의 사용되지 않는 공간과 첫 번째 프레임의 투명 픽셀을 채우는 데 사용할 수 있습니다(MAY). 폐기 메서드가 1인 경우 배경 색상도 사용됩니다.

참고:

  • 'VP8X' 청크알파 플래그가 설정되지 않은 경우에도 배경 색상은 불투명하지 않은 알파 값을 포함할 수 있습니다(MAY).

  • 뷰어 애플리케이션은 배경 색상 값을 힌트로 취급해야 하며(SHOULD) 이를 사용할 필요가 없습니다.

  • 캔버스는 각 루프의 시작 부분에서 지워집니다. 이를 위해 배경 색상을 사용할 수 있습니다(MAY).

루프 수: 16비트 (uint16)
애니메이션을 반복하는 횟수입니다. 0이면 무한을 의미합니다.

이 청크는 'VP8X' 청크의 Animation 플래그가 설정된 경우 표시되어야 합니다(MUST). Animation 플래그가 설정되지 않고 이 청크가 있는 경우 무시해야 합니다(MUST).

'ANMF' 덩어리:

애니메이션 이미지의 경우 이 청크에는 단일 프레임에 관한 정보가 포함됩니다. 애니메이션 플래그가 설정되지 않은 경우 이 청크가 있으면 안 됩니다(SHOULD NOT).

 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입니다.
프레임 너비에서 1을 뺀 값: 24비트 (uint24)
프레임의 1부터 시작하는 너비입니다. 프레임 너비는 1 + Frame Width Minus One입니다.
프레임 높이에서 1을 뺀 값: 24비트 (uint24)
프레임의 1부터 시작하는 높이입니다. 프레임 높이는 1 + Frame Height Minus One입니다.
프레임 지속 시간: 24비트 (uint24)
다음 프레임을 표시하기 전에 대기하는 시간입니다(1밀리초 단위). 프레임 지속 시간이 0 (일반적으로 10 이하)인 경우의 해석은 구현에 의해 정의됩니다. 많은 도구와 브라우저는 GIF와 유사한 최소 길이를 할당합니다.
예약됨: 6비트
0여야 합니다. 독자는 이 필드를 무시해야 합니다(MUST).
블렌딩 방법 (B): 1비트

현재 프레임의 투명 픽셀이 이전 캔버스의 상응하는 픽셀과 블렌딩되는 방식을 나타냅니다.

  • 0: 알파 혼합을 사용합니다. 이전 프레임을 삭제한 후 알파 블렌딩을 사용하여 캔버스의 현재 프레임을 렌더링합니다 (아래 참고). 현재 프레임에 알파 채널이 없으면 알파 값이 255라고 가정하여 직사각형을 실질적으로 대체합니다.

  • 1: 혼합하지 않습니다. 이전 프레임을 삭제한 후 현재 프레임으로 덮인 직사각형을 덮어써서 캔버스의 현재 프레임을 렌더링합니다.

폐기 방법 (D): 1비트

현재 프레임이 캔버스에 표시된 후 (다음 프레임을 렌더링하기 전에) 처리되는 방식을 나타냅니다.

  • 0: 폐기하지 않습니다. 캔버스는 그대로 둡니다.

  • 1: 배경 색상으로 삭제합니다. 현재 프레임으로 덮인 캔버스의 직사각형'ANIM' 청크에 지정된 배경 색상으로 채웁니다.

참고:

  • 프레임 처리는 프레임 직사각형, 즉 프레임 X, 프레임 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
    
  • 알파 블렌딩은 이미지의 색상 프로필을 고려하여 선형 색상 공간에서 실행되어야 합니다(SHOULD). 색상 프로필이 없으면 표준 RGB (sRGB)로 가정됩니다. 참고로 ~2.2의 감마로 인해 sRGB도 선형화해야 합니다.

프레임 데이터: 청크 크기 - 16바이트

구성 요소:

참고: 'ANMF' 페이로드인 Frame DataRIFF 파일 형식에 설명된 대로 패딩된 개별 청크로 구성됩니다.

알파

 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여야 합니다. 독자는 이 필드를 무시해야 합니다(MUST).
사전 처리 (P): 2비트

이러한 정보 제공 비트는 압축 중에 실행된 사전 처리를 알리는 데 사용됩니다. 디코더는 이 정보를 사용하여 표시 전에 값을 디더링하거나 경사를 평활화하는 등의 작업을 할 수 있습니다.

  • 0: 사전 처리가 없습니다.
  • 1: 레벨 축소.

디코더는 지정된 방식으로 이 정보를 사용할 필요가 없습니다.

필터링 방법 (F): 2비트

사용되는 필터링 방법은 다음과 같습니다.

  • 0: 없음.
  • 1: 가로 필터.
  • 2: 세로 필터.
  • 3: 그라데이션 필터.

각 픽셀에 대해 다음 계산을 사용하여 필터링이 수행됩니다. 현재 X 위치를 둘러싼 알파 값에 다음과 같은 라벨이 지정되어 있다고 가정합니다.

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

위치 X에서 알파 값을 계산하려고 합니다. 먼저 필터링 방법에 따라 예측이 이루어집니다.

  • 메서드 0: 예측자 = 0
  • 메서드 1: 예측자 = A
  • 메서드 2: 예측자 = B
  • 메서드 3: predictor = clip(A + B - C)

여기서 clip(v)는 다음과 같습니다.

  • v < 0이면 0,
  • v > 255인 경우 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' 청크가 포함된 프레임은 이 청크를 포함하면 안 됩니다(SHOULD NOT).

사유: 투명성 정보는 이미 'VP8L' 청크의 일부입니다.

알파 채널 데이터는 압축되지 않은 원시 데이터 (압축 방법이 '0'인 경우)로 저장되거나 무손실 형식(압축 방법이 '1'인 경우)을 사용하여 압축됩니다.

  • 원시 데이터: 길이 = 너비 * 높이의 바이트 시퀀스로 구성되며 모든 8비트 투명도 값이 스캔 순서로 포함됩니다.

  • 무손실 형식 압축: 바이트 시퀀스는 암시적 크기(너비 x 높이)의 압축된 이미지 스트림('WebP 손실 없는 비트스트림 형식')입니다. 즉, 이 이미지 스트림에 이미지 크기를 설명하는 헤더가 포함되어 있지 않습니다.

    사유: 측정기준이 다른 소스에서 이미 알려져 있으므로 다시 저장하면 중복되고 오류가 발생하기 쉽습니다.

    이미지 스트림이 Alpha, Red, Green, Blue (ARGB) 색상 값으로 디코딩되면 무손실 형식 사양에 설명된 프로세스에 따라 ARGB 4개의 green 채널에서 투명도 정보를 추출해야 합니다.

    사유: 녹색 채널은 다른 채널과 달리 사양에서 추가 변환 단계가 허용되어 압축을 개선할 수 있습니다.

비트스트림 (VP8/VP8L)

이 청크에는 단일 프레임의 압축된 비트스트림 데이터가 포함됩니다.

비트스트림 청크는 (i) 'VP8 ' (중요한 네 번째 문자 공간에 유의)을 FourCC로 사용하는 'VP8 ' 청크 또는 (ii) 'VP8L'을 FourCC로 사용하는 '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 프로필

이 청크는 이미지 데이터 앞에 표시되어야 합니다(MUST).

이러한 청크는 최대 1개여야 합니다(SHOULD). 이러한 청크가 더 있다면 판독기는 첫 번째 청크를 제외한 모든 청크를 무시할 수 있습니다(MAY). 자세한 내용은 ICC 사양을 참조하세요.

이 청크가 없으면 sRGB를 가정해야 합니다(SHOULD).

메타데이터

메타데이터는 'EXIF' 또는 'XMP ' 청크에 저장할 수 있습니다.

각 유형('EXIF' 및 'XMP ')의 청크는 최대 1개여야 합니다(SHOULD). 이러한 청크가 더 많은 경우 판독기는 첫 번째 청크를 제외한 모든 청크를 무시할 수 있습니다(MAY).

청크는 다음과 같이 정의됩니다.

'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 공백 (0x20)입니다.

메타데이터 처리에 관한 추가 안내는 메타데이터 실무 그룹의 '메타데이터 처리 가이드라인'에서 확인할 수 있습니다.

알 수 없는 덩어리

FourCC가 이 문서에 설명된 모든 청크와 다른 RIFF 청크 (RIFF 파일 형식 섹션에 설명됨)는 알 수 없는 청크로 간주됩니다.

사유: 알 수 없는 청크를 허용하면 형식을 향후 확장에 대비할 수 있고 애플리케이션별 데이터의 저장도 가능합니다.

파일은 알 수 없는 청크를 포함할 수 있습니다(MAY).

판독기는 이러한 청크를 무시해야 합니다(SHOULD). 작성자는 원래 순서로 청크를 보존해야 합니다 (SHOULD). 단, 이러한 청크를 수정할 의도가 있는 경우는 예외입니다.

프레임으로 캔버스 조립

여기에서는 애니메이션 이미지의 경우 독자가 캔버스를 조립해야 하는 방법을 간략하게 설명합니다.

먼저 'VP8X' 청크에 제공된 크기(가로 Canvas Width Minus One + 1픽셀, 높이 Canvas Height Minus One + 1픽셀)를 사용하여 캔버스를 만듭니다. 'ANIM' 청크의 Loop Count 필드는 애니메이션 프로세스가 반복되는 횟수를 제어합니다. 0이 아닌 Loop Count 값의 경우 Loop Count - 1이고 Loop Count이 0인 경우 무한합니다.

각 루프 반복이 시작될 때 캔버스는 'ANIM' 청크의 배경 색상이나 애플리케이션에서 정의한 색상으로 채워집니다.

'ANMF' 청크에는 표시 순서대로 지정된 개별 프레임이 포함됩니다. 각 프레임을 렌더링하기 전에 이전 프레임의 Disposal method가 적용됩니다.

디코딩된 프레임의 렌더링은 캔버스의 왼쪽 상단을 원점으로 사용하여 데카르트 좌표 (2 * Frame X, 2 * Frame Y)로 시작됩니다. 너비 Frame Width Minus One + 1픽셀, 높이 Frame Height Minus One + 1픽셀은 Blending method를 사용하여 캔버스에 렌더링됩니다.

캔버스는 Frame Duration밀리초 동안 표시됩니다. 이는 'ANMF' 청크에 의해 지정된 모든 프레임이 표시될 때까지 계속됩니다. 그런 다음 새 루프 반복이 시작되거나 모든 반복이 완료되면 캔버스가 최종 상태로 남습니다.

다음 의사 코드는 렌더링 프로세스를 보여줍니다. VP8X.field 표기법은 설명이 동일한 'VP8X' 청크의 필드를 의미합니다.

VP8X.flags.hasAnimation MUST be TRUE
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
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
    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

파일 레이아웃 예

알파가 있는 손실(lossy) 인코딩 이미지는 다음과 같습니다.

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

손실 없이 인코딩된 이미지는 다음과 같습니다.

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

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)