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