Avifinfo

Parser::parse_iref()privateWP 1.0

Parses an "iref" box.

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.

Метод класса: Parser{}

Хуков нет.

Возвращает

Status. FOUND on success or an error on failure.

Использование

// private - только в коде основоного (родительского) класса
$result = $this->parse_iref( $num_remaining_bytes );
$num_remaining_bytes(int) (обязательный)
The number of bytes that should be available from the resource.

Код Parser::parse_iref() WP 6.6.2

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;
}