บทนำ
WebP เป็นรูปแบบรูปภาพที่ใช้สําหรับ (1) การเข้ารหัสเฟรมหลัก VP8 เพื่อบีบอัดข้อมูลรูปภาพแบบสูญเสียบางส่วน หรือ (2) การเข้ารหัส WebP แบบไม่สูญเสียข้อมูล รูปแบบการเข้ารหัสเหล่านี้ควรมีประสิทธิภาพมากกว่ารูปแบบเก่าๆ เช่น JPEG, GIF และ PNG ได้รับการเพิ่มประสิทธิภาพสำหรับการโอนภาพอย่างรวดเร็วผ่านเครือข่าย (สำหรับ เช่น สำหรับเว็บไซต์) รูปแบบ WebP มีฟีเจอร์ที่เทียบเท่า (โปรไฟล์สี ข้อมูลเมตา ภาพเคลื่อนไหว ฯลฯ) กับรูปแบบอื่นๆ ด้วย เอกสารนี้อธิบายถึง โครงสร้างของไฟล์ WebP
คอนเทนเนอร์ WebP (ซึ่งก็คือคอนเทนเนอร์ RIFF สําหรับ WebP) ช่วยให้รองรับฟีเจอร์ได้ เหนือและเหนือกรณีการใช้งานพื้นฐานของ WebP (ซึ่งก็คือไฟล์ที่มี เข้ารหัสเป็นคีย์เฟรม VP8) คอนเทนเนอร์ WebP จะมี การสนับสนุนสำหรับรายการต่อไปนี้
การบีบอัดแบบไม่สูญเสียข้อมูล: สามารถบีบอัดรูปภาพแบบไม่สูญเสียรายละเอียด โดยใช้ รูปแบบแบบไม่สูญเสียรายละเอียด WebP
ข้อมูลเมตา: รูปภาพอาจมีข้อมูลเมตาที่จัดเก็บในรูปแบบไฟล์ภาพแบบเปลี่ยนรูปแบบได้ (Exif) หรือรูปแบบแพลตฟอร์มข้อมูลเมตาแบบขยาย (XMP)
ความโปร่งใส: รูปภาพอาจมีช่องอัลฟ่า
โปรไฟล์สี: รูปภาพอาจมีโปรไฟล์ ICC ที่ฝังอยู่ตามที่อธิบายโดย International Color Consortium
ภาพเคลื่อนไหว: รูปภาพอาจมีหลายเฟรมที่มีการหยุดชั่วคราว มาทำเป็นภาพเคลื่อนไหว
การตั้งชื่อ
ขอแนะนำให้ใช้ประเภทต่อไปนี้เมื่อพูดถึง WebP container:
ชื่อรูปแบบคอนเทนเนอร์ | WebP |
นามสกุลชื่อไฟล์ | .webp |
ประเภท MIME | รูปภาพ/webp |
ตัวระบุประเภทเครื่องแบบ | org.webmproject.webp |
คำศัพท์และ พื้นฐาน
คีย์เวิร์ดประเภท "ต้อง" "ต้องไม่" "จำเป็น" "จะ" "จะไม่" "ควร" "ไม่ควร" "แนะนำ" "ไม่แนะนำ" "อาจ" และ "ไม่บังคับ" ใน ให้ตีความเอกสารตาม BCP 14 RFC 2119 RFC 8174 เมื่อใด และเฉพาะเมื่อปรากฏในอักษรตัวพิมพ์ใหญ่ทั้งหมด ดังที่แสดงในที่นี้
ไฟล์ WebP มีรูปภาพนิ่ง (นั่นคือเมทริกซ์พิกเซลที่เข้ารหัส) หรือภาพเคลื่อนไหว หรืออาจมีความโปร่งใส ข้อมูล โปรไฟล์สี และข้อมูลเมตา เราเรียกเมทริกซ์พิกเซลว่าผืนผ้าใบของรูปภาพ
การนับบิตในแผนภาพกลุ่มเริ่มต้นที่ 0
สำหรับบิตที่มีนัยสำคัญที่สุด ('MSB 0') ตามที่อธิบายไว้ใน RFC 1166
คําศัพท์เพิ่มเติมที่ใช้ตลอดทั้งเอกสารมีดังนี้
- ผู้อ่าน/ผู้เขียน
- โค้ดที่อ่านไฟล์ WebP จะเรียกว่าโปรแกรมอ่าน ขณะที่โค้ดที่ เขียนว่านักเขียน
- uint16
- จำนวนเต็มแบบ 16 บิตแบบ Little Endian ที่ไม่มีค่า
- uint24
- จำนวนเต็ม 24 บิตแบบ Little Endian ที่ไม่มีค่าลงท้าย
- uint32
- จำนวนเต็มแบบ 32 บิตที่เป็นลูกเล่นที่ไม่มีเครื่องหมาย
- FourCC
- รหัส 4 อักขระ (FourCC) คือ uint32 ที่สร้างขึ้นโดยการต่อเชื่อมอักขระ ASCII 4 ตัวตามลําดับ Little-endian แปลว่า "aaaa" (0x61616161) และ "AAAA" (0x41414141) ถือเป็น FourCCs ที่ต่างกัน
- จาก 1
- ช่องจำนวนเต็มที่ไม่มีเครื่องหมายซึ่งจัดเก็บค่าชดเชยด้วย
-1
ตัวอย่างเช่น จะจัดเก็บค่า 25 เป็น 24 - 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 :
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- Chunk FourCC: 32 บิต
- รหัส ASCII 4 อักขระที่ใช้ระบุข้อมูลโค้ด
- ขนาดกลุ่ม: 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' |
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- "RIFF": 32 บิต
- อักขระ ASCII "R", "I", "F", "F"
- ขนาดไฟล์: 32 บิต (uint32)
- ขนาดของไฟล์ในหน่วยไบต์ โดยเริ่มจากออฟเซต 8 ค่าสูงสุดของ ช่องนี้มีขนาด 2^32 ลบ 10 ไบต์ ดังนั้นขนาดของทั้งไฟล์จึงอยู่ที่ ส่วนใหญ่ 4 GiB ลบ 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 บิตสตรีม
โปรดทราบว่าอักขระที่ 4 ใน 'VP8' FourCC คือการเว้นวรรคแบบ ASCII (0x20)
ข้อกำหนดรูปแบบ VP8 บิตสตรีมมีอธิบายอยู่ในรูปแบบข้อมูล VP8 และ คู่มือการถอดรหัส โปรดทราบว่าส่วนหัวของเฟรม VP8 มีเฟรม VP8 ความกว้างและความสูง ซึ่งจะถือว่าเป็นความกว้างและความสูงของผืนผ้าใบ
ข้อกำหนด VP8 อธิบายวิธีถอดรหัสรูปภาพเป็นรูปแบบ Y'CbCr หากต้องการแปลงเป็น RGB คุณควรใช้คําแนะนํา BT.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 ได้ที่ รูปแบบ Bitstream แบบไม่สูญเสียรายละเอียดของ WebP โปรดทราบว่าส่วนหัว VP8L มีความกว้างและความสูงของรูปภาพ VP8L ซึ่งจะถือว่าเป็นความกว้างและความสูงของภาพพิมพ์แคนวาส
รูปแบบไฟล์แบบขยาย
หมายเหตุ: เครื่องอ่านรุ่นเก่าอาจไม่รองรับไฟล์ที่ใช้รูปแบบแบบขยาย
ไฟล์รูปแบบแบบขยายประกอบด้วยรายการต่อไปนี้
ข้อมูล "VP8X" ที่มีข้อมูลเกี่ยวกับฟีเจอร์ที่ใช้ในไฟล์
ข้อมูล "ICCP" ที่ไม่บังคับซึ่งมีโปรไฟล์สี
"ANIM" ที่ไม่บังคับ กลุ่มที่มีข้อมูลการควบคุมภาพเคลื่อนไหว
ข้อมูลรูปภาพ
"EXIF" ที่ไม่บังคับ กลุ่มที่มีข้อมูลเมตา Exif
ข้อมูล "XMP" ที่ไม่บังคับซึ่งมีข้อมูลเมตา XMP
รายการข้อมูลโค้ดที่ไม่รู้จัก (ไม่บังคับ)
สำหรับภาพนิ่ง ข้อมูลรูปภาพจะประกอบด้วยเฟรมเดียว ซึ่งประกอบด้วย
ข้อมูลย่อยอัลฟ่า (ไม่บังคับ)
สำหรับภาพเคลื่อนไหว ข้อมูลรูปภาพประกอบด้วยหลายเฟรม ดูรายละเอียดเพิ่มเติมเกี่ยวกับเฟรมได้ในส่วนภาพเคลื่อนไหว
ข้อมูลทั้งหมดที่จำเป็นต่อการสร้างใหม่และการแก้สี ซึ่งได้แก่ 'VP8X', 'ICCP', 'ANIM', 'ANMF', 'ALPH', 'VP8' และ 'VP8L' จะต้องปรากฏตามลำดับที่อธิบายไว้ก่อนหน้านี้ ผู้อ่านอาจล้มเหลวเมื่อชิ้นส่วนจำนวนมากจำเป็นต่อการสร้างใหม่ และการแก้สีไม่ถูกต้อง
ข้อมูลเมตาและกลุ่มที่ไม่รู้จักอาจปรากฏไม่เป็นระเบียบ
เหตุผล: ข้อมูลส่วนที่จำเป็นต่อการสร้างใหม่ควรปรากฏในไฟล์ก่อนเพื่อให้โปรแกรมอ่านเริ่มถอดรหัสรูปภาพได้ก่อนที่จะได้รับข้อมูลทั้งหมด แอปพลิเคชันอาจได้รับประโยชน์จาก การเรียงลำดับข้อมูลเมตาและ กลุ่มที่กำหนดเองเพื่อให้เหมาะกับการใช้งาน
ส่วนหัวของไฟล์ 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 บิต
- กำหนดว่าไฟล์มี "ICCP" หรือไม่ เป็นกลุ่ม
- อัลฟ่า (L): 1 บิต
- กำหนดว่าเฟรมใดๆ ของรูปภาพมีข้อมูลความโปร่งใสหรือไม่ ("อัลฟ่า")
- ข้อมูลเมตา Exif (E): 1 บิต
- กำหนดว่าไฟล์มีข้อมูลเมตา Exif หรือไม่
- ข้อมูลเมตา XMP (X): 1 บิต
- ตั้งค่าหากไฟล์มีข้อมูลเมตา XMP
- ภาพเคลื่อนไหว (A): 1 บิต
- ตั้งค่าหากเป็นภาพเคลื่อนไหว ข้อมูลใน "ANIM" และ "ANMF" กลุ่มควรเป็น ซึ่งใช้ควบคุมภาพเคลื่อนไหว
- สงวนไว้ (R): 1 บิต
- ต้องเป็น
0
ผู้อ่านต้องไม่สนใจช่องนี้ - สงวนไว้: 24 บิต
- ต้องเป็น
0
ผู้อ่านต้องไม่สนใจช่องนี้ - ความกว้างของภาพพิมพ์แคนวาสลบ 1: 24 บิต ความกว้างของผืนผ้าใบเป็นพิกเซลแบบ
- ฐาน 1
ความกว้างของภาพพิมพ์แคนวาสจริงคือ
1 Canvas Width Minus One
- ความสูงลบของ Canvas ที่ 1: 24 บิต
- ความสูงของแคนวาสตาม 1 หน่วยเป็นพิกเซล
ความสูงของแคนวาสจริงคือ
1 Canvas Height Minus One
ผลคูณของความกว้างของแคนวาสและความสูงของแคนวาสต้องไม่เกิน 2^32 - 1
ข้อมูลจำเพาะในอนาคตอาจเพิ่มช่องอื่นๆ ไม่ต้องสนใจช่องที่ไม่รู้จัก
แอนิเมชัน
ภาพเคลื่อนไหวควบคุมโดย "ANIM" และ "ANMF" เป็นกลุ่ม
ข้อมูลโค้ด "ANIM"
สำหรับรูปภาพเคลื่อนไหว ข้อมูลโค้ดนี้จะมีพารามิเตอร์ส่วนกลางของภาพเคลื่อนไหว
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" ตั้งค่ากลุ่มแล้ว หากไม่ได้ตั้งค่าแฟล็กภาพเคลื่อนไหวและมีกลุ่มนี้อยู่ จะต้อง ถูกละเว้น
ข้อมูลโค้ด "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
- ความกว้างของกรอบลบที่ 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
ผู้อ่านต้องไม่สนใจช่องนี้ - วิธีการผสม (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
ควรดำเนินการไล่สีตัวอักษรในพื้นที่สีแบบเส้นตรง โดยพิจารณา โปรไฟล์สีของรูปภาพ หากไม่มีโปรไฟล์สี ระบบจะถือว่าใช้ RGB มาตรฐาน (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
: ตัวทำนาย = clip(A B - C)
โดยที่ clip(v)
เท่ากับ
- 0 ถ้า v < 0
- 255 ถ้า v > 255 หรือ
- หากเป็นอย่างอื่น
ค่าสุดท้ายได้มาจากการเพิ่มค่าที่ขยาย X
ลงในตัวคาดการณ์ และใช้การดำเนินการทางคณิตศาสตร์แบบ modulo-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" (โปรดทราบว่า ช่องว่างอักขระที่ 4 อย่างมีนัยสำคัญ) เป็น FourCC หรือ (2) "VP8L" กลุ่ม โดยใช้ "VP8L" ว่าเป็น FourCC
รูปแบบของ "VP8" และ "VP8L" กลุ่มข้อมูลตามที่อธิบายไว้ในส่วน รูปแบบไฟล์แบบง่าย (สูญหาย) และรูปแบบไฟล์แบบง่าย (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
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| ChunkHeader('ICCP') |
| |
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
: Color Profile :
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- โปรไฟล์สี: ขนาดกลุ่ม ไบต์
- โปรไฟล์ ICC
ข้อมูลส่วนนี้ต้องปรากฏก่อนข้อมูลรูปภาพ
ไม่ควรมีข้อมูลดังกล่าวเกิน 1 รายการ หากมีกลุ่มลักษณะนี้มากกว่า อาจละเว้นทั้งหมดยกเว้นรายการแรก โปรดดูรายละเอียดในข้อกำหนดของ ICC
หากไม่มีส่วนนี้แสดงว่าควรใช้ sRGB
ข้อมูลเมตา
ข้อมูลเมตาสามารถจัดเก็บไว้ในข้อมูลโค้ด "EXIF" หรือ "XMP"
แต่ละประเภทควรมีกลุ่มไม่เกิน 1 กลุ่ม ("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
โปรดทราบว่าอักขระที่ 4 ใน "XMP " FourCC คือการเว้นวรรคแบบ ASCII (0x20)
ดูคำแนะนำเพิ่มเติมเกี่ยวกับการจัดการข้อมูลเมตาได้ใน"หลักเกณฑ์สำหรับการจัดการข้อมูลเมตา" ของกลุ่มทำงานด้านข้อมูลเมตา
กลุ่มที่ไม่รู้จัก
ข้อมูลโค้ด 4 ตัวอักษรของข้อมูล RIFF (อธิบายไว้ในส่วนรูปแบบไฟล์ RIFF) ที่แตกต่างจากข้อมูลโค้ด 4 ตัวอักษรของข้อมูลใดๆ ที่อธิบายไว้ในเอกสารนี้ จะถือว่าเป็นข้อมูลที่ไม่รู้จัก
เหตุผล: การให้สิทธิ์สำหรับข้อมูลที่ไม่รู้จักเป็นการเผื่อไว้สำหรับการขยายรูปแบบในอนาคต และช่วยให้จัดเก็บข้อมูลเฉพาะแอปพลิเคชันได้
ไฟล์อาจมีส่วนที่ไม่รู้จัก:
- ที่ส่วนท้ายของไฟล์ตามที่อธิบายไว้ในไฟล์ WebP แบบขยาย ส่วนหัว หรือ
- ที่ส่วนท้ายของข้อมูล "ANMF" ตามที่อธิบายไว้ในส่วนภาพเคลื่อนไหว
ผู้อ่านควรละเว้นข้อมูลส่วนนี้ นักเขียนควรเก็บรักษาเนื้อหาเหล่านี้ไว้ ลำดับเดิม (เว้นแต่ผู้ลงโฆษณาตั้งใจจะแก้ไขกลุ่มเหล่านี้โดยเฉพาะ)
การประกอบภาพพิมพ์แคนวาสจากกรอบ
ในส่วนนี้เราจะอธิบายภาพรวมเกี่ยวกับวิธีที่เครื่องอ่านต้องประกอบภาพพิมพ์แคนวาส ของภาพเคลื่อนไหว
กระบวนการเริ่มต้นด้วยการสร้างผืนผ้าใบโดยใช้ขนาดที่ระบุไว้ในข้อมูลโค้ด "VP8X" ซึ่งกว้าง Canvas Width Minus One 1
พิกเซลและสูง Canvas Height Minus
One 1
พิกเซล ฟิลด์ Loop Count
จาก "ANIM" กลุ่มควบคุมวิธีการ
จะแสดงกระบวนการสร้างภาพเคลื่อนไหวซ้ำหลายครั้ง นี่คือLoop Count - 1
สำหรับ
ค่า Loop Count
ที่ไม่ใช่ 0 หรืออนันต์หาก Loop Count
เป็น 0
ในช่วงเริ่มต้นการทำซ้ำวนซ้ำแต่ละครั้ง ผืนผ้าใบจะถูกเติมโดยใช้ สีพื้นหลังจาก "ANIM" กลุ่มหรือสีที่แอปพลิเคชันกำหนด
"ANMF" กลุ่มจะประกอบด้วยเฟรมแต่ละเฟรมตามลำดับการแสดงผล ก่อนแสดงผล
แต่ละเฟรม ระบบจะใช้ Disposal method
ของเฟรมก่อนหน้า
การแสดงผลของเฟรมที่ถอดรหัสจะเริ่มที่พิกัดพิกัดคาร์ทีเซียน (2 *
Frame X
, 2 * Frame Y
) โดยใช้มุมซ้ายบนของผืนผ้าใบเป็นจุดเริ่มต้น
กว้าง Frame Width Minus One 1
พิกเซล x 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 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
ตัวอย่างเลย์เอาต์ไฟล์
รูปภาพที่เข้ารหัสแบบสูญเสียบางส่วนที่มีอัลฟ่าอาจมีลักษณะดังนี้
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)