Error parse_sps_for_vvcC_configuration()

in libheif/codecs/vvc.cc [277:393]


Error parse_sps_for_vvcC_configuration(const uint8_t* sps, size_t size,
                                       Box_vvcC::configuration* config,
                                       int* width, int* height)
{
  // remove start-code emulation bytes from SPS header stream

  std::vector<uint8_t> sps_no_emul = remove_start_code_emulation(sps, size);

  sps = sps_no_emul.data();
  size = sps_no_emul.size();

  BitReader reader(sps, (int) size);

  // skip NAL header
  reader.skip_bits(2 * 8);

  // skip SPS ID
  reader.skip_bits(4);

  // skip VPS ID
  reader.skip_bits(4);

  config->numTemporalLayers = (uint8_t)(reader.get_bits(3) + 1);
  config->chroma_format_idc = (uint8_t)(reader.get_bits(2));
  config->chroma_format_present_flag = true;
  reader.skip_bits(2);

  bool sps_ptl_dpb_hrd_params_present_flag = reader.get_bits(1);
  if (sps_ptl_dpb_hrd_params_present_flag) {
    // profile_tier_level( 1, sps_max_sublayers_minus1 )

    if (true /*profileTierPresentFlag*/) {
      //general_profile_idc
          //general_tier_flag
          reader.skip_bits(8);
    }
    reader.skip_bits(8); // general_level_idc
    reader.skip_bits(1); //ptl_frame_only_constraint_flag
    reader.skip_bits(1); //ptl_multilayer_enabled_flag
    if (true /* profileTierPresentFlag*/ ) {
      // general_constraints_info()

      bool gci_present_flag = reader.get_bits(1);
      if (gci_present_flag) {
        assert(false);
      }

      reader.skip_to_byte_boundary();
    }

    std::vector<bool> ptl_sublayer_level_present_flag(config->numTemporalLayers);
    for (int i = config->numTemporalLayers-2; i >= 0; i--) {
      ptl_sublayer_level_present_flag[i] = reader.get_bits(1);
    }

    reader.skip_to_byte_boundary();

    for (int i = config->numTemporalLayers-2; i >= 0; i--) {
      if (ptl_sublayer_level_present_flag[i]) {
        reader.skip_bits(8); // sublayer_level_idc[i]
      }
    }

    if (true /*profileTierPresentFlag*/) {
      int ptl_num_sub_profiles = reader.get_bits(8);
      for (int i = 0; i < ptl_num_sub_profiles; i++) {
        uint32_t idc = reader.get_bits(32); //general_sub_profile_idc[i]
        (void) idc;
      }
    }
  }

  reader.skip_bits(1); // sps_gdr_enabled_flag
  bool sps_ref_pic_resampling_enabled_flag = reader.get_bits(1);
  if (sps_ref_pic_resampling_enabled_flag) {
    reader.skip_bits(1); // sps_res_change_in_clvs_allowed_flag
  }

  int sps_pic_width_max_in_luma_samples;
  int sps_pic_height_max_in_luma_samples;

  bool success;
  success = reader.get_uvlc(&sps_pic_width_max_in_luma_samples);
  (void)success;
  success = reader.get_uvlc(&sps_pic_height_max_in_luma_samples);
  (void)success;

  *width = sps_pic_width_max_in_luma_samples;
  *height = sps_pic_height_max_in_luma_samples;

  int sps_conformance_window_flag = reader.get_bits(1);
  if (sps_conformance_window_flag) {
    int left,right,top,bottom;
    reader.get_uvlc(&left);
    reader.get_uvlc(&right);
    reader.get_uvlc(&top);
    reader.get_uvlc(&bottom);
  }

  bool sps_subpic_info_present_flag = reader.get_bits(1);
  if (sps_subpic_info_present_flag) {
    assert(false); // TODO
  }

  int bitDepth_minus8;
  success = reader.get_uvlc(&bitDepth_minus8);
  (void)success;

  if (bitDepth_minus8 > 0xFF - 8) {
    return {heif_error_Encoding_error, heif_suberror_Unspecified, "VCC bit depth out of range."};
  }

  config->bit_depth = (uint8_t)(bitDepth_minus8 + 8);
  config->bit_depth_present_flag = true;

  return Error::Ok;
}