// 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.

#include "avifinfo.h"

#include <stdint.h>
#include <stdio.h>
#include <string.h>

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

// Status returned when reading the content of a box (or file).
typedef enum {
  kFound,     // Input correctly parsed and information retrieved.
  kNotFound,  // Input correctly parsed but information is missing or elsewhere.
  kTruncated,  // Input correctly parsed until missing bytes to continue.
  kAborted,  // Input correctly parsed until stopped to avoid timeout or crash.
  kInvalid,  // Input incorrectly parsed.
} AvifInfoInternalStatus;

// uint32_t is used everywhere in this file. It is unlikely to be insufficient
// to parse AVIF headers. Clamp any input to 2^32-1 for simplicity.
static const uint32_t kAvifInfoInternalMaxSize = UINT32_MAX;

// Reads an unsigned integer from 'input' with most significant bits first.
// 'input' must be at least 'num_bytes'-long.
static uint32_t AvifInfoInternalReadBigEndian(const uint8_t* input,
                                              uint32_t num_bytes) {
  uint32_t value = 0;
  for (uint32_t i = 0; i < num_bytes; ++i) {
    value = (value << 8) | input[i];
  }
  return value;
}

//------------------------------------------------------------------------------
// Convenience macros.

#if defined(AVIFINFO_LOG_ERROR)  // Toggle to log encountered issues.
static void AvifInfoInternalLogError(const char* file, int line,
                                     AvifInfoInternalStatus status) {
  const char* kStr[] = {"Found", "NotFound", "Truncated", "Invalid", "Aborted"};
  fprintf(stderr, "  %s:%d: %s\n", file, line, kStr[status]);
  // Set a breakpoint here to catch the first detected issue.
}
#define AVIFINFO_RETURN(check_status)                               \
  do {                                                              \
    const AvifInfoInternalStatus status_checked = (check_status);   \
    if (status_checked != kFound && status_checked != kNotFound) {  \
      AvifInfoInternalLogError(__FILE__, __LINE__, status_checked); \
    }                                                               \
    return status_checked;                                          \
  } while (0)
#else
#define AVIFINFO_RETURN(check_status) \
  do {                                \
    return (check_status);            \
  } while (0)
#endif

#define AVIFINFO_CHECK(check_condition, check_status)      \
  do {                                                     \
    if (!(check_condition)) AVIFINFO_RETURN(check_status); \
  } while (0)
#define AVIFINFO_CHECK_STATUS_IS(check_status, expected_status)            \
  do {                                                                     \
    const AvifInfoInternalStatus status_returned = (check_status);         \
    AVIFINFO_CHECK(status_returned == (expected_status), status_returned); \
  } while (0)
#define AVIFINFO_CHECK_FOUND(check_status) \
  AVIFINFO_CHECK_STATUS_IS((check_status), kFound)
#define AVIFINFO_CHECK_NOT_FOUND(check_status) \
  AVIFINFO_CHECK_STATUS_IS((check_status), kNotFound)

//------------------------------------------------------------------------------
// Box header parsing and various size checks.

typedef struct {
  uint32_t size;              // In bytes.
  const uint8_t* type;        // Points to four characters.
  uint32_t version;           // 0 or actual version if this is a full box.
  uint32_t flags;             // 0 or actual value if this is a full box.
  uint32_t content_size;      // 'size' minus the header size.
  uint32_t content_position;  // Position in bytes of the 'content' of this box
                              // relative to its container.
  const uint8_t* content;     // Content bytes of this box (after its header).
} AvifInfoInternalBox;

// Reads the header of a 'box' starting at 'bytes + position'.
// 'num_bytes' is the number of available 'bytes'.
// 'max_num_bytes' is the size of the container of the 'box' (either the file
// itself or the content of the parent of the 'box').
static AvifInfoInternalStatus AvifInfoInternalParseBox(
    const uint8_t* bytes, uint32_t num_bytes, uint32_t max_num_bytes,
    uint32_t position, uint32_t* num_parsed_boxes, AvifInfoInternalBox* box) {
  // See ISO/IEC 14496-12:2012(E) 4.2
  uint32_t box_header_size = 8;  // box 32b size + 32b type (at least)
  AVIFINFO_CHECK(position <= kAvifInfoInternalMaxSize - box_header_size,
                 kAborted);
  AVIFINFO_CHECK(position + box_header_size <= max_num_bytes, kInvalid);
  AVIFINFO_CHECK(position + box_header_size <= num_bytes, kTruncated);
  box->size = AvifInfoInternalReadBigEndian(bytes + position, sizeof(uint32_t));
  // '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 (box->size == 1) {
    box_header_size += 8;
    AVIFINFO_CHECK(position + box_header_size <= max_num_bytes, kInvalid);
    AVIFINFO_CHECK(position + box_header_size <= num_bytes, kTruncated);
    // Stop the parsing if any box has a size greater than 4GB.
    AVIFINFO_CHECK(AvifInfoInternalReadBigEndian(bytes + position + 8,
                                                 sizeof(uint32_t)) == 0,
                   kAborted);
    // Read the 32 least-significant bits.
    box->size =
        AvifInfoInternalReadBigEndian(bytes + position + 12, sizeof(uint32_t));
  } else if (box->size == 0) {
    box->size = max_num_bytes - position;
  }
  AVIFINFO_CHECK(box->size >= box_header_size, kInvalid);
  AVIFINFO_CHECK(box->size <= kAvifInfoInternalMaxSize - position, kAborted);
  AVIFINFO_CHECK(position + box->size <= max_num_bytes, kInvalid);
  AVIFINFO_CHECK(position + box_header_size <= num_bytes, kTruncated);
  box->type = bytes + position + 4;

  const int has_fullbox_header =
      !memcmp(box->type, "meta", 4) || !memcmp(box->type, "pitm", 4) ||
      !memcmp(box->type, "ipma", 4) || !memcmp(box->type, "ispe", 4) ||
      !memcmp(box->type, "pixi", 4) || !memcmp(box->type, "iref", 4) ||
      !memcmp(box->type, "auxC", 4);
  if (has_fullbox_header) box_header_size += 4;
  AVIFINFO_CHECK(box->size >= box_header_size, kInvalid);
  box->content_position = position + box_header_size;
  AVIFINFO_CHECK(box->content_position <= num_bytes, kTruncated);
  box->content_size = box->size - box_header_size;
  box->content = bytes + box->content_position;
  // Avoid timeouts. The maximum number of parsed boxes is arbitrary.
  ++*num_parsed_boxes;
  AVIFINFO_CHECK(*num_parsed_boxes < 4096, kAborted);

  box->version = 0;
  box->flags = 0;
  if (has_fullbox_header) {
    box->version = AvifInfoInternalReadBigEndian(bytes + position + 8, 1);
    box->flags = AvifInfoInternalReadBigEndian(bytes + position + 9, 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).
    uint32_t is_parsable = 1;
    if (!memcmp(box->type, "meta", 4)) is_parsable = (box->version <= 0);
    if (!memcmp(box->type, "pitm", 4)) is_parsable = (box->version <= 1);
    if (!memcmp(box->type, "ipma", 4)) is_parsable = (box->version <= 1);
    if (!memcmp(box->type, "ispe", 4)) is_parsable = (box->version <= 0);
    if (!memcmp(box->type, "pixi", 4)) is_parsable = (box->version <= 0);
    if (!memcmp(box->type, "iref", 4)) is_parsable = (box->version <= 1);
    if (!memcmp(box->type, "auxC", 4)) is_parsable = (box->version <= 0);
    // Instead of considering this file as invalid, skip unparsable boxes.
    if (!is_parsable) box->type = (const uint8_t*)"\0skip";
  }
  return kFound;
}

// Returns kFound if 'min_size' bytes can be read from the 'box.content' now.
// 'num_bytes' is the number of available bytes of the parent of the 'box'.
static AvifInfoInternalStatus AccessContent(const AvifInfoInternalBox* box,
                                            uint32_t num_bytes,
                                            uint32_t min_size) {
  AVIFINFO_CHECK(box->content_size >= min_size, kInvalid);
  AVIFINFO_CHECK(box->content_position + min_size <= num_bytes, kTruncated);
  return kFound;
}

//------------------------------------------------------------------------------
// Search if the file identifies itself as AVIF through an "ftyp" box.

static AvifInfoInternalStatus ParseFileForBrand(const uint8_t* bytes,
                                                uint32_t num_bytes,
                                                uint32_t file_size,
                                                uint32_t* num_parsed_boxes) {
  uint32_t position = 0;  // Within 'bytes' (that points to first byte of file).
  do {
    AvifInfoInternalBox box;
    AVIFINFO_CHECK_FOUND(AvifInfoInternalParseBox(
        bytes, num_bytes, file_size, position, num_parsed_boxes, &box));

    if (!memcmp(box.type, "ftyp", 4)) {
      // Iterate over brands. See ISO/IEC 14496-12:2012(E) 4.3.1
      AVIFINFO_CHECK(box.content_size >= 8, kInvalid);  // major_brand + version
      for (uint32_t i = 0; i < box.content_size; i += 4) {
        AVIFINFO_CHECK_FOUND(AccessContent(&box, num_bytes, i + 4));
        if (i == 4) continue;  // Skip minor_version.
        if (!memcmp(box.content + i, "avif", 4) ||
            !memcmp(box.content + i, "avis", 4)) {
          return kFound;
        }
      }
      AVIFINFO_RETURN(kInvalid);  // Only one "ftyp" allowed per file.
    }
    position += box.size;
    // File is valid only if the end of at least one box is at the same position
    // as the end of the container. Oddities are caught when parsing further.
  } while (position != file_size);
  AVIFINFO_RETURN(kInvalid);  // There should be one "ftyp" box.
}

//------------------------------------------------------------------------------
// Search the primary item ID through "meta > pitm" boxes.

static AvifInfoInternalStatus ParseMetaForPrimaryItemId(
    const uint8_t* bytes, uint32_t num_bytes, uint32_t max_num_bytes,
    uint32_t* num_parsed_boxes, uint32_t* primary_item_id) {
  uint32_t position = 0;  // Within 'bytes' (first byte of "meta" box content).
  do {
    AvifInfoInternalBox box;
    AVIFINFO_CHECK_FOUND(AvifInfoInternalParseBox(
        bytes, num_bytes, max_num_bytes, position, num_parsed_boxes, &box));

    if (!memcmp(box.type, "pitm", 4)) {
      // See ISO/IEC 14496-12:2015(E) 8.11.4.2
      const uint32_t num_bytes_per_id = (box.version == 0) ? 2 : 4;
      AVIFINFO_CHECK_FOUND(AccessContent(&box, num_bytes, num_bytes_per_id));
      *primary_item_id =
          AvifInfoInternalReadBigEndian(box.content + 0, num_bytes_per_id);
      return kFound;
    }
    position += box.size;
  } while (position != max_num_bytes);

  // According to ISO/IEC 14496-12:2012(E) 8.11.1.1, there is at most one "meta"
  // per file. No "pitm" until now means never.
  AVIFINFO_RETURN(kInvalid);
}

static AvifInfoInternalStatus ParseFileForPrimaryItemId(
    const uint8_t* bytes, uint32_t num_bytes, uint32_t file_size,
    uint32_t* num_parsed_boxes, uint32_t* primary_item_id) {
  uint32_t position = 0;  // Within 'bytes' (that points to first byte of file).
  do {
    AvifInfoInternalBox box;
    AVIFINFO_CHECK_FOUND(AvifInfoInternalParseBox(
        bytes, num_bytes, file_size, position, num_parsed_boxes, &box));

    if (!memcmp(box.type, "meta", 4)) {
      return ParseMetaForPrimaryItemId(
          box.content, num_bytes - box.content_position, box.content_size,
          num_parsed_boxes, primary_item_id);
    }
    position += box.size;
  } while (position != file_size);
  AVIFINFO_RETURN(kInvalid);  // No "meta" is an issue.
}

//------------------------------------------------------------------------------
// Search the features of an item given its ID through "meta > iprp" boxes.

static AvifInfoInternalStatus ParseIpcoForFeaturesInProperty(
    const uint8_t* bytes, uint32_t num_bytes, uint32_t max_num_bytes,
    uint32_t target_property_index, uint32_t* num_parsed_boxes,
    AvifInfoFeatures* features) {
  uint32_t position = 0;
  uint32_t box_index = 1;  // 1-based index. Used for iterating over properties.
  do {
    AvifInfoInternalBox box;
    AVIFINFO_CHECK_FOUND(AvifInfoInternalParseBox(
        bytes, num_bytes, max_num_bytes, position, num_parsed_boxes, &box));

    if (box_index != target_property_index) {
      // Skip.
    } else if (features->width == 0 && !memcmp(box.type, "ispe", 4)) {
      // See ISO/IEC 23008-12:2017(E) 6.5.3.2
      AVIFINFO_CHECK_FOUND(AccessContent(&box, num_bytes, 4 + 4));
      features->width = AvifInfoInternalReadBigEndian(box.content + 0, 4);
      features->height = AvifInfoInternalReadBigEndian(box.content + 4, 4);
      AVIFINFO_CHECK(features->width != 0 && features->height != 0, kInvalid);
      return kFound;
    } else if (features->num_channels == 0 && !memcmp(box.type, "pixi", 4)) {
      // See ISO/IEC 23008-12:2017(E) 6.5.6.2
      AVIFINFO_CHECK_FOUND(AccessContent(&box, num_bytes, 1));
      features->num_channels =
          AvifInfoInternalReadBigEndian(box.content + 0, 1);
      AVIFINFO_CHECK(features->num_channels >= 1, kInvalid);
      AVIFINFO_CHECK_FOUND(
          AccessContent(&box, num_bytes, 1 + features->num_channels));
      features->bit_depth = AvifInfoInternalReadBigEndian(box.content + 1, 1);
      AVIFINFO_CHECK(features->bit_depth >= 1, kInvalid);
      for (uint32_t i = 1; i < features->num_channels; ++i) {
        const uint32_t bit_depth =
            AvifInfoInternalReadBigEndian(box.content + 1 + i, 1);
        // Bit depth should be the same for all channels.
        AVIFINFO_CHECK(bit_depth == features->bit_depth, kInvalid);
      }
      return kFound;
    } else if (features->num_channels == 0 && !memcmp(box.type, "av1C", 4)) {
      // 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.
      AVIFINFO_CHECK_FOUND(AccessContent(&box, num_bytes, 3));
      const uint32_t fields = AvifInfoInternalReadBigEndian(box.content + 2, 1);
      const int high_bitdepth = (fields & 0x40) != 0;
      const int twelve_bit = (fields & 0x20) != 0;
      const int monochrome = (fields & 0x10) != 0;
      if (twelve_bit) {
        AVIFINFO_CHECK(high_bitdepth, kInvalid);
      }
      features->num_channels = monochrome ? 1 : 3;
      features->bit_depth = high_bitdepth ? twelve_bit ? 12 : 10 : 8;
      return kFound;
    }
    ++box_index;
    position += box.size;
  } while (position != max_num_bytes && box_index <= target_property_index);
  AVIFINFO_RETURN(kNotFound);
}

static AvifInfoInternalStatus ParseIprpForFeaturesInProperty(
    const uint8_t* bytes, uint32_t num_bytes, uint32_t max_num_bytes,
    uint32_t target_property_index, uint32_t* num_parsed_boxes,
    AvifInfoFeatures* features) {
  uint32_t position = 0;
  do {
    AvifInfoInternalBox box;
    AVIFINFO_CHECK_FOUND(AvifInfoInternalParseBox(
        bytes, num_bytes, max_num_bytes, position, num_parsed_boxes, &box));

    if (!memcmp(box.type, "ipco", 4)) {
      return ParseIpcoForFeaturesInProperty(
          box.content, num_bytes - box.content_position, box.content_size,
          target_property_index, num_parsed_boxes, features);
    }
    position += box.size;
  } while (position != max_num_bytes);
  AVIFINFO_RETURN(kInvalid);  // No "ipco" in "iprp" is an issue.
}

static AvifInfoInternalStatus ParseIprpForFeatures(const uint8_t* bytes,
                                                   uint32_t num_bytes,
                                                   uint32_t max_num_bytes,
                                                   uint32_t target_item_id,
                                                   uint32_t* num_parsed_boxes,
                                                   AvifInfoFeatures* features) {
  uint32_t position = 0;
  do {
    AvifInfoInternalBox box;
    AVIFINFO_CHECK_FOUND(AvifInfoInternalParseBox(
        bytes, num_bytes, max_num_bytes, position, num_parsed_boxes, &box));

    if (!memcmp(box.type, "ipma", 4)) {
      // See ISO/IEC 23008-12:2017(E) 9.3.2
      AVIFINFO_CHECK_FOUND(AccessContent(&box, num_bytes, 4));
      const uint32_t entry_count =
          AvifInfoInternalReadBigEndian(box.content + 0, 4);
      uint32_t offset = 4;
      const uint32_t id_num_bytes = (box.version < 1) ? 2 : 4;
      const uint32_t index_num_bytes = (box.flags & 1) ? 2 : 1;
      const uint32_t essential_bit_mask = (box.flags & 1) ? 0x8000 : 0x80;

      for (uint32_t entry = 0; entry < entry_count; ++entry) {
        AVIFINFO_CHECK_FOUND(
            AccessContent(&box, num_bytes, offset + id_num_bytes + 1));
        const uint32_t item_id =
            AvifInfoInternalReadBigEndian(box.content + offset, id_num_bytes);

        offset += id_num_bytes;
        const uint32_t association_count =
            AvifInfoInternalReadBigEndian(box.content + offset, 1);
        offset += 1;

        for (uint32_t property = 0; property < association_count; ++property) {
          AVIFINFO_CHECK_FOUND(
              AccessContent(&box, num_bytes, offset + index_num_bytes));
          const uint32_t value = AvifInfoInternalReadBigEndian(
              box.content + offset, index_num_bytes);
          offset += index_num_bytes;

          if (item_id == target_item_id) {
            // const int essential = (value & essential_bit_mask);  // Unused.
            const uint32_t property_index = (value & ~essential_bit_mask);

            // Parse again at the same "iprp" level to find the associated
            // "ipco" and the "ispe", "pixi" or "av1C" within.
            const AvifInfoInternalStatus status =
                ParseIprpForFeaturesInProperty(bytes, num_bytes, max_num_bytes,
                                               property_index, num_parsed_boxes,
                                               features);
            if (status != kFound) {
              // Stop in case of error, carry on if not found.
              AVIFINFO_CHECK_NOT_FOUND(status);
            } else if (features->width != 0 && features->height != 0 &&
                       features->num_channels != 0 &&
                       features->bit_depth != 0) {
              return kFound;  // Found everything. Otherwise carry on.
            }
          }
        }
      }

      // According to ISO/IEC 14496-12:2012(E) 8.11.1.1, there is at most one
      // "meta" per file. According to ISO/IEC 23008-12:2017(E) 9.3.1, there is
      // exactly one "ipma" per "iprp" and at most one "iprp" per "meta".
      // The primary properties shall have been found now.
      if (features->width != 0 && features->height != 0) {
        // Exception: The bit depth and number of channels may be referenced
        //            in a tile and not in the primary item of item type "grid".
        return kNotFound;  // Continue the search at a higher level.
      }
      AVIFINFO_RETURN(kInvalid);
    }
    position += box.size;
  } while (position != max_num_bytes);
  AVIFINFO_RETURN(kInvalid);  // No "ipma" in "iprp" is an issue.
}

static AvifInfoInternalStatus ParseMetaForFeatures(const uint8_t* bytes,
                                                   uint32_t num_bytes,
                                                   uint32_t max_num_bytes,
                                                   uint32_t target_item_id,
                                                   uint32_t* num_parsed_boxes,
                                                   AvifInfoFeatures* features) {
  uint32_t position = 0;
  do {
    AvifInfoInternalBox box;
    AVIFINFO_CHECK_FOUND(AvifInfoInternalParseBox(
        bytes, num_bytes, max_num_bytes, position, num_parsed_boxes, &box));

    if (!memcmp(box.type, "iprp", 4)) {
      return ParseIprpForFeatures(box.content, num_bytes - box.content_position,
                                  box.content_size, target_item_id,
                                  num_parsed_boxes, features);
    }
    position += box.size;
  } while (position != max_num_bytes);
  AVIFINFO_RETURN(kInvalid);  // No "iprp" in "meta" is an issue.
}

static AvifInfoInternalStatus ParseFileForFeatures(const uint8_t* bytes,
                                                   uint32_t num_bytes,
                                                   uint32_t file_size,
                                                   uint32_t target_item_id,
                                                   uint32_t* num_parsed_boxes,
                                                   AvifInfoFeatures* features) {
  uint32_t position = 0;
  do {
    AvifInfoInternalBox box;
    AVIFINFO_CHECK_FOUND(AvifInfoInternalParseBox(
        bytes, num_bytes, file_size, position, num_parsed_boxes, &box));

    if (!memcmp(box.type, "meta", 4)) {
      return ParseMetaForFeatures(box.content, num_bytes - box.content_position,
                                  box.content_size, target_item_id,
                                  num_parsed_boxes, features);
    }
    position += box.size;
  } while (position != file_size);
  AVIFINFO_RETURN(kInvalid);  // No "meta" is an issue.
}

//------------------------------------------------------------------------------
// Search if a tile contains features through "meta > iref > dimg" boxes.

static AvifInfoInternalStatus ParseIrefForFeaturesInTiles(
    const uint8_t* bytes, uint32_t num_bytes, uint32_t max_num_bytes,
    const uint8_t* meta_bytes, uint32_t meta_num_bytes,
    uint32_t meta_max_num_bytes, uint32_t primary_item_id,
    uint32_t* num_parsed_boxes, AvifInfoFeatures* features) {
  uint32_t position = 0;
  do {
    AvifInfoInternalBox box;
    AVIFINFO_CHECK_FOUND(AvifInfoInternalParseBox(
        bytes, num_bytes, max_num_bytes, position, num_parsed_boxes, &box));

    if (!memcmp(box.type, "dimg", 4)) {
      // See ISO/IEC 14496-12:2015(E) 8.11.12.2
      const uint32_t num_bytes_per_id = (box.version == 0) ? 2 : 4;
      uint32_t offset = 0;
      AVIFINFO_CHECK_FOUND(
          AccessContent(&box, num_bytes, num_bytes_per_id + 2));
      const uint32_t from_item_id =
          AvifInfoInternalReadBigEndian(box.content + offset, num_bytes_per_id);
      offset += num_bytes_per_id;
      if (from_item_id == primary_item_id) {
        const uint32_t reference_count =
            AvifInfoInternalReadBigEndian(box.content + offset, 2);
        offset += 2;
        for (uint32_t i = 0; i < reference_count; ++i) {
          AVIFINFO_CHECK_FOUND(
              AccessContent(&box, num_bytes, offset + num_bytes_per_id));
          const uint32_t to_item_id = AvifInfoInternalReadBigEndian(
              box.content + offset, num_bytes_per_id);
          offset += num_bytes_per_id;
          AVIFINFO_CHECK(meta_bytes != NULL && meta_bytes < bytes, kInvalid);
          AVIFINFO_CHECK(meta_max_num_bytes > 0, kInvalid);
          // Go up one level: from "dimg" among "iref" to boxes among "meta".
          AVIFINFO_CHECK_NOT_FOUND(ParseMetaForFeatures(
              meta_bytes, meta_num_bytes, meta_max_num_bytes, to_item_id,
              num_parsed_boxes, features));
          // Trying the first tile should be enough. Check others just in case.
        }
      }
    }
    position += box.size;
  } while (position != max_num_bytes);
  AVIFINFO_RETURN(kNotFound);  // No "dimg" in "iref" is not an issue.
}

static AvifInfoInternalStatus ParseMetaForFeaturesInTiles(
    const uint8_t* bytes, uint32_t num_bytes, uint32_t max_num_bytes,
    uint32_t primary_item_id, uint32_t* num_parsed_boxes,
    AvifInfoFeatures* features) {
  uint32_t position = 0;
  do {
    AvifInfoInternalBox box;
    AVIFINFO_CHECK_FOUND(AvifInfoInternalParseBox(
        bytes, num_bytes, max_num_bytes, position, num_parsed_boxes, &box));

    if (!memcmp(box.type, "iref", 4)) {
      return ParseIrefForFeaturesInTiles(
          box.content, num_bytes - box.content_position, box.content_size,
          bytes, num_bytes, max_num_bytes, primary_item_id, num_parsed_boxes,
          features);
    }
    position += box.size;
  } while (position != max_num_bytes);
  AVIFINFO_RETURN(kNotFound);  // No "iref" in "meta" is not an issue.
}

static AvifInfoInternalStatus ParseFileForFeaturesInTiles(
    const uint8_t* bytes, uint32_t num_bytes, uint32_t file_size,
    uint32_t primary_item_id, uint32_t* num_parsed_boxes,
    AvifInfoFeatures* features) {
  uint32_t position = 0;
  do {
    AvifInfoInternalBox box;
    AVIFINFO_CHECK_FOUND(AvifInfoInternalParseBox(
        bytes, num_bytes, file_size, position, num_parsed_boxes, &box));

    if (!memcmp(box.type, "meta", 4)) {
      return ParseMetaForFeaturesInTiles(
          box.content, num_bytes - box.content_position, box.content_size,
          primary_item_id, num_parsed_boxes, features);
    }
    position += box.size;
  } while (position != file_size);
  AVIFINFO_RETURN(kInvalid);  // No "meta" is an issue.
}

//------------------------------------------------------------------------------
// Search if there is an alpha layer through "meta > iprp > ipco > auxC" boxes.

static AvifInfoInternalStatus ParseIpcoForAlpha(const uint8_t* bytes,
                                                uint32_t num_bytes,
                                                uint32_t max_num_bytes,
                                                uint32_t* num_parsed_boxes) {
  uint32_t position = 0;
  do {
    AvifInfoInternalBox box;
    AVIFINFO_CHECK_FOUND(AvifInfoInternalParseBox(
        bytes, num_bytes, max_num_bytes, position, num_parsed_boxes, &box));

    if (!memcmp(box.type, "auxC", 4)) {
      // See AV1 Image File Format (AVIF) 4
      // at https://aomediacodec.github.io/av1-avif/#auxiliary-images
      const char* kAlphaStr = "urn:mpeg:mpegB:cicp:systems:auxiliary:alpha";
      const uint32_t kAlphaStrLength = 44;  // Includes terminating character.
      if (box.content_size >= kAlphaStrLength) {
        AVIFINFO_CHECK(box.content_position + kAlphaStrLength <= num_bytes,
                       kTruncated);
        const char* const aux_type = (const char*)box.content;
        if (strcmp(aux_type, kAlphaStr) == 0) {
          // 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.
          return kFound;
        }
      }
    }
    position += box.size;
  } while (position != max_num_bytes);
  AVIFINFO_RETURN(kNotFound);  // No "auxC" in "ipco" is not an issue.
}

static AvifInfoInternalStatus ParseIprpForAlpha(const uint8_t* bytes,
                                                uint32_t num_bytes,
                                                uint32_t max_num_bytes,
                                                uint32_t* num_parsed_boxes) {
  uint32_t position = 0;
  do {
    AvifInfoInternalBox box;
    AVIFINFO_CHECK_FOUND(AvifInfoInternalParseBox(
        bytes, num_bytes, max_num_bytes, position, num_parsed_boxes, &box));

    if (!memcmp(box.type, "ipco", 4)) {
      return ParseIpcoForAlpha(box.content, num_bytes - box.content_position,
                               box.content_size, num_parsed_boxes);
    }
    position += box.size;
  } while (position != max_num_bytes);
  AVIFINFO_RETURN(kInvalid);  // No "ipco" in "iprp" is an issue.
}

static AvifInfoInternalStatus ParseMetaForAlpha(const uint8_t* bytes,
                                                uint32_t num_bytes,
                                                uint32_t max_num_bytes,
                                                uint32_t* num_parsed_boxes) {
  uint32_t position = 0;
  do {
    AvifInfoInternalBox box;
    AVIFINFO_CHECK_FOUND(AvifInfoInternalParseBox(
        bytes, num_bytes, max_num_bytes, position, num_parsed_boxes, &box));

    if (!memcmp(box.type, "iprp", 4)) {
      return ParseIprpForAlpha(box.content, num_bytes - box.content_position,
                               box.content_size, num_parsed_boxes);
    }
    position += box.size;
  } while (position != max_num_bytes);
  AVIFINFO_RETURN(kInvalid);  // No "iprp" in "meta" is an issue.
}

static AvifInfoInternalStatus ParseFileForAlpha(const uint8_t* bytes,
                                                uint32_t num_bytes,
                                                uint32_t file_size,
                                                uint32_t* num_parsed_boxes) {
  uint32_t position = 0;
  do {
    AvifInfoInternalBox box;
    AVIFINFO_CHECK_FOUND(AvifInfoInternalParseBox(
        bytes, num_bytes, file_size, position, num_parsed_boxes, &box));

    if (!memcmp(box.type, "meta", 4)) {
      return ParseMetaForAlpha(box.content, num_bytes - box.content_position,
                               box.content_size, num_parsed_boxes);
    }
    position += box.size;
  } while (position != file_size);
  AVIFINFO_RETURN(kInvalid);  // No "meta" is an issue.
}

//------------------------------------------------------------------------------
// Parsing starting point.

static AvifInfoInternalStatus AvifInfoInternalParseFile(
    const uint8_t* bytes, uint32_t num_bytes, uint32_t file_size,
    AvifInfoFeatures* features) {
  uint32_t num_parsed_boxes = 0;
  AVIFINFO_CHECK_FOUND(
      ParseFileForBrand(bytes, num_bytes, file_size, &num_parsed_boxes));

  // 'bytes' is an AVIF file. Next step is finding the ID of the primary item.
  uint32_t primary_item_id;
  AVIFINFO_CHECK_FOUND(ParseFileForPrimaryItemId(
      bytes, num_bytes, file_size, &num_parsed_boxes, &primary_item_id));

  // Now find the 'features' of the primary item.
  AvifInfoInternalStatus status =
      ParseFileForFeatures(bytes, num_bytes, file_size, primary_item_id,
                           &num_parsed_boxes, features);
  if (status == kNotFound) {
    // It is possible that some of the 'features' are missing for the primary
    // item. Try to look into tiles in case they are defined there.
    status = ParseFileForFeaturesInTiles(bytes, num_bytes, file_size,
                                         primary_item_id, &num_parsed_boxes,
                                         features);
  }
  AVIFINFO_CHECK_FOUND(status);

  // If there is an alpha plane, add 1 to the number of channels.
  status = ParseFileForAlpha(bytes, num_bytes, file_size, &num_parsed_boxes);
  if (status == kFound) {
    ++features->num_channels;
  } else {
    AVIFINFO_CHECK_NOT_FOUND(status);
  }
  return kFound;
}

//------------------------------------------------------------------------------
// Public API

AvifInfoStatus AvifInfoGet(const uint8_t* data, size_t data_size,
                           AvifInfoFeatures* features) {
  // Consider the file to be of maximum size.
  return AvifInfoGetWithSize(data, data_size, features,
                             /*file_size=*/kAvifInfoInternalMaxSize);
}

AvifInfoStatus AvifInfoGetWithSize(const uint8_t* data, size_t data_size,
                                   AvifInfoFeatures* features,
                                   size_t file_size) {
  if (features != NULL) memset(features, 0, sizeof(*features));
  if (data == NULL) return kAvifInfoNotEnoughData;
  if (data_size > file_size) data_size = file_size;

  AvifInfoFeatures parsed_features;
  memset(&parsed_features, 0, sizeof(parsed_features));
  const AvifInfoInternalStatus status = AvifInfoInternalParseFile(
      data,
      (data_size >= kAvifInfoInternalMaxSize) ? kAvifInfoInternalMaxSize
                                              : (uint32_t)data_size,
      (file_size >= kAvifInfoInternalMaxSize) ? kAvifInfoInternalMaxSize
                                              : (uint32_t)file_size,
      &parsed_features);

  if (status == kNotFound) {
    return (data_size < file_size) ? kAvifInfoNotEnoughData
                                   : kAvifInfoInvalidFile;
  }
  if (status == kTruncated) return kAvifInfoNotEnoughData;
  if (status == kInvalid) return kAvifInfoInvalidFile;
  if (status == kAborted) return kAvifInfoTooComplex;
  if (features != NULL) {
    memcpy(features, &parsed_features, sizeof(*features));
  }
  return kAvifInfoOk;
}

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

#undef AVIFINFO_RETURN
#undef AVIFINFO_CHECK
#undef AVIFINFO_CHECK_STATUS_IS
#undef AVIFINFO_CHECK_FOUND
#undef AVIFINFO_CHECK_NOT_FOUND
