bool Image_reader::decode_core()

in src/mlio/image_reader.cc [156:236]


bool Image_reader::decode_core(stdx::span<std::uint8_t> out, const Instance &instance) const
{
    Memory_slice img_buf{};
    if (params_.image_frame == Image_frame::recordio) {
        // Skip the 24-byte header defined in image_recordio.h in the
        // MXNet GitHub repository. This header contains metadata and
        // is not relevant in our implementation.
        img_buf = instance.bits().subslice(recordio_image_header_offset_);
    }
    else {
        img_buf = instance.bits();
    }

    cv::Mat mat{1,
                static_cast<int>(img_buf.size()),
                CV_8U,
                // NOLINTNEXTLINE(cppcoreguidelines-pro-type-const-cast)
                static_cast<void *>(const_cast<std::byte *>(img_buf.data()))};

    cv::ImreadModes mode{};
    int type{};

    switch (img_dims_[0]) {
    case 1:
        mode = cv::ImreadModes::IMREAD_GRAYSCALE;
        type = CV_8UC1;
        break;
    case 3:
        mode = cv::ImreadModes::IMREAD_COLOR;
        type = CV_8UC3;
        break;
    case 4:
        mode = cv::ImreadModes::IMREAD_UNCHANGED;
        type = CV_8UC4;
        break;
    default:
        throw std::invalid_argument{fmt::format(
            "The specified image dimensions have an unsupported number of channels ({0:n}).",
            img_dims_[0])};
    }

    cv::Mat tmp = decode_image(mat, mode, instance);
    if (tmp.empty()) {
        return false;
    }

    if (params_.resize) {
        if (!resize(tmp, tmp, instance)) {
            return false;
        }
    }

    if (params_.to_rgb && tmp.channels() != 1) {
        try {
            cv::cvtColor(tmp, tmp, cv::COLOR_BGR2RGB);
        }
        catch (const cv::Exception &e) {
            if (warn_bad_instances() || error_bad_example_) {
                auto msg = fmt::format(
                    "The BGR2RGB operation failed for the image #{1:n} in the data store '{0}' with the following exception: {2}",
                    instance.data_store().id(),
                    instance.index(),
                    e.what());

                if (warn_bad_instances()) {
                    logger::warn(msg);
                }

                if (error_bad_example_) {
                    throw Invalid_instance_error{msg};
                }
            }

            return false;
        }
    }

    cv::Mat dst{img_dims_[1], img_dims_[2], type, out.data()};

    return crop(tmp, dst, instance);
}