@@ -395,25 +395,34 @@ where
395
395
}
396
396
397
397
fn write_signed_int ( int : i32 , writer : & mut Cursor < Vec < u8 > > ) -> Result < ( ) > {
398
- let start_pos = int. trailing_zeros ( ) as usize ;
399
- write_int ( 21 , int. to_be_bytes ( ) , start_pos, writer)
398
+ write_int ( 21 , int. to_be_bytes ( ) , 4 , writer)
399
+ }
400
+
401
+ fn bytes_to_occupy_uint ( uint : u32 ) -> usize {
402
+ if uint == 0 {
403
+ return 1 ;
404
+ }
405
+
406
+ let ret = 4 - ( uint. to_le ( ) . leading_zeros ( ) >> 3 ) as usize ;
407
+ if ret == 3 {
408
+ return 4 ;
409
+ }
410
+ ret
400
411
}
401
412
402
413
fn write_unsigned_int ( uint : u32 , writer : & mut Cursor < Vec < u8 > > ) -> Result < ( ) > {
403
- let start_pos = uint . trailing_zeros ( ) as usize ;
404
- write_int ( 22 , uint. to_be_bytes ( ) , start_pos , writer)
414
+ let bytes_needed = bytes_to_occupy_uint ( uint ) ;
415
+ write_int ( 22 , uint. to_be_bytes ( ) , bytes_needed , writer)
405
416
}
406
417
407
418
fn write_int (
408
419
flags : u32 ,
409
420
bytes : [ u8 ; 4 ] ,
410
- mut start_pos : usize ,
421
+ bytes_needed : usize ,
411
422
writer : & mut Cursor < Vec < u8 > > ,
412
423
) -> Result < ( ) > {
413
- if start_pos == 1 || start_pos == 4 {
414
- start_pos = 0 ;
415
- }
416
- write_data ( flags, & bytes[ start_pos..] , writer)
424
+ debug_assert ! ( bytes_needed != 0 ) ;
425
+ write_data ( flags, & bytes[ 4 - bytes_needed..] , writer)
417
426
}
418
427
419
428
fn write_picture ( picture : & Picture , writer : & mut Cursor < Vec < u8 > > ) -> Result < ( ) > {
@@ -459,3 +468,62 @@ fn write_data(flags: u32, data: &[u8], writer: &mut Cursor<Vec<u8>>) -> Result<(
459
468
460
469
Ok ( ( ) )
461
470
}
471
+
472
+ #[ cfg( test) ]
473
+ mod tests {
474
+ use crate :: mp4:: ilst:: write:: bytes_to_occupy_uint;
475
+
476
+ macro_rules! int_test {
477
+ (
478
+ func: $fun: expr,
479
+ $(
480
+ {
481
+ input: $input: expr,
482
+ expected: $expected: expr $( , ) ?
483
+ }
484
+ ) ,+ $( , ) ?
485
+ ) => {
486
+ $(
487
+ {
488
+ let bytes = $fun( $input) ;
489
+ assert_eq!( & $input. to_be_bytes( ) [ 4 - bytes..] , & $expected[ ..] ) ;
490
+ }
491
+ ) +
492
+ }
493
+ }
494
+
495
+ #[ test]
496
+ fn integer_shrinking_unsigned ( ) {
497
+ int_test ! {
498
+ func: bytes_to_occupy_uint,
499
+ {
500
+ input: 0u32 ,
501
+ expected: [ 0 ] ,
502
+ } ,
503
+ {
504
+ input: 1u32 ,
505
+ expected: [ 1 ] ,
506
+ } ,
507
+ {
508
+ input: 32767u32 ,
509
+ expected: [ 127 , 255 ] ,
510
+ } ,
511
+ {
512
+ input: 65535u32 ,
513
+ expected: [ 255 , 255 ] ,
514
+ } ,
515
+ {
516
+ input: 8_388_607_u32 ,
517
+ expected: [ 0 , 127 , 255 , 255 ] ,
518
+ } ,
519
+ {
520
+ input: 16_777_215_u32 ,
521
+ expected: [ 0 , 255 , 255 , 255 ] ,
522
+ } ,
523
+ {
524
+ input: u32 :: MAX ,
525
+ expected: [ 255 , 255 , 255 , 255 ] ,
526
+ } ,
527
+ }
528
+ }
529
+ }
0 commit comments