in libheif/codecs/uncompressed_image.cc [44:240]
static Error uncompressed_image_type_is_supported(std::shared_ptr<Box_uncC>& uncC, std::shared_ptr<Box_cmpd>& cmpd)
{
if (isKnownUncompressedFrameConfigurationBoxProfile(uncC))
{
return Error::Ok;
}
if (!cmpd) {
return Error(heif_error_Unsupported_feature,
heif_suberror_Unsupported_data_version,
"Missing required cmpd box (no match in uncC box) for uncompressed codec");
}
for (Box_uncC::Component component : uncC->get_components()) {
uint16_t component_index = component.component_index;
uint16_t component_type = cmpd->get_components()[component_index].component_type;
if ((component_type > 7) && (component_type != component_type_padded)) {
printf("unsupported component type: %d\n", component_type);
std::stringstream sstr;
sstr << "Uncompressed image with component_type " << ((int) component_type) << " is not implemented yet";
return Error(heif_error_Unsupported_feature,
heif_suberror_Unsupported_data_version,
sstr.str());
}
if ((component.component_bit_depth > 8) && (component.component_bit_depth != 16)) {
printf("unsupported component bit depth for index: %d, value: %d\n", component_index, component.component_bit_depth);
std::stringstream sstr;
sstr << "Uncompressed image with component_bit_depth " << ((int) component.component_bit_depth) << " is not implemented yet";
return Error(heif_error_Unsupported_feature,
heif_suberror_Unsupported_data_version,
sstr.str());
}
if (component.component_format != component_format_unsigned) {
printf("unsupported component format\n");
std::stringstream sstr;
sstr << "Uncompressed image with component_format " << ((int) component.component_format) << " is not implemented yet";
return Error(heif_error_Unsupported_feature,
heif_suberror_Unsupported_data_version,
sstr.str());
}
if (component.component_align_size > 2) {
printf("unsupported component_align_size\n");
std::stringstream sstr;
sstr << "Uncompressed image with component_align_size " << ((int) component.component_align_size) << " is not implemented yet";
return Error(heif_error_Unsupported_feature,
heif_suberror_Unsupported_data_version,
sstr.str());
}
}
if ((uncC->get_sampling_type() != sampling_mode_no_subsampling)
&& (uncC->get_sampling_type() != sampling_mode_422)
&& (uncC->get_sampling_type() != sampling_mode_420)
) {
printf("bad sampling: %d\n", uncC->get_sampling_type());
std::stringstream sstr;
sstr << "Uncompressed sampling_type of " << ((int) uncC->get_sampling_type()) << " is not implemented yet";
return Error(heif_error_Unsupported_feature,
heif_suberror_Unsupported_data_version,
sstr.str());
}
if ((uncC->get_interleave_type() != interleave_mode_component)
&& (uncC->get_interleave_type() != interleave_mode_pixel)
&& (uncC->get_interleave_type() != interleave_mode_mixed)
&& (uncC->get_interleave_type() != interleave_mode_row)
&& (uncC->get_interleave_type() != interleave_mode_tile_component)
) {
printf("bad interleave: %d\n", uncC->get_interleave_type());
std::stringstream sstr;
sstr << "Uncompressed interleave_type of " << ((int) uncC->get_interleave_type()) << " is not implemented yet";
return Error(heif_error_Unsupported_feature,
heif_suberror_Unsupported_data_version,
sstr.str());
}
// Validity checks per ISO/IEC 23001-17 Section 5.2.1.5.3
if (uncC->get_sampling_type() == sampling_mode_422) {
// We check Y Cb and Cr appear in the chroma test
// TODO: error for tile width not multiple of 2
if ((uncC->get_interleave_type() != interleave_mode_component)
&& (uncC->get_interleave_type() != interleave_mode_mixed)
&& (uncC->get_interleave_type() != interleave_mode_multi_y))
{
std::stringstream sstr;
sstr << "YCbCr 4:2:2 subsampling is only valid with component, mixed or multi-Y interleave mode (ISO/IEC 23001-17 5.2.1.5.3).";
return Error(heif_error_Invalid_input,
heif_suberror_Invalid_parameter_value,
sstr.str());
}
if ((uncC->get_row_align_size() != 0) && (uncC->get_interleave_type() == interleave_mode_component)) {
if (uncC->get_row_align_size() % 2 != 0) {
std::stringstream sstr;
sstr << "YCbCr 4:2:2 subsampling with component interleave requires row_align_size to be a multiple of 2 (ISO/IEC 23001-17 5.2.1.5.3).";
return Error(heif_error_Invalid_input,
heif_suberror_Invalid_parameter_value,
sstr.str());
}
}
if (uncC->get_tile_align_size() != 0) {
if (uncC->get_tile_align_size() % 2 != 0) {
std::stringstream sstr;
sstr << "YCbCr 4:2:2 subsampling requires tile_align_size to be a multiple of 2 (ISO/IEC 23001-17 5.2.1.5.3).";
return Error(heif_error_Invalid_input,
heif_suberror_Invalid_parameter_value,
sstr.str());
}
}
}
// Validity checks per ISO/IEC 23001-17 Section 5.2.1.5.4
if (uncC->get_sampling_type() == sampling_mode_422) {
// We check Y Cb and Cr appear in the chroma test
// TODO: error for tile width not multiple of 2
if ((uncC->get_interleave_type() != interleave_mode_component)
&& (uncC->get_interleave_type() != interleave_mode_mixed))
{
std::stringstream sstr;
sstr << "YCbCr 4:2:0 subsampling is only valid with component or mixed interleave mode (ISO/IEC 23001-17 5.2.1.5.4).";
return Error(heif_error_Invalid_input,
heif_suberror_Invalid_parameter_value,
sstr.str());
}
if ((uncC->get_row_align_size() != 0) && (uncC->get_interleave_type() == interleave_mode_component)) {
if (uncC->get_row_align_size() % 2 != 0) {
std::stringstream sstr;
sstr << "YCbCr 4:2:2 subsampling with component interleave requires row_align_size to be a multiple of 2 (ISO/IEC 23001-17 5.2.1.5.4).";
return Error(heif_error_Invalid_input,
heif_suberror_Invalid_parameter_value,
sstr.str());
}
}
if (uncC->get_tile_align_size() != 0) {
if (uncC->get_tile_align_size() % 4 != 0) {
std::stringstream sstr;
sstr << "YCbCr 4:2:2 subsampling requires tile_align_size to be a multiple of 4 (ISO/IEC 23001-17 5.2.1.5.3).";
return Error(heif_error_Invalid_input,
heif_suberror_Invalid_parameter_value,
sstr.str());
}
}
}
if ((uncC->get_interleave_type() == interleave_mode_mixed) && (uncC->get_sampling_type() == sampling_mode_no_subsampling))
{
std::stringstream sstr;
sstr << "Interleave interleave mode is not valid with subsampling mode (ISO/IEC 23001-17 5.2.1.6.4).";
return Error(heif_error_Invalid_input,
heif_suberror_Invalid_parameter_value,
sstr.str());
}
if ((uncC->get_interleave_type() == interleave_mode_multi_y)
&& ((uncC->get_sampling_type() != sampling_mode_422) && (uncC->get_sampling_type() != sampling_mode_411)))
{
std::stringstream sstr;
sstr << "Multi-Y interleave mode is only valid with 4:2:2 and 4:1:1 subsampling modes (ISO/IEC 23001-17 5.2.1.6.7).";
return Error(heif_error_Invalid_input,
heif_suberror_Invalid_parameter_value,
sstr.str());
}
// TODO: throw error if mixed and Cb and Cr are not adjacent.
if (uncC->get_block_size() != 0) {
printf("unsupported block size\n");
std::stringstream sstr;
sstr << "Uncompressed block_size of " << ((int) uncC->get_block_size()) << " is not implemented yet";
return Error(heif_error_Unsupported_feature,
heif_suberror_Unsupported_data_version,
sstr.str());
}
if (uncC->is_components_little_endian()) {
printf("unsupported components LE\n");
return Error(heif_error_Unsupported_feature,
heif_suberror_Unsupported_data_version,
"Uncompressed components_little_endian == 1 is not implemented yet");
}
if (uncC->is_block_pad_lsb()) {
printf("unsupported block pad LSB\n");
return Error(heif_error_Unsupported_feature,
heif_suberror_Unsupported_data_version,
"Uncompressed block_pad_lsb == 1 is not implemented yet");
}
if (uncC->is_block_little_endian()) {
printf("unsupported block LE\n");
return Error(heif_error_Unsupported_feature,
heif_suberror_Unsupported_data_version,
"Uncompressed block_little_endian == 1 is not implemented yet");
}
if (uncC->is_block_reversed()) {
printf("unsupported block reversed\n");
return Error(heif_error_Unsupported_feature,
heif_suberror_Unsupported_data_version,
"Uncompressed block_reversed == 1 is not implemented yet");
}
if ((uncC->get_pixel_size() != 0) && ((uncC->get_interleave_type() != interleave_mode_pixel) && (uncC->get_interleave_type() != interleave_mode_multi_y))) {
std::stringstream sstr;
sstr << "Uncompressed pixel_size of " << ((int) uncC->get_pixel_size()) << " is only valid with interleave_type 1 or 5 (ISO/IEC 23001-17 5.2.1.7)";
return Error(heif_error_Invalid_input,
heif_suberror_Invalid_parameter_value,
sstr.str());
}
return Error::Ok;
}