Title: Parser::parse_ipco
Published: April 3, 2024
Last modified: April 28, 2025

---

# Parser::parse_ipco( int $num_remaining_bytes ): AvifinfoStatus

## In this article

 * [Description](https://developer.wordpress.org/reference/classes/avifinfo-parser/parse_ipco/?output_format=md#description)
 * [Parameters](https://developer.wordpress.org/reference/classes/avifinfo-parser/parse_ipco/?output_format=md#parameters)
 * [Return](https://developer.wordpress.org/reference/classes/avifinfo-parser/parse_ipco/?output_format=md#return)
 * [Source](https://developer.wordpress.org/reference/classes/avifinfo-parser/parse_ipco/?output_format=md#source)

[ Back to top](https://developer.wordpress.org/reference/classes/avifinfo-parser/parse_ipco/?output_format=md#wp--skip-link--target)

This function’s access is marked private. This means it is not intended for use 
by plugin or theme developers, only by core. It is listed here for completeness.

Parses an “ipco” box.

## 󠀁[Description](https://developer.wordpress.org/reference/classes/avifinfo-parser/parse_ipco/?output_format=md#description)󠁿

"ispe" is used for width and height, "pixi" and "av1C" are used for bit depth and
number of channels, and "auxC" is used for alpha.

## 󠀁[Parameters](https://developer.wordpress.org/reference/classes/avifinfo-parser/parse_ipco/?output_format=md#parameters)󠁿

 `$handle`Avifinfostreamrequired

The resource the box will be parsed from.

`$num_remaining_bytes`intrequired

The number of bytes that should be available from the resource.

## 󠀁[Return](https://developer.wordpress.org/reference/classes/avifinfo-parser/parse_ipco/?output_format=md#return)󠁿

 AvifinfoStatus FOUND on success or an error on failure.

## 󠀁[Source](https://developer.wordpress.org/reference/classes/avifinfo-parser/parse_ipco/?output_format=md#source)󠁿

    ```php
     * "ispe" is used for width and height, "pixi" and "av1C" are used for bit depth
     * and number of channels, and "auxC" is used for alpha.
     *
     * @param stream  $handle              The resource the box will be parsed from.
     * @param int     $num_remaining_bytes The number of bytes that should be available from the resource.
     * @return Status                      FOUND on success or an error on failure.
     */
    private function parse_ipco( $num_remaining_bytes ) {
      $box_index = 1; // 1-based index. Used for iterating over properties.
      do {
        $box    = new Box();
        $status = $box->parse( $this->handle, $this->num_parsed_boxes, $num_remaining_bytes );
        if ( $status != FOUND ) {
          return $status;
        }

        if ( $box->type == 'ispe' ) {
          // See ISO/IEC 23008-12:2017(E) 6.5.3.2
          if ( $box->content_size < 8 ) {
            return INVALID;
          }
          if ( !( $data = read( $this->handle, 8 ) ) ) {
            return TRUNCATED;
          }
          $width  = read_big_endian( substr( $data, 0, 4 ), 4 );
          $height = read_big_endian( substr( $data, 4, 4 ), 4 );
          if ( $width == 0 || $height == 0 ) {
            return INVALID;
          }
          if ( count( $this->features->dim_props ) <= MAX_FEATURES &&
               $box_index <= MAX_VALUE ) {
            $dim_prop_count = count( $this->features->dim_props );
            $this->features->dim_props[$dim_prop_count]                 = new Dim_Prop();
            $this->features->dim_props[$dim_prop_count]->property_index = $box_index;
            $this->features->dim_props[$dim_prop_count]->width          = $width;
            $this->features->dim_props[$dim_prop_count]->height         = $height;
          } else {
            $this->data_was_skipped = true;
          }
          if ( !skip( $this->handle, $box->content_size - 8 ) ) {
            return TRUNCATED;
          }
        } else if ( $box->type == 'pixi' ) {
          // See ISO/IEC 23008-12:2017(E) 6.5.6.2
          if ( $box->content_size < 1 ) {
            return INVALID;
          }
          if ( !( $data = read( $this->handle, 1 ) ) ) {
            return TRUNCATED;
          }
          $num_channels = read_big_endian( $data, 1 );
          if ( $num_channels < 1 ) {
            return INVALID;
          }
          if ( $box->content_size < 1 + $num_channels ) {
            return INVALID;
          }
          if ( !( $data = read( $this->handle, 1 ) ) ) {
            return TRUNCATED;
          }
          $bit_depth = read_big_endian( $data, 1 );
          if ( $bit_depth < 1 ) {
            return INVALID;
          }
          for ( $i = 1; $i < $num_channels; ++$i ) {
            if ( !( $data = read( $this->handle, 1 ) ) ) {
              return TRUNCATED;
            }
            // Bit depth should be the same for all channels.
            if ( read_big_endian( $data, 1 ) != $bit_depth ) {
              return INVALID;
            }
            if ( $i > 32 ) {
              return ABORTED; // Be reasonable.
            }
          }
          if ( count( $this->features->chan_props ) <= MAX_FEATURES &&
               $box_index <= MAX_VALUE && $bit_depth <= MAX_VALUE &&
               $num_channels <= MAX_VALUE ) {
            $chan_prop_count = count( $this->features->chan_props );
            $this->features->chan_props[$chan_prop_count]                 = new Chan_Prop();
            $this->features->chan_props[$chan_prop_count]->property_index = $box_index;
            $this->features->chan_props[$chan_prop_count]->bit_depth      = $bit_depth;
            $this->features->chan_props[$chan_prop_count]->num_channels   = $num_channels;
          } else {
            $this->data_was_skipped = true;
          }
          if ( !skip( $this->handle, $box->content_size - ( 1 + $num_channels ) ) ) {
            return TRUNCATED;
          }
        } else if ( $box->type == 'av1C' ) {
          // See AV1 Codec ISO Media File Format Binding 2.3.1
          // at https://aomediacodec.github.io/av1-isobmff/#av1c
          // Only parse the necessary third byte. Assume that the others are valid.
          if ( $box->content_size < 3 ) {
            return INVALID;
          }
          if ( !( $data = read( $this->handle, 3 ) ) ) {
            return TRUNCATED;
          }
          $byte          = read_big_endian( substr( $data, 2, 1 ), 1 );
          $high_bitdepth = ( $byte & 0x40 ) != 0;
          $twelve_bit    = ( $byte & 0x20 ) != 0;
          $monochrome    = ( $byte & 0x10 ) != 0;
          if ( $twelve_bit && !$high_bitdepth ) {
              return INVALID;
          }
          if ( count( $this->features->chan_props ) <= MAX_FEATURES &&
               $box_index <= MAX_VALUE ) {
            $chan_prop_count = count( $this->features->chan_props );
            $this->features->chan_props[$chan_prop_count]                 = new Chan_Prop();
            $this->features->chan_props[$chan_prop_count]->property_index = $box_index;
            $this->features->chan_props[$chan_prop_count]->bit_depth      =
                $high_bitdepth ? $twelve_bit ? 12 : 10 : 8;
            $this->features->chan_props[$chan_prop_count]->num_channels   = $monochrome ? 1 : 3;
          } else {
            $this->data_was_skipped = true;
          }
          if ( !skip( $this->handle, $box->content_size - 3 ) ) {
            return TRUNCATED;
          }
        } else if ( $box->type == 'auxC' ) {
          // See AV1 Image File Format (AVIF) 4
          // at https://aomediacodec.github.io/av1-avif/#auxiliary-images
          $kAlphaStr       = "urn:mpeg:mpegB:cicp:systems:auxiliary:alpha\0";
          $kAlphaStrLength = 44; // Includes terminating character.
          if ( $box->content_size >= $kAlphaStrLength ) {
            if ( !( $data = read( $this->handle, $kAlphaStrLength ) ) ) {
              return TRUNCATED;
            }
            if ( substr( $data, 0, $kAlphaStrLength ) == $kAlphaStr ) {
              // Note: It is unlikely but it is possible that this alpha plane does
              //       not belong to the primary item or a tile. Ignore this issue.
              $this->features->has_alpha = true;
            }
            if ( !skip( $this->handle, $box->content_size - $kAlphaStrLength ) ) {
              return TRUNCATED;
            }
          } else {
            if ( !skip( $this->handle, $box->content_size ) ) {
              return TRUNCATED;
            }
          }
        } else {
          if ( !skip( $this->handle, $box->content_size ) ) {
            return TRUNCATED;
    ```

[View all references](https://developer.wordpress.org/reference/files/wp-includes/class-avif-info.php/)
[View on Trac](https://core.trac.wordpress.org/browser/tags/7.0/src/wp-includes/class-avif-info.php#L336)
[View on GitHub](https://github.com/WordPress/wordpress-develop/blob/7.0/src/wp-includes/class-avif-info.php#L336-L481)

## User Contributed Notes

You must [log in](https://login.wordpress.org/?redirect_to=https%3A%2F%2Fdeveloper.wordpress.org%2Freference%2Fclasses%2Favifinfo-parser%2Fparse_ipco%2F)
before being able to contribute a note or feedback.