Avifinfo

Box::parse()publicWP 1.0

Reads the box header.

Method of the class: Box{}

No Hooks.

Return

Status. FOUND on success or an error on failure.

Usage

$Box = new Box();
$Box->parse( $handle, $num_parsed_boxes, $num_remaining_bytes );
$handle(stream) (required)
The resource the header will be parsed from.
$num_parsed_boxes(int) (required) (passed by reference — &)
The total number of parsed boxes. Prevents timeouts.
$num_remaining_bytes(int)
The number of bytes that should be available from the resource.
Default: MAX_SIZE

Box::parse() code WP 6.6.2

public function parse( $handle, &$num_parsed_boxes, $num_remaining_bytes = MAX_SIZE ) {
  // See ISO/IEC 14496-12:2012(E) 4.2
  $header_size = 8; // box 32b size + 32b type (at least)
  if ( $header_size > $num_remaining_bytes ) {
    return INVALID;
  }
  if ( !( $data = read( $handle, 8 ) ) ) {
    return TRUNCATED;
  }
  $this->size = read_big_endian( $data, 4 );
  $this->type = substr( $data, 4, 4 );
  // 'box->size==1' means 64-bit size should be read after the box type.
  // 'box->size==0' means this box extends to all remaining bytes.
  if ( $this->size == 1 ) {
    $header_size += 8;
    if ( $header_size > $num_remaining_bytes ) {
      return INVALID;
    }
    if ( !( $data = read( $handle, 8 ) ) ) {
      return TRUNCATED;
    }
    // Stop the parsing if any box has a size greater than 4GB.
    if ( read_big_endian( $data, 4 ) != 0 ) {
      return ABORTED;
    }
    // Read the 32 least-significant bits.
    $this->size = read_big_endian( substr( $data, 4, 4 ), 4 );
  } else if ( $this->size == 0 ) {
    $this->size = $num_remaining_bytes;
  }
  if ( $this->size < $header_size ) {
    return INVALID;
  }
  if ( $this->size > $num_remaining_bytes ) {
    return INVALID;
  }

  $has_fullbox_header = $this->type == 'meta' || $this->type == 'pitm' ||
                        $this->type == 'ipma' || $this->type == 'ispe' ||
                        $this->type == 'pixi' || $this->type == 'iref' ||
                        $this->type == 'auxC';
  if ( $has_fullbox_header ) {
    $header_size += 4;
  }
  if ( $this->size < $header_size ) {
    return INVALID;
  }
  $this->content_size = $this->size - $header_size;
  // Avoid timeouts. The maximum number of parsed boxes is arbitrary.
  ++$num_parsed_boxes;
  if ( $num_parsed_boxes >= MAX_NUM_BOXES ) {
    return ABORTED;
  }

  $this->version = 0;
  $this->flags   = 0;
  if ( $has_fullbox_header ) {
    if ( !( $data = read( $handle, 4 ) ) ) {
      return TRUNCATED;
    }
    $this->version = read_big_endian( $data, 1 );
    $this->flags   = read_big_endian( substr( $data, 1, 3 ), 3 );
    // See AV1 Image File Format (AVIF) 8.1
    // at https://aomediacodec.github.io/av1-avif/#avif-boxes (available when
    // https://github.com/AOMediaCodec/av1-avif/pull/170 is merged).
    $is_parsable = ( $this->type == 'meta' && $this->version <= 0 ) ||
                   ( $this->type == 'pitm' && $this->version <= 1 ) ||
                   ( $this->type == 'ipma' && $this->version <= 1 ) ||
                   ( $this->type == 'ispe' && $this->version <= 0 ) ||
                   ( $this->type == 'pixi' && $this->version <= 0 ) ||
                   ( $this->type == 'iref' && $this->version <= 1 ) ||
                   ( $this->type == 'auxC' && $this->version <= 0 );
    // Instead of considering this file as invalid, skip unparsable boxes.
    if ( !$is_parsable ) {
      $this->type = 'unknownversion';
    }
  }
  // print_r( $this ); // Uncomment to print all boxes.
  return FOUND;
}