mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 17:12:43 +00:00 
			
		
		
		
	LibGfx: Parse some of WebP 'VP8 ' chunk
This is for lossy compression, in which case a WebP file is a single VP8 key frame. This only parses the 10-byte frame header, which contains image dimensions (and some other things). For now, just dbgln_if() all data. Eventually we'll want to use at least width and height.
This commit is contained in:
		
							parent
							
								
									e56e7db9d4
								
							
						
					
					
						commit
						0774d2135c
					
				
					 1 changed files with 50 additions and 3 deletions
				
			
		|  | @ -147,11 +147,58 @@ static ErrorOr<Chunk> decode_webp_advance_chunk(WebPLoadingContext& context, Rea | |||
| } | ||||
| 
 | ||||
| // https://developers.google.com/speed/webp/docs/riff_container#simple_file_format_lossy
 | ||||
| // https://datatracker.ietf.org/doc/html/rfc6386#section-19 "Annex A: Bitstream Syntax"
 | ||||
| static ErrorOr<void> decode_webp_simple_lossy(WebPLoadingContext& context, Chunk const& vp8_chunk) | ||||
| { | ||||
|     // FIXME
 | ||||
|     (void)context; | ||||
|     (void)vp8_chunk; | ||||
|     VERIFY(vp8_chunk.type == FourCC("VP8 ")); | ||||
| 
 | ||||
|     if (vp8_chunk.data.size() < 10) | ||||
|         return context.error("WebPImageDecoderPlugin: 'VP8 ' chunk too small"); | ||||
| 
 | ||||
|     // FIXME: Eventually, this should probably call into LibVideo/VP8,
 | ||||
|     // and image decoders should move into LibImageDecoders which depends on both LibGfx and LibVideo.
 | ||||
|     // (LibVideo depends on LibGfx, so LibGfx can't depend on LibVideo itself.)
 | ||||
| 
 | ||||
|     // https://datatracker.ietf.org/doc/html/rfc6386#section-4 "Overview of Compressed Data Format"
 | ||||
|     // "The decoder is simply presented with a sequence of compressed frames [...]
 | ||||
|     //  The first frame presented to the decompressor is [...] a key frame.  [...]
 | ||||
|     //  [E]very compressed frame has three or more pieces. It begins with an uncompressed data chunk comprising 10 bytes in the case of key frames
 | ||||
| 
 | ||||
|     u8 const* data = vp8_chunk.data.data(); | ||||
| 
 | ||||
|     // https://datatracker.ietf.org/doc/html/rfc6386#section-9.1 "Uncompressed Data Chunk"
 | ||||
|     u32 frame_tag = data[0] | (data[1] << 8) | (data[2] << 16); | ||||
|     bool is_key_frame = (frame_tag & 1) == 0; // https://www.rfc-editor.org/errata/eid5534
 | ||||
|     u8 version = (frame_tag & 0xe) >> 1; | ||||
|     bool show_frame = (frame_tag & 0x10) != 0; | ||||
|     u32 size_of_first_partition = frame_tag >> 5; | ||||
| 
 | ||||
|     if (!is_key_frame) | ||||
|         return context.error("WebPImageDecoderPlugin: 'VP8 ' chunk not a key frame"); | ||||
| 
 | ||||
|     // FIXME: !show_frame does not make sense in a webp file either, probably?
 | ||||
| 
 | ||||
|     u32 start_code = data[3] | (data[4] << 8) | (data[5] << 16); | ||||
|     if (start_code != 0x2a019d) // https://www.rfc-editor.org/errata/eid7370
 | ||||
|         return context.error("WebPImageDecoderPlugin: 'VP8 ' chunk invalid start_code"); | ||||
| 
 | ||||
|     // "The scaling specifications for each dimension are encoded as follows.
 | ||||
|     //   0     | No upscaling (the most common case).
 | ||||
|     //   1     | Upscale by 5/4.
 | ||||
|     //   2     | Upscale by 5/3.
 | ||||
|     //   3     | Upscale by 2."
 | ||||
|     // This is a display-time operation and doesn't affect decoding.
 | ||||
|     u16 width_and_horizontal_scale = data[6] | (data[7] << 8); | ||||
|     u16 width = width_and_horizontal_scale & 0x3fff; | ||||
|     u8 horizontal_scale = width_and_horizontal_scale >> 14; | ||||
| 
 | ||||
|     u16 heigth_and_vertical_scale = data[8] | (data[9] << 8); | ||||
|     u16 height = heigth_and_vertical_scale & 0x3fff; | ||||
|     u8 vertical_scale = heigth_and_vertical_scale >> 14; | ||||
| 
 | ||||
|     dbgln_if(WEBP_DEBUG, "version {}, show_frame {}, size_of_first_partition {}, width {}, horizontal_scale {}, height {}, vertical_scale {}", | ||||
|         version, show_frame, size_of_first_partition, width, horizontal_scale, height, vertical_scale); | ||||
| 
 | ||||
|     return {}; | ||||
| } | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Nico Weber
						Nico Weber