@@ -201,3 +201,50 @@ reftest!(
201201 lossless_indexed_2bit_palette,
202202 lossless_indexed_4bit_palette
203203) ;
204+
205+ // Builds a minimal RIFF WebP containing only a VP8L header (no image data).
206+ // This is enough to test dimension parsing without needing valid pixel data.
207+ fn vp8l_dimensions_only_webp ( width_minus_one : u32 , height_minus_one : u32 ) -> Vec < u8 > {
208+ let packed = ( width_minus_one & 0x3FFF ) | ( ( height_minus_one & 0x3FFF ) << 14 ) ;
209+ let packed_le = packed. to_le_bytes ( ) ;
210+ // VP8L payload: 1-byte signature + 4-byte packed header = 5 bytes
211+ let payload: [ u8 ; 5 ] = [ 0x2F , packed_le[ 0 ] , packed_le[ 1 ] , packed_le[ 2 ] , packed_le[ 3 ] ] ;
212+ let chunk_size: u32 = payload. len ( ) as u32 ;
213+ // RIFF file_size = "WEBP"(4) + "VP8L"(4) + size_field(4) + payload(5) + padding(1) = 18
214+ let riff_size: u32 = 4 + 4 + 4 + chunk_size + ( chunk_size % 2 ) ;
215+ [
216+ b"RIFF" . as_slice ( ) ,
217+ & riff_size. to_le_bytes ( ) ,
218+ b"WEBP" ,
219+ b"VP8L" ,
220+ & chunk_size. to_le_bytes ( ) ,
221+ & payload,
222+ & [ 0x00 ] , // padding byte (chunk_size=5 is odd)
223+ ]
224+ . concat ( )
225+ }
226+
227+ #[ test]
228+ fn test_vp8l_max_width_dimensions ( ) {
229+ // Regression test: VP8L encodes (width - 1) in bits 0-13 and (height - 1) in bits 14-27.
230+ // The buggy formula `(1 + header) & 0x3FFF` returns 0 instead of 16384 when the encoded
231+ // value is 0x3FFF, because adding 1 carries into bit 14 before the mask is applied.
232+ // The correct formula is `(header & 0x3FFF) + 1`.
233+ let data = vp8l_dimensions_only_webp ( 16383 , 0 ) ;
234+ let decoder = image_webp:: WebPDecoder :: new ( Cursor :: new ( data) ) . unwrap ( ) ;
235+ assert_eq ! ( decoder. dimensions( ) , ( 16384 , 1 ) ) ;
236+ }
237+
238+ #[ test]
239+ fn test_vp8l_max_height_dimensions ( ) {
240+ let data = vp8l_dimensions_only_webp ( 0 , 16383 ) ;
241+ let decoder = image_webp:: WebPDecoder :: new ( Cursor :: new ( data) ) . unwrap ( ) ;
242+ assert_eq ! ( decoder. dimensions( ) , ( 1 , 16384 ) ) ;
243+ }
244+
245+ #[ test]
246+ fn test_vp8l_max_width_and_height_dimensions ( ) {
247+ let data = vp8l_dimensions_only_webp ( 16383 , 16383 ) ;
248+ let decoder = image_webp:: WebPDecoder :: new ( Cursor :: new ( data) ) . unwrap ( ) ;
249+ assert_eq ! ( decoder. dimensions( ) , ( 16384 , 16384 ) ) ;
250+ }
0 commit comments