static Error uncompressed_image_type_is_supported()

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