Parser::parse_iref( int $num_remaining_bytes ): AvifinfoStatus

In this article

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

Parses an “iref” box.

Description

The "dimg" boxes contain links between tiles and their parent items, which can be used to infer bit depth and number of channels for the primary item when the latter does not have these properties.

Parameters

$handleAvifinfostreamrequired
The resource the box will be parsed from.
$num_remaining_bytesintrequired
The number of bytes that should be available from the resource.

Return

AvifinfoStatus FOUND on success or an error on failure.

Source

private function parse_iref( $num_remaining_bytes ) {
  do {
    $box    = new Box();
    $status = $box->parse( $this->handle, $this->num_parsed_boxes, $num_remaining_bytes );
    if ( $status != FOUND ) {
      return $status;
    }

    if ( $box->type == 'dimg' ) {
      // See ISO/IEC 14496-12:2015(E) 8.11.12.2
      $num_bytes_per_id = ( $box->version == 0 ) ? 2 : 4;
      $num_read_bytes   = $num_bytes_per_id + 2;
      if ( $box->content_size < $num_read_bytes ) {
        return INVALID;
      }
      if ( !( $data = read( $this->handle, $num_read_bytes ) ) ) {
        return TRUNCATED;
      }
      $from_item_id    = read_big_endian( $data, $num_bytes_per_id );
      $reference_count = read_big_endian( substr( $data, $num_bytes_per_id, 2 ), 2 );

      for ( $i = 0; $i < $reference_count; ++$i ) {
        if ( $i >= MAX_TILES ) {
          $this->data_was_skipped = true;
          break;
        }
        $num_read_bytes += $num_bytes_per_id;
        if ( $box->content_size < $num_read_bytes ) {
          return INVALID;
        }
        if ( !( $data = read( $this->handle, $num_bytes_per_id ) ) ) {
          return TRUNCATED;
        }
        $to_item_id = read_big_endian( $data, $num_bytes_per_id );
        $tile_count = count( $this->features->tiles );
        if ( $from_item_id <= MAX_VALUE && $to_item_id <= MAX_VALUE &&
             $tile_count < MAX_TILES ) {
          $this->features->tiles[$tile_count]                 = new Tile();
          $this->features->tiles[$tile_count]->tile_item_id   = $to_item_id;
          $this->features->tiles[$tile_count]->parent_item_id = $from_item_id;
        } else {
          $this->data_was_skipped = true;
        }
      }

      // If all features are available now, do not look further.
      $status = $this->features->get_primary_item_features();
      if ( $status != NOT_FOUND ) {
        return $status;
      }

      // Mostly if 'data_was_skipped'.
      if ( !skip( $this->handle, $box->content_size - $num_read_bytes ) ) {
        return TRUNCATED;
      }
    } else {
      if ( !skip( $this->handle, $box->content_size ) ) {
        return TRUNCATED;
      }
    }
    $num_remaining_bytes -= $box->size;
  } while ( $num_remaining_bytes > 0 );
  return NOT_FOUND;
}

User Contributed Notes

You must log in before being able to contribute a note or feedback.