<?php
/**
 * Copyright (c) 2021, Alliance for Open Media. All rights reserved
 *
 * This source code is subject to the terms of the BSD 2 Clause License and
 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
 * was not distributed with this source code in the LICENSE file, you can
 * obtain it at www.aomedia.org/license/software. If the Alliance for Open
 * Media Patent License 1.0 was not distributed with this source code in the
 * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
 */

namespace Avifinfo;

const FOUND     = 0; // Input correctly parsed and information retrieved.
const NOT_FOUND = 1; // Input correctly parsed but information is missing or elsewhere.
const TRUNCATED = 2; // Input correctly parsed until missing bytes to continue.
const ABORTED   = 3; // Input correctly parsed until stopped to avoid timeout or crash.
const INVALID   = 4; // Input incorrectly parsed.

const MAX_SIZE      = 4294967295; // Unlikely to be insufficient to parse AVIF headers.
const MAX_NUM_BOXES = 4096;       // Be reasonable. Avoid timeouts and out-of-memory.
const MAX_VALUE     = 255;
const MAX_TILES     = 16;
const MAX_PROPS     = 32;
const MAX_FEATURES  = 8;
const UNDEFINED     = 0;          // Value was not yet parsed.

/**
 * Reads an unsigned integer with most significant bits first.
 *
 * @param binary string $input     Must be at least $num_bytes-long.
 * @param int           $num_bytes Number of parsed bytes.
 * @return int                     Value.
 */
function read_big_endian( $input, $num_bytes ) {
  if ( $num_bytes == 1 ) {
    return unpack( 'C', $input ) [1];
  } else if ( $num_bytes == 2 ) {
    return unpack( 'n', $input ) [1];
  } else if ( $num_bytes == 3 ) {
    $bytes = unpack( 'C3', $input );
    return ( $bytes[1] << 16 ) | ( $bytes[2] << 8 ) | $bytes[3];
  } else { // $num_bytes is 4
    // This might fail to read unsigned values >= 2^31 on 32-bit systems.
    // See https://www.php.net/manual/en/function.unpack.php#106041
    return unpack( 'N', $input ) [1];
  }
}

/**
 * Reads bytes and advances the stream position by the same count.
 *
 * @param stream               $handle    Bytes will be read from this resource.
 * @param int                  $num_bytes Number of bytes read. Must be greater than 0.
 * @return binary string|false            The raw bytes or false on failure.
 */
function read( $handle, $num_bytes ) {
  $data = fread( $handle, $num_bytes );
  return ( $data !== false && strlen( $data ) >= $num_bytes ) ? $data : false;
}

/**
 * Advances the stream position by the given offset.
 *
 * @param stream $handle    Bytes will be skipped from this resource.
 * @param int    $num_bytes Number of skipped bytes. Can be 0.
 * @return bool             True on success or false on failure.
 */
// Skips 'num_bytes' from the 'stream'. 'num_bytes' can be zero.
function skip( $handle, $num_bytes ) {
  return ( fseek( $handle, $num_bytes, SEEK_CUR ) == 0 );
}

//------------------------------------------------------------------------------
// Features are parsed into temporary property associations.

class Tile { // Tile item id <-> parent item id associations.
  public $tile_item_id;
  public $parent_item_id;
}

class Prop { // Property index <-> item id associations.
  public $property_index;
  public $item_id;
}

class Dim_Prop { // Property <-> features associations.
  public $property_index;
  public $width;
  public $height;
}

class Chan_Prop { // Property <-> features associations.
  public $property_index;
  public $bit_depth;
  public $num_channels;
}

class Features {
  public $has_primary_item = false; // True if "pitm" was parsed.
  public $has_alpha = false; // True if an alpha "auxC" was parsed.
  public $primary_item_id;
  public $primary_item_features = array( // Deduced from the data below.
    'width'        => UNDEFINED, // In number of pixels.
    'height'       => UNDEFINED, // Ignores mirror and rotation.
    'bit_depth'    => UNDEFINED, // Likely 8, 10 or 12 bits per channel per pixel.
    'num_channels' => UNDEFINED  // Likely 1, 2, 3 or 4 channels:
                                          //   (1 monochrome or 3 colors) + (0 or 1 alpha)
  );

  public $tiles = array(); // Tile[]
  public $props = array(); // Prop[]
  public $dim_props = array(); // Dim_Prop[]
  public $chan_props = array(); // Chan_Prop[]

  /**
   * Binds the width, height, bit depth and number of channels from stored internal features.
   *
   * @param int     $target_item_id Id of the item whose features will be bound.
   * @param int     $tile_depth     Maximum recursion to search within tile-parent relations.
   * @return Status                 FOUND on success or NOT_FOUND on failure.
   */
  private function get_item_features( $target_item_id, $tile_depth ) {
    foreach ( $this->props as $prop ) {
      if ( $prop->item_id != $target_item_id ) {
        continue;
      }

      // Retrieve the width and height of the primary item if not already done.
      if ( $target_item_id == $this->primary_item_id &&
           ( $this->primary_item_features['width'] == UNDEFINED ||
             $this->primary_item_features['height'] == UNDEFINED ) ) {
        foreach ( $this->dim_props as $dim_prop ) {
          if ( $dim_prop->property_index != $prop->property_index ) {
            continue;
          }
          $this->primary_item_features['width']  = $dim_prop->width;
          $this->primary_item_features['height'] = $dim_prop->height;
          if ( $this->primary_item_features['bit_depth'] != UNDEFINED &&
               $this->primary_item_features['num_channels'] != UNDEFINED ) {
            return FOUND;
          }
          break;
        }
      }
      // Retrieve the bit depth and number of channels of the target item if not
      // already done.
      if ( $this->primary_item_features['bit_depth'] == UNDEFINED ||
           $this->primary_item_features['num_channels'] == UNDEFINED ) {
        foreach ( $this->chan_props as $chan_prop ) {
          if ( $chan_prop->property_index != $prop->property_index ) {
            continue;
          }
          $this->primary_item_features['bit_depth']    = $chan_prop->bit_depth;
          $this->primary_item_features['num_channels'] = $chan_prop->num_channels;
          if ( $this->primary_item_features['width'] != UNDEFINED &&
              $this->primary_item_features['height'] != UNDEFINED ) {
            return FOUND;
          }
          break;
        }
      }
    }

    // Check for the bit_depth and num_channels in a tile if not yet found.
    if ( $tile_depth < 3 ) {
      foreach ( $this->tiles as $tile ) {
        if ( $tile->parent_item_id != $target_item_id ) {
          continue;
        }
        $status = get_item_features( $tile->tile_item_id, $tile_depth + 1 );
        if ( $status != NOT_FOUND ) {
          return $status;
        }
      }
    }
    return NOT_FOUND;
  }

  /**
   * Finds the width, height, bit depth and number of channels of the primary item.
   *
   * @return Status FOUND on success or NOT_FOUND on failure.
   */
  public function get_primary_item_features() {
    // Nothing to do without the primary item ID.
    if ( !$this->has_primary_item ) {
      return NOT_FOUND;
    }
    // Early exit.
    if ( empty( $this->dim_props ) || empty( $this->chan_props ) ) {
      return NOT_FOUND;
    }
    $status = $this->get_item_features( $this->primary_item_id, /*tile_depth=*/ 0 );
    if ( $status != FOUND ) {
      return $status;
    }

    // "auxC" is parsed before the "ipma" properties so it is known now, if any.
    if ( $this->has_alpha ) {
      ++$this->primary_item_features['num_channels'];
    }
    return FOUND;
  }
}

//------------------------------------------------------------------------------

class Box {
  public $size; // In bytes.
  public $type; // Four characters.
  public $version; // 0 or actual version if this is a full box.
  public $flags; // 0 or actual value if this is a full box.
  public $content_size; // 'size' minus the header size.

  /**
   * Reads the box header.
   *
   * @param stream  $handle              The resource the header will be parsed from.
   * @param int     $num_parsed_boxes    The total number of parsed boxes. Prevents timeouts.
   * @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.
   */
  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;
  }
}

//------------------------------------------------------------------------------

class Parser {
  private $handle; // Input stream.
  private $num_parsed_boxes = 0;
  private $data_was_skipped = false;
  public $features;

  function __construct( $handle ) {
    $this->handle   = $handle;
    $this->features = new Features();
  }

  /**
   * Parses an "ipco" box.
   *
   * "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";
        $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;
        }
      }
      ++$box_index;
      $num_remaining_bytes -= $box->size;
    } while ( $num_remaining_bytes > 0 );
    return NOT_FOUND;
  }

  /**
   * Parses an "iprp" box.
   *
   * The "ipco" box contain the properties which are linked to items by the "ipma" box.
   *
   * @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_iprp( $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 == 'ipco' ) {
        $status = $this->parse_ipco( $box->content_size );
        if ( $status != NOT_FOUND ) {
          return $status;
        }
      } else if ( $box->type == 'ipma' ) {
        // See ISO/IEC 23008-12:2017(E) 9.3.2
        $num_read_bytes = 4;
        if ( $box->content_size < $num_read_bytes ) {
          return INVALID;
        }
        if ( !( $data = read( $this->handle, $num_read_bytes ) ) ) {
          return TRUNCATED;
        }
        $entry_count        = read_big_endian( $data, 4 );
        $id_num_bytes       = ( $box->version < 1 ) ? 2 : 4;
        $index_num_bytes    = ( $box->flags & 1 ) ? 2 : 1;
        $essential_bit_mask = ( $box->flags & 1 ) ? 0x8000 : 0x80;

        for ( $entry = 0; $entry < $entry_count; ++$entry ) {
          if ( $entry >= MAX_PROPS ||
               count( $this->features->props ) >= MAX_PROPS ) {
            $this->data_was_skipped = true;
            break;
          }
          $num_read_bytes += $id_num_bytes + 1;
          if ( $box->content_size < $num_read_bytes ) {
            return INVALID;
          }
          if ( !( $data = read( $this->handle, $id_num_bytes + 1 ) ) ) {
            return TRUNCATED;
          }
          $item_id           = read_big_endian(
              substr( $data, 0, $id_num_bytes ), $id_num_bytes );
          $association_count = read_big_endian(
              substr( $data, $id_num_bytes, 1 ), 1 );

          for ( $property = 0; $property < $association_count; ++$property ) {
            if ( $property >= MAX_PROPS ||
                 count( $this->features->props ) >= MAX_PROPS ) {
              $this->data_was_skipped = true;
              break;
            }
            $num_read_bytes += $index_num_bytes;
            if ( $box->content_size < $num_read_bytes ) {
              return INVALID;
            }
            if ( !( $data = read( $this->handle, $index_num_bytes ) ) ) {
              return TRUNCATED;
            }
            $value          = read_big_endian( $data, $index_num_bytes );
            // $essential = ($value & $essential_bit_mask);  // Unused.
            $property_index = ( $value & ~$essential_bit_mask );
            if ( $property_index <= MAX_VALUE && $item_id <= MAX_VALUE ) {
              $prop_count = count( $this->features->props );
              $this->features->props[$prop_count]                 = new Prop();
              $this->features->props[$prop_count]->property_index = $property_index;
              $this->features->props[$prop_count]->item_id        = $item_id;
            } else {
              $this->data_was_skipped = true;
            }
          }
          if ( $property < $association_count ) {
            break; // Do not read garbage.
          }
        }

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

  /**
   * 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.
   *
   * @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_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;
  }

  /**
   * Parses a "meta" box.
   *
   * It looks for the primary item ID in the "pitm" box and recurses into other boxes
   * to find its features.
   *
   * @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_meta( $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 == 'pitm' ) {
        // See ISO/IEC 14496-12:2015(E) 8.11.4.2
        $num_bytes_per_id = ( $box->version == 0 ) ? 2 : 4;
        if ( $num_bytes_per_id > $num_remaining_bytes ) {
          return INVALID;
        }
        if ( !( $data = read( $this->handle, $num_bytes_per_id ) ) ) {
          return TRUNCATED;
        }
        $primary_item_id = read_big_endian( $data, $num_bytes_per_id );
        if ( $primary_item_id > MAX_VALUE ) {
          return ABORTED;
        }
        $this->features->has_primary_item = true;
        $this->features->primary_item_id  = $primary_item_id;
        if ( !skip( $this->handle, $box->content_size - $num_bytes_per_id ) ) {
          return TRUNCATED;
        }
      } else if ( $box->type == 'iprp' ) {
        $status = $this->parse_iprp( $box->content_size );
        if ( $status != NOT_FOUND ) {
          return $status;
        }
      } else if ( $box->type == 'iref' ) {
        $status = $this->parse_iref( $box->content_size );
        if ( $status != NOT_FOUND ) {
          return $status;
        }
      } else {
        if ( !skip( $this->handle, $box->content_size ) ) {
          return TRUNCATED;
        }
      }
      $num_remaining_bytes -= $box->size;
    } while ( $num_remaining_bytes != 0 );
    // According to ISO/IEC 14496-12:2012(E) 8.11.1.1 there is at most one "meta".
    return INVALID;
  }

  /**
   * Parses a file stream.
   *
   * The file type is checked through the "ftyp" box.
   *
   * @return bool True if the input stream is an AVIF bitstream or false.
   */
  public function parse_ftyp() {
    $box    = new Box();
    $status = $box->parse( $this->handle, $this->num_parsed_boxes );
    if ( $status != FOUND ) {
      return false;
    }

    if ( $box->type != 'ftyp' ) {
      return false;
    }
    // Iterate over brands. See ISO/IEC 14496-12:2012(E) 4.3.1
    if ( $box->content_size < 8 ) {
      return false;
    }
    for ( $i = 0; $i + 4 <= $box->content_size; $i += 4 ) {
      if ( !( $data = read( $this->handle, 4 ) ) ) {
        return false;
      }
      if ( $i == 4 ) {
        continue; // Skip minor_version.
      }
      if ( substr( $data, 0, 4 ) == 'avif' || substr( $data, 0, 4 ) == 'avis' ) {
        return skip( $this->handle, $box->content_size - ( $i + 4 ) );
      }
      if ( $i > 32 * 4 ) {
        return false; // Be reasonable.
      }

    }
    return false; // No AVIF brand no good.
  }

  /**
   * Parses a file stream.
   *
   * Features are extracted from the "meta" box.
   *
   * @return bool True if the main features of the primary item were parsed or false.
   */
  public function parse_file() {
    $box = new Box();
    while ( $box->parse( $this->handle, $this->num_parsed_boxes ) == FOUND ) {
      if ( $box->type === 'meta' ) {
        if ( $this->parse_meta( $box->content_size ) != FOUND ) {
          return false;
        }
        return true;
      }
      if ( !skip( $this->handle, $box->content_size ) ) {
        return false;
      }
    }
    return false; // No "meta" no good.
  }
}
