@@ -467,8 +467,8 @@ impl From<Status> for &str {
467467 per HEIF (ISO/IEC DIS 23008-12) § 6.5.5.1"
468468 }
469469 Status :: ColrBadQuantityBMFF => {
470- "Each sample entry shall have at most one ColourInformationBox (colr) \
471- per ISOBMFF (ISO 14496-12:2020) § 12.1.5"
470+ "Each sample entry should have at most one ColourInformationBox (colr) \
471+ for a given value of colour_type per ISOBMFF (ISO 14496-12:2020) § 12.1.5"
472472 }
473473 Status :: ColrBadSize => {
474474 "Unexpected size for colr box"
@@ -3636,13 +3636,16 @@ fn read_ipco<T: Read>(
36363636 let property = match b. head . name {
36373637 BoxType :: AuxiliaryTypeProperty => ItemProperty :: AuxiliaryType ( read_auxc ( & mut b) ?) ,
36383638 BoxType :: AV1CodecConfigurationBox => ItemProperty :: AV1Config ( read_av1c ( & mut b) ?) ,
3639- BoxType :: ColourInformationBox => match read_colr ( & mut b, strictness) ? {
3640- ParsedColourInformation :: Supported ( colr) => ItemProperty :: Colour ( colr) ,
3641- ParsedColourInformation :: Unsupported ( colour_type) => {
3642- error ! ( "read_colr colour_type: {colour_type:?}" ) ;
3643- return Status :: ColrBadType . into ( ) ;
3639+ BoxType :: ColourInformationBox => {
3640+ let colour_type = be_u32 ( & mut b) ?. to_be_bytes ( ) ;
3641+ match read_colr ( & mut b, colour_type, strictness) ? {
3642+ ParsedColourInformation :: Supported ( colr) => ItemProperty :: Colour ( colr) ,
3643+ ParsedColourInformation :: Unsupported ( colour_type) => {
3644+ error ! ( "read_colr colour_type: {colour_type:?}" ) ;
3645+ return Status :: ColrBadType . into ( ) ;
3646+ }
36443647 }
3645- } ,
3648+ }
36463649 BoxType :: ImageMirror => ItemProperty :: Mirroring ( read_imir ( & mut b) ?) ,
36473650 BoxType :: ImageRotation => ItemProperty :: Rotation ( read_irot ( & mut b) ?) ,
36483651 BoxType :: ImageSpatialExtentsProperty => {
@@ -3837,12 +3840,12 @@ enum ParsedColourInformation {
38373840
38383841/// Parse colour information
38393842/// See ISOBMFF (ISO 14496-12:2020) § 12.1.5
3843+ /// The caller is expected to have already read the colour_type field.
38403844fn read_colr < T : Read > (
38413845 src : & mut BMFFBox < T > ,
3846+ colour_type : [ u8 ; 4 ] ,
38423847 strictness : ParseStrictness ,
38433848) -> Result < ParsedColourInformation > {
3844- let colour_type = be_u32 ( src) ?. to_be_bytes ( ) ;
3845-
38463849 match & colour_type {
38473850 b"nclx" => {
38483851 const NUM_RESERVED_BITS : u8 = 7 ;
@@ -5683,6 +5686,7 @@ fn read_video_sample_entry<T: Read>(
56835686 let mut codec_specific = None ;
56845687 let mut pixel_aspect_ratio = None ;
56855688 let mut colour_info = None ;
5689+ let mut colr_types_seen = TryVec :: < FourCC > :: new ( ) ;
56865690 let mut hdr_mastering_display = None ;
56875691 let mut hdr_content_light_level = None ;
56885692 let mut protection_info = TryVec :: new ( ) ;
@@ -5802,22 +5806,32 @@ fn read_video_sample_entry<T: Read>(
58025806 debug ! ( "Parsed pasp box: {pasp:?}, PAR {pixel_aspect_ratio:?}" ) ;
58035807 }
58045808 BoxType :: ColourInformationBox => {
5805- if colour_info. is_some ( ) {
5806- // ISO/IEC 14496-12:2015 § 12.1.5.1 permits one or more colr boxes
5807- // in a VisualSampleEntry and assigns them no normative behaviour;
5808- // a reader may keep the first (most accurate) and ignore the rest.
5809- // Only reject under Strict.
5810- warn ! ( "Multiple colr boxes in video sample entry, keeping first" ) ;
5809+ // ISO/IEC 14496-12:2015 § 12.1.5.1 permits one or more colr boxes
5810+ // in a VisualSampleEntry (at most one for a given colour_type) and
5811+ // assigns them no normative behaviour; a reader may keep the first
5812+ // (most accurate) and ignore the rest. Only reject a repeated
5813+ // colour_type, and only under Strict.
5814+ let colour_type = FourCC :: from ( be_u32 ( & mut b) ?. to_be_bytes ( ) ) ;
5815+ if colr_types_seen. contains ( & colour_type) {
5816+ warn ! (
5817+ "Multiple {colour_type:?} colr boxes in video sample entry, keeping first"
5818+ ) ;
58115819 fail_with_status_if (
58125820 strictness == ParseStrictness :: Strict ,
58135821 Status :: ColrBadQuantityBMFF ,
58145822 ) ?;
5815- skip_box_content ( & mut b) ?;
5816- } else if let ParsedColourInformation :: Supported ( colr) =
5817- read_colr ( & mut b, strictness) ?
5818- {
5819- debug ! ( "Parsed colr box: {colr:?}" ) ;
5820- colour_info = Some ( colr) ;
5823+ skip_box_remain ( & mut b) ?;
5824+ } else {
5825+ colr_types_seen. push ( colour_type. clone ( ) ) ?;
5826+ if colour_info. is_some ( ) {
5827+ debug ! ( "Already have colour info, skipping {colour_type:?} colr box" ) ;
5828+ skip_box_remain ( & mut b) ?;
5829+ } else if let ParsedColourInformation :: Supported ( colr) =
5830+ read_colr ( & mut b, colour_type. value , strictness) ?
5831+ {
5832+ debug ! ( "Parsed colr box: {colr:?}" ) ;
5833+ colour_info = Some ( colr) ;
5834+ }
58215835 }
58225836 }
58235837 BoxType :: MasteringDisplayColourVolumeBox => {
0 commit comments