@@ -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 ;
@@ -5652,6 +5655,7 @@ fn read_video_sample_entry<T: Read>(
56525655 let mut codec_specific = None ;
56535656 let mut pixel_aspect_ratio = None ;
56545657 let mut colour_info = None ;
5658+ let mut colr_types_seen = TryVec :: < FourCC > :: new ( ) ;
56555659 let mut hdr_mastering_display = None ;
56565660 let mut hdr_content_light_level = None ;
56575661 let mut protection_info = TryVec :: new ( ) ;
@@ -5771,22 +5775,32 @@ fn read_video_sample_entry<T: Read>(
57715775 debug ! ( "Parsed pasp box: {pasp:?}, PAR {pixel_aspect_ratio:?}" ) ;
57725776 }
57735777 BoxType :: ColourInformationBox => {
5774- if colour_info. is_some ( ) {
5775- // ISO/IEC 14496-12:2015 § 12.1.5.1 permits one or more colr boxes
5776- // in a VisualSampleEntry and assigns them no normative behaviour;
5777- // a reader may keep the first (most accurate) and ignore the rest.
5778- // Only reject under Strict.
5779- warn ! ( "Multiple colr boxes in video sample entry, keeping first" ) ;
5778+ // ISO/IEC 14496-12:2015 § 12.1.5.1 permits one or more colr boxes
5779+ // in a VisualSampleEntry (at most one for a given colour_type) and
5780+ // assigns them no normative behaviour; a reader may keep the first
5781+ // (most accurate) and ignore the rest. Only reject a repeated
5782+ // colour_type, and only under Strict.
5783+ let colour_type = FourCC :: from ( be_u32 ( & mut b) ?. to_be_bytes ( ) ) ;
5784+ if colr_types_seen. contains ( & colour_type) {
5785+ warn ! (
5786+ "Multiple {colour_type:?} colr boxes in video sample entry, keeping first"
5787+ ) ;
57805788 fail_with_status_if (
57815789 strictness == ParseStrictness :: Strict ,
57825790 Status :: ColrBadQuantityBMFF ,
57835791 ) ?;
5784- skip_box_content ( & mut b) ?;
5785- } else if let ParsedColourInformation :: Supported ( colr) =
5786- read_colr ( & mut b, strictness) ?
5787- {
5788- debug ! ( "Parsed colr box: {colr:?}" ) ;
5789- colour_info = Some ( colr) ;
5792+ skip_box_remain ( & mut b) ?;
5793+ } else {
5794+ colr_types_seen. push ( colour_type. clone ( ) ) ?;
5795+ if colour_info. is_some ( ) {
5796+ debug ! ( "Already have colour info, skipping {colour_type:?} colr box" ) ;
5797+ skip_box_remain ( & mut b) ?;
5798+ } else if let ParsedColourInformation :: Supported ( colr) =
5799+ read_colr ( & mut b, colour_type. value , strictness) ?
5800+ {
5801+ debug ! ( "Parsed colr box: {colr:?}" ) ;
5802+ colour_info = Some ( colr) ;
5803+ }
57905804 }
57915805 }
57925806 BoxType :: MasteringDisplayColourVolumeBox => {
0 commit comments