From 8c6ec2bf1ded486159732885ae7896feea4d7e2e Mon Sep 17 00:00:00 2001 From: Dmitry Baryshev Date: Fri, 15 Jul 2022 19:25:53 -0700 Subject: [PATCH 1/6] BINDINGS/C++: Refactor image_input --- .../c++/qt/advanced-with-c++-api/qtsail.cpp | 9 +- src/bindings/c++/image-c++.cpp | 3 +- src/bindings/c++/image_input-c++.cpp | 317 ++++-------------- src/bindings/c++/image_input-c++.h | 265 ++------------- tests/bindings/c++/can-load.cpp | 46 ++- 5 files changed, 122 insertions(+), 518 deletions(-) diff --git a/examples/c++/qt/advanced-with-c++-api/qtsail.cpp b/examples/c++/qt/advanced-with-c++-api/qtsail.cpp index f5683c2f..402485c2 100644 --- a/examples/c++/qt/advanced-with-c++-api/qtsail.cpp +++ b/examples/c++/qt/advanced-with-c++-api/qtsail.cpp @@ -72,14 +72,13 @@ sail_status_t QtSail::loadImage(const QString &path, QVector *qimages, Q qimages->clear(); delays->clear(); - sail::image_input image_input; sail::image image; sail::image first_image; // Initialize loading. // sail::io_file io_file(path.toLocal8Bit().constData()); - SAIL_TRY(image_input.start(io_file)); + sail::image_input image_input(io_file); // Load all the available image frames in the file. // @@ -117,9 +116,6 @@ sail_status_t QtSail::loadImage(const QString &path, QVector *qimages, Q SAIL_LOG_DEBUG("Loaded images: %d", qimages->size()); - // Optional - SAIL_TRY(image_input.stop()); - m_ui->labelStatus->setText(tr("%1 [%2x%3] [%4 → %5]") .arg(QFileInfo(path).fileName()) .arg(first_image.width()) @@ -208,8 +204,7 @@ sail_status_t QtSail::onProbe() QElapsedTimer elapsedTimer; elapsedTimer.start(); - sail::image_input image_input; - auto [image, codec_info] = image_input.probe(path.toLocal8Bit().constData()); + auto [image, codec_info] = sail::image_input(path.toLocal8Bit().constData()).probe(); QMessageBox::information(this, tr("File info"), diff --git a/src/bindings/c++/image-c++.cpp b/src/bindings/c++/image-c++.cpp index 19c95b14..a18c2972 100644 --- a/src/bindings/c++/image-c++.cpp +++ b/src/bindings/c++/image-c++.cpp @@ -303,8 +303,7 @@ void image::set_iccp(sail::iccp &&iccp) noexcept sail_status_t image::load(const std::string &path) { - image_input input; - SAIL_TRY(input.start(path)); + image_input input(path); image img; SAIL_TRY(input.next_frame(&img)); diff --git a/src/bindings/c++/image_input-c++.cpp b/src/bindings/c++/image_input-c++.cpp index 76ef8956..3e4043ab 100644 --- a/src/bindings/c++/image_input-c++.cpp +++ b/src/bindings/c++/image_input-c++.cpp @@ -34,215 +34,126 @@ namespace sail class SAIL_HIDDEN image_input::pimpl { public: - pimpl() - : state(nullptr) + pimpl(sail::abstract_io *abstract_io_ext) + : abstract_io(abstract_io_ext) + , abstract_io_ref(*abstract_io) + , abstract_io_adapter(new sail::abstract_io_adapter(abstract_io_ref)) + , state(nullptr) + , override_codec_info(false) + , override_load_options(false) { } - sail_status_t ensure_not_started() + pimpl(sail::abstract_io &abstract_io_ext) + : abstract_io() + , abstract_io_ref(abstract_io_ext) + , abstract_io_adapter(new sail::abstract_io_adapter(abstract_io_ref)) + , state(nullptr) + , override_codec_info(false) + , override_load_options(false) { - if (state != nullptr) { - SAIL_LOG_ERROR("Reading operation is in progress. Stop it before starting a new one"); - return SAIL_ERROR_CONFLICTING_OPERATION; - } - - return SAIL_OK; } - void *state; - std::unique_ptr abstract_io_adapter; -}; - -image_input::image_input() - : d(new pimpl) -{ -} + sail_status_t start(); -image_input::~image_input() -{ - stop(); -} +private: + const std::unique_ptr abstract_io; + sail::abstract_io &abstract_io_ref; -sail_status_t image_input::start(const std::string &path) -{ - SAIL_TRY(d->ensure_not_started()); - - SAIL_TRY(sail_start_loading_from_file(path.c_str(), nullptr, &d->state)); +public: + const std::unique_ptr abstract_io_adapter; + void *state; - return SAIL_OK; -} + bool override_codec_info; + sail::codec_info codec_info; + bool override_load_options; + sail::load_options load_options; +}; -sail_status_t image_input::start(const std::string &path, const sail::codec_info &codec_info) +sail_status_t image_input::pimpl::start() { - SAIL_TRY(d->ensure_not_started()); - - SAIL_TRY(sail_start_loading_from_file(path.c_str(), codec_info.sail_codec_info_c(), &d->state)); + if (!override_codec_info) { + codec_info = abstract_io_ref.codec_info(); + } - return SAIL_OK; -} + const sail_codec_info *sail_codec_info = codec_info.sail_codec_info_c(); -sail_status_t image_input::start(const std::string &path, const sail::codec_info &codec_info, const sail::load_options &load_options) -{ - SAIL_TRY(d->ensure_not_started()); + sail_load_options *sail_load_options = nullptr; - sail_load_options *sail_load_options; - SAIL_TRY(load_options.to_sail_load_options(&sail_load_options)); + SAIL_AT_SCOPE_EXIT( + sail_destroy_load_options(sail_load_options); + ); - SAIL_TRY_OR_CLEANUP(sail_start_loading_from_file_with_options(path.c_str(), codec_info.sail_codec_info_c(), sail_load_options, &d->state), - /* cleanup */ sail_destroy_load_options(sail_load_options)); + if (override_load_options) { + SAIL_TRY(load_options.to_sail_load_options(&sail_load_options)); + } - sail_destroy_load_options(sail_load_options); + SAIL_TRY(sail_start_loading_from_io_with_options(&abstract_io_adapter->sail_io_c(), sail_codec_info, sail_load_options, &state)); return SAIL_OK; } -sail_status_t image_input::start(const void *buffer, std::size_t buffer_length) +image_input::image_input(const std::string &path) + : d(new pimpl(new io_file(path))) { - SAIL_TRY(d->ensure_not_started()); - - SAIL_TRY(sail_start_loading_from_memory(buffer, buffer_length, nullptr, &d->state)); - - return SAIL_OK; } -sail_status_t image_input::start(const void *buffer, std::size_t buffer_length, const sail::codec_info &codec_info) +image_input::image_input(const void *buffer, std::size_t buffer_length) + : d(new pimpl(new io_memory(buffer, buffer_length))) { - SAIL_TRY(d->ensure_not_started()); - - SAIL_TRY(sail_start_loading_from_memory(buffer, buffer_length, codec_info.sail_codec_info_c(), &d->state)); - - return SAIL_OK; } -sail_status_t image_input::start(const void *buffer, std::size_t buffer_length, const sail::load_options &load_options) +image_input::image_input(const sail::arbitrary_data &arbitrary_data) + : image_input(arbitrary_data.data(), arbitrary_data.size()) { - SAIL_TRY(d->ensure_not_started()); - - sail_load_options *sail_load_options; - SAIL_TRY(load_options.to_sail_load_options(&sail_load_options)); - - SAIL_TRY_OR_CLEANUP(sail_start_loading_from_memory_with_options(buffer, buffer_length, nullptr, sail_load_options, &d->state), - /* cleanup */ sail_destroy_load_options(sail_load_options)); - - sail_destroy_load_options(sail_load_options); - - return SAIL_OK; } -sail_status_t image_input::start(const void *buffer, std::size_t buffer_length, const sail::codec_info &codec_info, const sail::load_options &load_options) +image_input::image_input(sail::abstract_io &abstract_io) + : d(new pimpl(abstract_io)) { - SAIL_TRY(d->ensure_not_started()); - - sail_load_options *sail_load_options; - SAIL_TRY(load_options.to_sail_load_options(&sail_load_options)); - - SAIL_TRY_OR_CLEANUP(sail_start_loading_from_memory_with_options(buffer, buffer_length, codec_info.sail_codec_info_c(), sail_load_options, &d->state), - /* cleanup */ sail_destroy_load_options(sail_load_options)); - - sail_destroy_load_options(sail_load_options); - - return SAIL_OK; } -sail_status_t image_input::start(const sail::arbitrary_data &arbitrary_data) +image_input::~image_input() { - SAIL_TRY(start(arbitrary_data.data(), arbitrary_data.size())); - - return SAIL_OK; + if (d) { + SAIL_TRY_OR_SUPPRESS(sail_stop_loading(d->state)); + } } -sail_status_t image_input::start(const sail::arbitrary_data &arbitrary_data, const sail::codec_info &codec_info) +image_input::image_input(image_input &&other) { - SAIL_TRY(start(arbitrary_data.data(), arbitrary_data.size(), codec_info)); - - return SAIL_OK; + *this = std::move(other); } -sail_status_t image_input::start(const sail::arbitrary_data &arbitrary_data, const sail::load_options &load_options) +image_input& image_input::operator=(image_input &&other) { - SAIL_TRY(start(arbitrary_data.data(), arbitrary_data.size(), load_options)); + d = std::move(other.d); + other.d = {}; - return SAIL_OK; + return *this; } -sail_status_t image_input::start(const sail::arbitrary_data &arbitrary_data, const sail::codec_info &codec_info, const sail::load_options &load_options) +image_input& image_input::with(const sail::codec_info &codec_info) { - SAIL_TRY(start(arbitrary_data.data(), arbitrary_data.size(), codec_info, load_options)); + d->override_codec_info = true; + d->codec_info = codec_info; - return SAIL_OK; + return *this; } -sail_status_t image_input::start(sail::abstract_io &abstract_io) +image_input& image_input::with(const sail::load_options &load_options) { - SAIL_TRY(d->ensure_not_started()); + d->override_load_options = true; + d->load_options = load_options; - d->abstract_io_adapter.reset(new sail::abstract_io_adapter(abstract_io)); - - const sail::codec_info codec_info = abstract_io.codec_info(); - - if (!codec_info.is_valid()) { - SAIL_LOG_AND_RETURN(SAIL_ERROR_CODEC_NOT_FOUND); - } - - SAIL_TRY(sail_start_loading_from_io(&d->abstract_io_adapter->sail_io_c(), codec_info.sail_codec_info_c(), &d->state)); - - return SAIL_OK; -} - -sail_status_t image_input::start(sail::abstract_io &abstract_io, const sail::codec_info &codec_info) -{ - SAIL_TRY(d->ensure_not_started()); - - d->abstract_io_adapter.reset(new sail::abstract_io_adapter(abstract_io)); - - SAIL_TRY(sail_start_loading_from_io(&d->abstract_io_adapter->sail_io_c(), codec_info.sail_codec_info_c(), &d->state)); - - return SAIL_OK; -} - -sail_status_t image_input::start(sail::abstract_io &abstract_io, const sail::load_options &load_options) -{ - SAIL_TRY(d->ensure_not_started()); - - d->abstract_io_adapter.reset(new sail::abstract_io_adapter(abstract_io)); - - const sail::codec_info codec_info = abstract_io.codec_info(); - - if (!codec_info.is_valid()) { - SAIL_LOG_AND_RETURN(SAIL_ERROR_CODEC_NOT_FOUND); - } - - sail_load_options *sail_load_options; - SAIL_TRY(load_options.to_sail_load_options(&sail_load_options)); - - SAIL_TRY_OR_CLEANUP(sail_start_loading_from_io_with_options(&d->abstract_io_adapter->sail_io_c(), codec_info.sail_codec_info_c(), sail_load_options, &d->state), - /* cleanup */ sail_destroy_load_options(sail_load_options)); - - sail_destroy_load_options(sail_load_options); - - return SAIL_OK; -} - -sail_status_t image_input::start(sail::abstract_io &abstract_io, const sail::codec_info &codec_info, const sail::load_options &load_options) -{ - SAIL_TRY(d->ensure_not_started()); - - d->abstract_io_adapter.reset(new sail::abstract_io_adapter(abstract_io)); - - sail_load_options *sail_load_options; - SAIL_TRY(load_options.to_sail_load_options(&sail_load_options)); - - SAIL_TRY_OR_CLEANUP(sail_start_loading_from_io_with_options(&d->abstract_io_adapter->sail_io_c(), codec_info.sail_codec_info_c(), sail_load_options, &d->state), - /* cleanup */ sail_destroy_load_options(sail_load_options)); - - sail_destroy_load_options(sail_load_options); - - return SAIL_OK; + return *this; } sail_status_t image_input::next_frame(sail::image *image) { - SAIL_CHECK_PTR(image); + if (d->state == nullptr) { + SAIL_TRY(d->start()); + } sail_image *sail_image = nullptr; @@ -268,57 +179,8 @@ image image_input::next_frame() return image; } -sail_status_t image_input::stop() -{ - sail_status_t saved_status = SAIL_OK; - SAIL_TRY_OR_EXECUTE(sail_stop_loading(d->state), - /* on error */ saved_status = __sail_error_result); - - d->state = nullptr; - d->abstract_io_adapter.reset(); - - return saved_status; -} - -std::tuple image_input::probe(const std::string &path) -{ - const sail_codec_info *sail_codec_info; - sail_image *sail_image = nullptr; - - SAIL_AT_SCOPE_EXIT( - sail_destroy_image(sail_image); - ); - - SAIL_TRY_OR_EXECUTE(sail_probe_file(path.c_str(), &sail_image, &sail_codec_info), - /* on error */ return {}); - - return std::tuple{ image(sail_image), codec_info(sail_codec_info) }; -} - -std::tuple image_input::probe(const void *buffer, std::size_t buffer_length) -{ - const sail_codec_info *sail_codec_info; - sail_image *sail_image = nullptr; - - SAIL_AT_SCOPE_EXIT( - sail_destroy_image(sail_image); - ); - - SAIL_TRY_OR_EXECUTE(sail_probe_memory(buffer, buffer_length, &sail_image, &sail_codec_info), - /* on error */ return {}); - - return std::tuple{ image(sail_image), codec_info(sail_codec_info) }; -} - -std::tuple image_input::probe(const sail::arbitrary_data &arbitrary_data) -{ - return probe(arbitrary_data.data(), arbitrary_data.size()); -} - -std::tuple image_input::probe(sail::abstract_io &abstract_io) +std::tuple image_input::probe() { - sail::abstract_io_adapter abstract_io_adapter(abstract_io); - const sail_codec_info *sail_codec_info; sail_image *sail_image = nullptr; @@ -326,49 +188,10 @@ std::tuple image_input::probe(sail::abstract_io &abstract_io) sail_destroy_image(sail_image); ); - SAIL_TRY_OR_EXECUTE(sail_probe_io(&abstract_io_adapter.sail_io_c(), &sail_image, &sail_codec_info), + SAIL_TRY_OR_EXECUTE(sail_probe_io(&d->abstract_io_adapter->sail_io_c(), &sail_image, &sail_codec_info), /* on error */ return {}); return std::tuple{ image(sail_image), codec_info(sail_codec_info) }; } -image image_input::load(const std::string &path) -{ - sail_image *sail_image = nullptr; - - SAIL_AT_SCOPE_EXIT( - sail_destroy_image(sail_image); - ); - - SAIL_TRY_OR_EXECUTE(sail_load_from_file(path.c_str(), &sail_image), - /* on error */ return {}); - - const sail::image image(sail_image); - sail_image->pixels = nullptr; - - return image; -} - -image image_input::load(const void *buffer, std::size_t buffer_length) -{ - sail_image *sail_image = nullptr; - - SAIL_AT_SCOPE_EXIT( - sail_destroy_image(sail_image); - ); - - SAIL_TRY_OR_EXECUTE(sail_load_from_memory(buffer, buffer_length, &sail_image), - /* on error */ return {}); - - const sail::image image(sail_image); - sail_image->pixels = nullptr; - - return image; -} - -image image_input::load(const sail::arbitrary_data &arbitrary_data) -{ - return load(arbitrary_data.data(), arbitrary_data.size()); -} - } diff --git a/src/bindings/c++/image_input-c++.h b/src/bindings/c++/image_input-c++.h index 8005b1bf..e5429dd6 100644 --- a/src/bindings/c++/image_input-c++.h +++ b/src/bindings/c++/image_input-c++.h @@ -36,312 +36,101 @@ #include "export.h" #include "arbitrary_data-c++.h" + #include "image_input-c++.h" #else #include #include #include + #include #endif namespace sail { class abstract_io; -class image; class codec_info; class load_options; /* - * Class to probe and load images form files, memory, and custom I/O sources. + * Probes and loads images from files, memory, and custom I/O sources. */ class SAIL_EXPORT image_input { public: /* - * Constructs a new image input. + * Constructs a new image input from the specified image file. */ - image_input(); + image_input(const std::string &path); /* - * Stops loading if it was started and destroys the image input. - */ - ~image_input(); - - /* - * Starts loading the specified image file. - * - * Typical usage: start() -> - * next_frame() x n -> - * stop(). - * - * Returns SAIL_OK on success. + * Constructs a new image input from the specified memory buffer. */ - sail_status_t start(const std::string &path); + image_input(const void *buffer, std::size_t buffer_length); /* - * Starts loading the specified image file with the specified codec. - * - * Typical usage: codec_info::from_extension() -> - * start() -> - * next_frame() x n -> - * stop(). - * - * Returns SAIL_OK on success. + * Constructs a new image input from the specified memory buffer. */ - sail_status_t start(const std::string &path, const sail::codec_info &codec_info); + image_input(const sail::arbitrary_data &arbitrary_data); /* - * Starts loading the specified image file with the specified load options. - * - * Typical usage: start() -> - * next_frame() x n -> - * stop(). - * - * Returns SAIL_OK on success. - */ - sail_status_t start(const std::string &path, const sail::load_options &load_options); - - /* - * Starts loading the specified image file with the specified codec and load options. - * - * Typical usage: codec_info::from_extension() -> - * start() -> - * next_frame() x n -> - * stop(). - * - * Returns SAIL_OK on success. - */ - sail_status_t start(const std::string &path, const sail::codec_info &codec_info, const sail::load_options &load_options); - - /* - * Starts loading the specified memory buffer. - * - * Typical usage: start() -> - * next_frame() x n -> - * stop(). - * - * Returns SAIL_OK on success. - */ - sail_status_t start(const void *buffer, std::size_t buffer_length); - - /* - * Starts loading the specified memory buffer with the specified codec. - * - * Typical usage: codec_info::from_extension() -> - * start() -> - * next_frame() x n -> - * stop(). - * - * Returns SAIL_OK on success. - */ - sail_status_t start(const void *buffer, std::size_t buffer_length, const sail::codec_info &codec_info); - - /* - * Starts loading the specified memory buffer with the specified load options. - * - * Typical usage: start() -> - * next_frame() x n -> - * stop(). - * - * Returns SAIL_OK on success. - */ - sail_status_t start(const void *buffer, std::size_t buffer_length, const sail::load_options &load_options); - - /* - * Starts loading the specified memory buffer with the specified codec and load options. - * - * Typical usage: codec_info::from_extension() -> - * start() -> - * next_frame() x n -> - * stop(). - * - * Returns SAIL_OK on success. - */ - sail_status_t start(const void *buffer, std::size_t buffer_length, const sail::codec_info &codec_info, const sail::load_options &load_options); - - /* - * Starts loading the specified memory buffer. - * - * Typical usage: start() -> - * next_frame() x n -> - * stop(). - * - * Returns SAIL_OK on success. - */ - sail_status_t start(const sail::arbitrary_data &arbitrary_data); - - /* - * Starts loading the specified memory buffer with the specified codec. - * - * Typical usage: codec_info::from_extension() -> - * start() -> - * next_frame() x n -> - * stop(). - * - * Returns SAIL_OK on success. - */ - sail_status_t start(const sail::arbitrary_data &arbitrary_data, const sail::codec_info &codec_info); - - /* - * Starts loading the specified memory buffer with the specified load options. - * - * Typical usage: start() -> - * next_frame() x n -> - * stop(). - * - * Returns SAIL_OK on success. + * Constructs a new image input from the specified I/O source. */ - sail_status_t start(const sail::arbitrary_data &arbitrary_data, const sail::load_options &load_options); + image_input(sail::abstract_io &abstract_io); /* - * Starts loading the specified memory buffer with the specified codec and load options. - * - * Typical usage: codec_info::from_extension() -> - * start() -> - * next_frame() x n -> - * stop(). - * - * Returns SAIL_OK on success. + * Stops loading if it was started and destroys the image input. */ - sail_status_t start(const sail::arbitrary_data &arbitrary_data, const sail::codec_info &codec_info, const sail::load_options &load_options); + ~image_input(); /* - * Starts loading the specified I/O source. - * - * Typical usage: start() -> - * next_frame() x n -> - * stop(). - * - * Returns SAIL_OK on success. + * Moves the image input. */ - sail_status_t start(sail::abstract_io &abstract_io); + image_input(image_input &&other); /* - * Starts loading the specified I/O source with the specified codec. - * - * Typical usage: codec_info::from_extension() -> - * start() -> - * next_frame() x n -> - * stop(). - * - * Returns SAIL_OK on success. + * Moves the image input. */ - sail_status_t start(sail::abstract_io &abstract_io, const sail::codec_info &codec_info); + image_input& operator=(image_input &&other); /* - * Starts loading the specified I/O source with the specified load options. - * - * Typical usage: start() -> - * next_frame() x n -> - * stop(). - * - * Returns SAIL_OK on success. + * Overrides the automatically detected codec info used to load the image. */ - sail_status_t start(sail::abstract_io &abstract_io, const sail::load_options &load_options); + image_input& with(const sail::codec_info &codec_info); /* - * Starts loading the specified I/O source with the specified codec and load options. - * - * Typical usage: codec_info::from_extension() -> - * start() -> - * next_frame() x n -> - * stop(). - * - * Returns SAIL_OK on success. + * Overrides the load options used to load the image. */ - sail_status_t start(sail::abstract_io &abstract_io, const sail::codec_info &codec_info, const sail::load_options &load_options); + image_input& with(const sail::load_options &load_options); /* - * Continues loading the source started by the previous call to start(). - * Assigns the loaded image to the 'image' argument. + * Continues loading the image. Assigns the loaded image to the 'image' argument. * * Returns SAIL_OK on success. * Returns SAIL_ERROR_NO_MORE_FRAMES when no more frames are available. */ sail_status_t next_frame(sail::image *image); - + /* - * Continues loading the source started by the previous call to start(). + * Continues loading the image. * * Returns an invalid image on error. */ image next_frame(); /* - * Stops loading the source started by the previous call to start(). Does nothing - * if no loading was started. - * - * It is essential to always stop loading to free memory and I/O resources. Failure to do so - * will lead to memory leaks. - * - * Returns SAIL_OK on success. - */ - sail_status_t stop(); - - /* - * Loads the specified image file and returns its properties without pixels and the corresponding + * Loads the image and returns its properties without pixels and the corresponding * codec info. * * This method is pretty fast because it doesn't decode whole image data for most image formats. * * Returns an invalid image on error. */ - static std::tuple probe(const std::string &path); - - /* - * Loads an image from the specified memory buffer and returns its properties without pixels - * and the corresponding codec info. - * - * This method is pretty fast because it doesn't decode whole image data for most image formats. - * - * Returns an invalid image on error. - */ - static std::tuple probe(const void *buffer, std::size_t buffer_length); - - /* - * Loads an image from the specified memory buffer and returns its properties without pixels - * and the corresponding codec info. - * - * This method is pretty fast because it doesn't decode whole image data for most image formats. - * - * Returns an invalid image on error. - */ - static std::tuple probe(const sail::arbitrary_data &arbitrary_data); - - /* - * Loads an image from the specified I/O source and returns its properties without pixels - * and the corresponding codec info. - * - * This method is pretty fast because it doesn't decode whole image data for most image formats. - * - * Returns an invalid image on error. - */ - static std::tuple probe(sail::abstract_io &abstract_io); - - /* - * Loads the specified image file. - * - * Returns an invalid image on error. - */ - static image load(const std::string &path); - - /* - * Loads an image from the specified memory buffer. - * - * Returns an invalid image on error. - */ - static image load(const void *buffer, std::size_t buffer_length); - - /* - * Loads an image from the specified memory buffer. - * - * Returns an invalid image on error. - */ - static image load(const sail::arbitrary_data &arbitrary_data); + std::tuple probe(); private: class pimpl; - const std::unique_ptr d; + std::unique_ptr d; }; } diff --git a/tests/bindings/c++/can-load.cpp b/tests/bindings/c++/can-load.cpp index 04940d89..e4268996 100644 --- a/tests/bindings/c++/can-load.cpp +++ b/tests/bindings/c++/can-load.cpp @@ -51,14 +51,14 @@ static MunitResult test_can_load_memory1(const MunitParameter params[], void *us size_t data_size; munit_assert(sail_file_contents_to_data(path, &data, &data_size) == SAIL_OK); - sail::image_input input; - sail::image image; - const sail::codec_info codec_info = sail::codec_info::from_path(path); munit_assert(codec_info.is_valid()); - munit_assert(input.start(data, data_size, codec_info) == SAIL_OK); - munit_assert(input.next_frame(&image) == SAIL_OK); + sail::image_input input(data, data_size); + input.with(codec_info); + sail::image image; + + munit_assert(input.next_frame(&image) == SAIL_OK); munit_assert(image.is_valid()); sail_free(data); @@ -78,14 +78,14 @@ static MunitResult test_can_load_memory2(const MunitParameter params[], void *us const sail::arbitrary_data arbitrary_data(reinterpret_cast(data), reinterpret_cast(data) + data_size); - sail::image_input input; - sail::image image; - const sail::codec_info codec_info = sail::codec_info::from_path(path); munit_assert(codec_info.is_valid()); - munit_assert(input.start(arbitrary_data, codec_info) == SAIL_OK); - munit_assert(input.next_frame(&image) == SAIL_OK); + sail::image_input input(arbitrary_data); + input.with(codec_info); + sail::image image; + + munit_assert(input.next_frame(&image) == SAIL_OK); munit_assert(image.is_valid()); sail_free(data); @@ -99,11 +99,10 @@ static MunitResult test_can_load_abstract_io_path(const MunitParameter params[], const char *path = munit_parameters_get(params, "path"); - sail::image_input input; sail::io_file io_file(path); + sail::image_input input(io_file); sail::image image; - munit_assert(input.start(io_file) == SAIL_OK); munit_assert(input.next_frame(&image) == SAIL_OK); munit_assert(image.is_valid()); @@ -122,12 +121,12 @@ static MunitResult test_can_load_abstract_io_memory1(const MunitParameter params const sail::codec_info codec_info = sail::codec_info::from_path(path); munit_assert(codec_info.is_valid()); - sail::image_input input; sail::io_memory io_memory(arbitrary_data.data(), arbitrary_data.size()); + sail::image_input input(io_memory); + input.with(codec_info); sail::image image; - munit_assert(input.start(io_memory, codec_info) == SAIL_OK); - munit_assert(input.next_frame(&image) == SAIL_OK); + munit_assert(input.next_frame(&image) == SAIL_OK); munit_assert(image.is_valid()); return MUNIT_OK; @@ -145,12 +144,12 @@ static MunitResult test_can_load_abstract_io_memory2(const MunitParameter params const sail::codec_info codec_info = sail::codec_info::from_path(path); munit_assert(codec_info.is_valid()); - sail::image_input input; sail::io_memory io_memory(arbitrary_data); + sail::image_input input(io_memory); + input.with(codec_info); sail::image image; - munit_assert(input.start(io_memory, codec_info) == SAIL_OK); - munit_assert(input.next_frame(&image) == SAIL_OK); + munit_assert(input.next_frame(&image) == SAIL_OK); munit_assert(image.is_valid()); return MUNIT_OK; @@ -168,12 +167,12 @@ static MunitResult test_can_load_abstract_io_memory3(const MunitParameter params const sail::codec_info codec_info = sail::codec_info::from_path(path); munit_assert(codec_info.is_valid()); - sail::image_input input; sail::io_memory io_memory(arbitrary_data.data(), arbitrary_data.size(), sail::io_memory::Operation::Read); + sail::image_input input(io_memory); + input.with(codec_info); sail::image image; - munit_assert(input.start(io_memory, codec_info) == SAIL_OK); - munit_assert(input.next_frame(&image) == SAIL_OK); + munit_assert(input.next_frame(&image) == SAIL_OK); munit_assert(image.is_valid()); return MUNIT_OK; @@ -191,12 +190,11 @@ static MunitResult test_can_load_abstract_io_memory4(const MunitParameter params const sail::codec_info codec_info = sail::codec_info::from_path(path); munit_assert(codec_info.is_valid()); - sail::image_input input; sail::io_memory io_memory(arbitrary_data, sail::io_memory::Operation::Read); + sail::image_input input = std::move(sail::image_input(io_memory).with(codec_info)); sail::image image; - munit_assert(input.start(io_memory, codec_info) == SAIL_OK); - munit_assert(input.next_frame(&image) == SAIL_OK); + munit_assert(input.next_frame(&image) == SAIL_OK); munit_assert(image.is_valid()); return MUNIT_OK; From 396942a9c19a497685a888689871e87bffa44a6b Mon Sep 17 00:00:00 2001 From: Dmitry Baryshev Date: Sat, 16 Jul 2022 16:54:58 -0700 Subject: [PATCH 2/6] BINDINGS/C++: Update comments --- src/bindings/c++/image_input-c++.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bindings/c++/image_input-c++.h b/src/bindings/c++/image_input-c++.h index e5429dd6..f820c5bc 100644 --- a/src/bindings/c++/image_input-c++.h +++ b/src/bindings/c++/image_input-c++.h @@ -79,7 +79,7 @@ class SAIL_EXPORT image_input image_input(sail::abstract_io &abstract_io); /* - * Stops loading if it was started and destroys the image input. + * Stops loading and destroys the image input. */ ~image_input(); From afdf43d30aba9c9e49ea49477fad07bb3fc3f9a5 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshev Date: Sat, 16 Jul 2022 16:55:05 -0700 Subject: [PATCH 3/6] BINDINGS/C++: Refactor image_output --- .../c++/qt/advanced-with-c++-api/qtsail.cpp | 6 +- src/bindings/c++/image-c++.cpp | 4 +- src/bindings/c++/image_output-c++.cpp | 240 +++++------------- src/bindings/c++/image_output-c++.h | 192 ++------------ 4 files changed, 90 insertions(+), 352 deletions(-) diff --git a/examples/c++/qt/advanced-with-c++-api/qtsail.cpp b/examples/c++/qt/advanced-with-c++-api/qtsail.cpp index 402485c2..80685c6a 100644 --- a/examples/c++/qt/advanced-with-c++-api/qtsail.cpp +++ b/examples/c++/qt/advanced-with-c++-api/qtsail.cpp @@ -135,7 +135,6 @@ sail_status_t QtSail::saveImage(const QString &path, const QImage &qimage) SAIL_LOG_AND_RETURN(SAIL_ERROR_CODEC_NOT_FOUND); } - sail::image_output image_output; sail::image image(const_cast(qimage.bits()), qImageFormatToSailPixelFormat(qimage.format()), qimage.width(), qimage.height(), qimage.bytesPerLine()); // SAIL tries to save an image as is, preserving its pixel format. @@ -158,10 +157,9 @@ sail_status_t QtSail::saveImage(const QString &path, const QImage &qimage) // save_options.tuning()["png-filter"] = std::string("none;sub"); - SAIL_TRY(image_output.start(path.toLocal8Bit().constData(), save_options)); + sail::image_output image_output(path.toLocal8Bit().constData()); + image_output.with(save_options); SAIL_TRY(image_output.next_frame(image)); - // Optional - SAIL_TRY(image_output.stop()); return SAIL_OK; } diff --git a/src/bindings/c++/image-c++.cpp b/src/bindings/c++/image-c++.cpp index a18c2972..f4e527f2 100644 --- a/src/bindings/c++/image-c++.cpp +++ b/src/bindings/c++/image-c++.cpp @@ -315,9 +315,9 @@ sail_status_t image::load(const std::string &path) sail_status_t image::save(const std::string &path) { - image_output output; + image_output output(path); - SAIL_TRY(output.save(path, *this)); + SAIL_TRY(output.next_frame(*this)); return SAIL_OK; } diff --git a/src/bindings/c++/image_output-c++.cpp b/src/bindings/c++/image_output-c++.cpp index dfba3fd1..2d0ef60e 100644 --- a/src/bindings/c++/image_output-c++.cpp +++ b/src/bindings/c++/image_output-c++.cpp @@ -34,218 +34,120 @@ namespace sail class SAIL_HIDDEN image_output::pimpl { public: - pimpl() - : state(nullptr) - , written(0) + pimpl(sail::abstract_io *abstract_io_ext, const sail::codec_info &other_codec_info) + : abstract_io(abstract_io_ext) + , abstract_io_ref(*abstract_io) + , abstract_io_adapter(new sail::abstract_io_adapter(abstract_io_ref)) + , state(nullptr) + , codec_info(other_codec_info) + , override_save_options(false) { } - sail_status_t start() + pimpl(sail::abstract_io &abstract_io_ext, const sail::codec_info &other_codec_info) + : abstract_io() + , abstract_io_ref(abstract_io_ext) + , abstract_io_adapter(new sail::abstract_io_adapter(abstract_io_ref)) + , state(nullptr) + , codec_info(other_codec_info) + , override_save_options(false) { - SAIL_TRY(ensure_not_started()); - - written = 0; - - return SAIL_OK; } - void *state; - std::unique_ptr abstract_io_adapter; - std::size_t written; + sail_status_t start(); private: - sail_status_t ensure_not_started() - { - if (state != nullptr) { - SAIL_LOG_ERROR("Saving operation is in progress. Stop it before starting a new one"); - return SAIL_ERROR_CONFLICTING_OPERATION; - } - - return SAIL_OK; - } -}; - -image_output::image_output() - : d(new pimpl) -{ -} - -image_output::~image_output() -{ - stop(); -} - -sail_status_t image_output::start(const std::string &path) -{ - SAIL_TRY(d->start()); - - SAIL_TRY(sail_start_saving_into_file(path.c_str(), nullptr, &d->state)); - - return SAIL_OK; -} + const std::unique_ptr abstract_io; + sail::abstract_io &abstract_io_ref; -sail_status_t image_output::start(const std::string &path, const sail::codec_info &codec_info) -{ - SAIL_TRY(d->start()); - - SAIL_TRY(sail_start_saving_into_file(path.c_str(), codec_info.sail_codec_info_c(), &d->state)); +public: + const std::unique_ptr abstract_io_adapter; + void *state; - return SAIL_OK; -} + sail::codec_info codec_info; + bool override_save_options; + sail::save_options save_options; +}; -sail_status_t image_output::start(const std::string &path, const sail::save_options &save_options) +sail_status_t image_output::pimpl::start() { - SAIL_TRY(d->start()); - - sail_save_options *sail_save_options; - SAIL_TRY(save_options.to_sail_save_options(&sail_save_options)); + const sail_codec_info *sail_codec_info = codec_info.sail_codec_info_c(); - SAIL_TRY_OR_CLEANUP(sail_start_saving_into_file_with_options(path.c_str(), nullptr, sail_save_options, &d->state), - /* cleanup */ sail_destroy_save_options(sail_save_options)); + sail_save_options *sail_save_options = nullptr; - sail_destroy_save_options(sail_save_options); - - return SAIL_OK; -} - -sail_status_t image_output::start(const std::string &path, const sail::codec_info &codec_info, const sail::save_options &save_options) -{ - SAIL_TRY(d->start()); - - sail_save_options *sail_save_options; - SAIL_TRY(save_options.to_sail_save_options(&sail_save_options)); + SAIL_AT_SCOPE_EXIT( + sail_destroy_save_options(sail_save_options); + ); - SAIL_TRY_OR_CLEANUP(sail_start_saving_into_file_with_options(path.c_str(), codec_info.sail_codec_info_c(), sail_save_options, &d->state), - /* cleanup */ sail_destroy_save_options(sail_save_options)); + if (override_save_options) { + SAIL_TRY(save_options.to_sail_save_options(&sail_save_options)); + } - sail_destroy_save_options(sail_save_options); + SAIL_TRY(sail_start_saving_into_io_with_options(&abstract_io_adapter->sail_io_c(), sail_codec_info, sail_save_options, &state)); return SAIL_OK; } -sail_status_t image_output::start(void *buffer, std::size_t buffer_length, const sail::codec_info &codec_info) +image_output::image_output(const std::string &path) + : d(new pimpl(new io_file(path, io_file::Operation::ReadWrite), sail::codec_info::from_path(path))) { - SAIL_TRY(d->start()); - - SAIL_TRY(sail_start_saving_into_memory(buffer, buffer_length, codec_info.sail_codec_info_c(), &d->state)); - - return SAIL_OK; } -sail_status_t image_output::start(void *buffer, std::size_t buffer_length, const sail::codec_info &codec_info, const sail::save_options &save_options) +image_output::image_output(void *buffer, std::size_t buffer_length, const sail::codec_info &codec_info) + : d(new pimpl(new io_memory(buffer, buffer_length), codec_info)) { - SAIL_TRY(d->start()); - - sail_save_options *sail_save_options; - SAIL_TRY(save_options.to_sail_save_options(&sail_save_options)); - - SAIL_TRY_OR_CLEANUP(sail_start_saving_into_memory_with_options(buffer, buffer_length, codec_info.sail_codec_info_c(), sail_save_options, &d->state), - /* cleanup */ sail_destroy_save_options(sail_save_options)); - - sail_destroy_save_options(sail_save_options); - - return SAIL_OK; } -sail_status_t image_output::start(sail::arbitrary_data *arbitrary_data, const sail::codec_info &codec_info) +image_output::image_output(sail::arbitrary_data *arbitrary_data, const sail::codec_info &codec_info) + : image_output(arbitrary_data->data(), arbitrary_data->size(), codec_info) { - SAIL_TRY(start(arbitrary_data->data(), arbitrary_data->size(), codec_info)); - - return SAIL_OK; } -sail_status_t image_output::start(sail::arbitrary_data *arbitrary_data, const sail::codec_info &codec_info, const sail::save_options &save_options) +image_output::image_output(sail::abstract_io &abstract_io, const sail::codec_info &codec_info) + : d(new pimpl(abstract_io, codec_info)) { - SAIL_TRY(start(arbitrary_data->data(), arbitrary_data->size(), codec_info, save_options)); - - return SAIL_OK; } -sail_status_t image_output::start(sail::abstract_io &abstract_io, const sail::codec_info &codec_info) -{ - SAIL_TRY(d->start()); - - d->abstract_io_adapter.reset(new sail::abstract_io_adapter(abstract_io)); - - SAIL_TRY(sail_start_saving_into_io_with_options(&d->abstract_io_adapter->sail_io_c(), codec_info.sail_codec_info_c(), nullptr, &d->state)); - - return SAIL_OK; -} - -sail_status_t image_output::start(sail::abstract_io &abstract_io, const sail::codec_info &codec_info, const sail::save_options &save_options) +image_output::~image_output() { - SAIL_TRY(d->start()); - - d->abstract_io_adapter.reset(new sail::abstract_io_adapter(abstract_io)); - - sail_save_options *sail_save_options; - SAIL_TRY(save_options.to_sail_save_options(&sail_save_options)); - - SAIL_TRY_OR_CLEANUP(sail_start_saving_into_io_with_options(&d->abstract_io_adapter->sail_io_c(), codec_info.sail_codec_info_c(), sail_save_options, &d->state), - /* cleanup */ sail_destroy_save_options(sail_save_options)); - - sail_destroy_save_options(sail_save_options); - - return SAIL_OK; + if (d) { + SAIL_TRY_OR_SUPPRESS(sail_stop_saving(d->state)); + } } -sail_status_t image_output::next_frame(const sail::image &image) const +image_output::image_output(image_output &&other) { - sail_image *sail_image = nullptr; - SAIL_TRY(image.to_sail_image(&sail_image)); - - SAIL_AT_SCOPE_EXIT( - sail_image->pixels = nullptr; - sail_destroy_image(sail_image); - ); - - SAIL_TRY(sail_write_next_frame(d->state, sail_image)); - - return SAIL_OK; + *this = std::move(other); } -sail_status_t image_output::stop() +image_output& image_output::operator=(image_output &&other) { - sail_status_t saved_status = SAIL_OK; - SAIL_TRY_OR_EXECUTE(sail_stop_saving_with_written(d->state, &d->written), - /* on error */ saved_status = __sail_error_result); - - d->state = nullptr; - d->abstract_io_adapter.reset(); + d = std::move(other.d); + other.d = {}; - return saved_status; + return *this; } -std::size_t image_output::written() const +image_output& image_output::with(const sail::codec_info &codec_info) { - return d->written; -} + d->codec_info = codec_info; -sail_status_t image_output::save(const std::string &path, const sail::image &image) -{ - sail_image *sail_image = nullptr; - SAIL_TRY(image.to_sail_image(&sail_image)); - - SAIL_AT_SCOPE_EXIT( - sail_image->pixels = nullptr; - sail_destroy_image(sail_image); - ); - - SAIL_TRY(sail_save_into_file(path.c_str(), sail_image)); - - return SAIL_OK; + return *this; } -sail_status_t image_output::save(void *buffer, std::size_t buffer_length, const sail::image &image) +image_output& image_output::with(const sail::save_options &save_options) { - SAIL_TRY(save(buffer, buffer_length, image, nullptr)); + d->override_save_options = true; + d->save_options = save_options; - return SAIL_OK; + return *this; } -sail_status_t image_output::save(void *buffer, std::size_t buffer_length, const sail::image &image, std::size_t *written) +sail_status_t image_output::next_frame(const sail::image &image) const { - SAIL_CHECK_PTR(buffer); + if (d->state == nullptr) { + SAIL_TRY(d->start()); + } sail_image *sail_image = nullptr; SAIL_TRY(image.to_sail_image(&sail_image)); @@ -255,21 +157,7 @@ sail_status_t image_output::save(void *buffer, std::size_t buffer_length, const sail_destroy_image(sail_image); ); - SAIL_TRY(sail_save_into_memory(buffer, buffer_length, sail_image, written)); - - return SAIL_OK; -} - -sail_status_t image_output::save(sail::arbitrary_data *arbitrary_data, const sail::image &image) -{ - SAIL_TRY(save(arbitrary_data->data(), arbitrary_data->size(), image)); - - return SAIL_OK; -} - -sail_status_t image_output::save(sail::arbitrary_data *arbitrary_data, const sail::image &image, std::size_t *written) -{ - SAIL_TRY(save(arbitrary_data->data(), arbitrary_data->size(), image, written)); + SAIL_TRY(sail_write_next_frame(d->state, sail_image)); return SAIL_OK; } diff --git a/src/bindings/c++/image_output-c++.h b/src/bindings/c++/image_output-c++.h index d077f49a..434e422a 100644 --- a/src/bindings/c++/image_output-c++.h +++ b/src/bindings/c++/image_output-c++.h @@ -51,141 +51,59 @@ class image; class save_options; /* - * Class to save images into files, memory, and custom I/O targets. + * Saves images to files, memory, and custom I/O targets. */ class SAIL_EXPORT image_output { public: /* - * Constructs a new image output. + * Constructs a new image output to the specified image file. + * Detects the image format based on the file extension. */ - image_output(); + image_output(const std::string &path); /* - * Stops saving if it was started and destroys the image output. + * Constructs a new image output to the specified memory buffer. */ - ~image_output(); - - /* - * Starts saving into the specified image file. - * - * Typical usage: start() -> - * next_frame() x n -> - * stop(). - * - * Returns SAIL_OK on success. - */ - sail_status_t start(const std::string &path); + image_output(void *buffer, std::size_t buffer_length, const sail::codec_info &codec_info); /* - * Starts saving into the specified image file with the specified codec. - * - * Typical usage: codec_info::from_extension() -> - * start() -> - * next_frame() x n -> - * stop(). - * - * Returns SAIL_OK on success. + * Constructs a new image output to the specified memory buffer. */ - sail_status_t start(const std::string &path, const sail::codec_info &codec_info); + image_output(sail::arbitrary_data *arbitrary_data, const sail::codec_info &codec_info); /* - * Starts saving into the specified image file with the specified save options. - * - * Typical usage: start() -> - * next_frame() x n -> - * stop(). - * - * Returns SAIL_OK on success. - */ - sail_status_t start(const std::string &path, const sail::save_options &save_options); - - /* - * Starts saving into the specified image file with the specified codec and save options. - * - * Typical usage: codec_info::from_extension() -> - * start() -> - * next_frame() x n -> - * stop(). - * - * Returns SAIL_OK on success. - */ - sail_status_t start(const std::string &path, const sail::codec_info &codec_info, const sail::save_options &save_options); - - /* - * Starts saving into the specified memory buffer with the specified codec. - * - * Typical usage: codec_info::from_extension() -> - * start() -> - * next_frame() x n -> - * stop(). - * - * Returns SAIL_OK on success. + * Constructs a new image output to the specified I/O source. */ - sail_status_t start(void *buffer, std::size_t buffer_length, const sail::codec_info &codec_info); + image_output(sail::abstract_io &abstract_io, const sail::codec_info &codec_info); /* - * Starts saving into the specified memory buffer with the specified codec and save options. - * - * Typical usage: codec_info::from_extension() -> - * start() -> - * next_frame() x n -> - * stop(). - * - * Returns SAIL_OK on success. + * Stops saving and destroys the image output. */ - sail_status_t start(void *buffer, std::size_t buffer_length, const sail::codec_info &codec_info, const sail::save_options &save_options); + ~image_output(); /* - * Starts saving into the specified memory buffer with the specified codec. - * - * Typical usage: codec_info::from_extension() -> - * start() -> - * next_frame() x n -> - * stop(). - * - * Returns SAIL_OK on success. + * Moves the image output. */ - sail_status_t start(sail::arbitrary_data *arbitrary_data, const sail::codec_info &codec_info); + image_output(image_output &&other); /* - * Starts saving into the specified memory buffer with the specified codec and save options. - * - * Typical usage: codec_info::from_extension() -> - * start() -> - * next_frame() x n -> - * stop(). - * - * Returns SAIL_OK on success. + * Moves the image output. */ - sail_status_t start(sail::arbitrary_data *arbitrary_data, const sail::codec_info &codec_info, const sail::save_options &save_options); + image_output& operator=(image_output &&other); /* - * Starts saving into the specified I/O target with the specified codec. - * - * Typical usage: codec_info::from_extension() -> - * start() -> - * next_frame() x n -> - * stop(). - * - * Returns SAIL_OK on success. + * Overrides the automatically detected codec info used to save the image. */ - sail_status_t start(sail::abstract_io &abstract_io, const sail::codec_info &codec_info); + image_output& with(const sail::codec_info &codec_info); /* - * Starts saving into the specified I/O target with the specified codec and save options. - * - * Typical usage: codec_info::from_extension() -> - * start() -> - * next_frame() x n -> - * stop(). - * - * Returns SAIL_OK on success. + * Overrides the save options used to save the image. */ - sail_status_t start(sail::abstract_io &abstract_io, const sail::codec_info &codec_info, const sail::save_options &save_options); + image_output& with(const sail::save_options &save_options); /* - * Continues saving started by start(). Saves the specified image into the underlying I/O target. + * Continues saving into the I/O target. * * If the selected image format doesn't support the image pixel format, an error is returned. * Consider converting the image into a supported image format beforehand. @@ -194,75 +112,9 @@ class SAIL_EXPORT image_output */ sail_status_t next_frame(const sail::image &image) const; - /* - * Stops saving started by the previous call to start() and closes the underlying I/O target. - * - * Returns SAIL_OK on success. - */ - sail_status_t stop(); - - /* - * Returns the number of bytes written by the last stop() operation. - */ - std::size_t written() const; - - /* - * Saves the specified image into the file. - * - * If the selected image format doesn't support the image pixel format, an error is returned. - * Consider converting the image into a supported image format beforehand. - * - * Returns SAIL_OK on success. - */ - static sail_status_t save(const std::string &path, const sail::image &image); - - /* - * Saves the specified image into the specified memory buffer. - * - * If the selected image format doesn't support the image pixel format, an error is returned. - * Consider converting the image into a supported image format beforehand. - * - * Returns SAIL_OK on success. - */ - static sail_status_t save(void *buffer, std::size_t buffer_length, const sail::image &image); - - /* - * Saves the specified image into the specified memory buffer. - * - * If the selected image format doesn't support the image pixel format, an error is returned. - * Consider converting the image into a supported image format beforehand. - * - * Saves the number of bytes written into the 'written' argument if it's not nullptr. - * - * Returns SAIL_OK on success. - */ - static sail_status_t save(void *buffer, std::size_t buffer_length, const sail::image &image, std::size_t *written); - - /* - * Saves the specified image into the specified memory buffer. - * - * If the selected image format doesn't support the image pixel format, an error is returned. - * Consider converting the image into a supported image format beforehand. - * - * Returns SAIL_OK on success. - */ - static sail_status_t save(sail::arbitrary_data *arbitrary_data, const sail::image &image); - - /* - * Saves the specified image into the specified memory buffer. - * - * If the selected image format doesn't support the image pixel format, an error is returned. - * Consider converting the image into a supported image format beforehand. - * - * Saves the number of bytes written into the 'written' argument if it's not nullptr. - * - * Returns SAIL_OK on success. - */ - static sail_status_t save(sail::arbitrary_data *arbitrary_data, const sail::image &image, std::size_t *written); - private: class pimpl; - const std::unique_ptr d; + std::unique_ptr d; }; } From 7b654520eea19156b5d7c5c834118b7105d0565d Mon Sep 17 00:00:00 2001 From: Dmitry Baryshev Date: Sat, 16 Jul 2022 16:59:33 -0700 Subject: [PATCH 4/6] BINDINGS/C++: Added explicit --- src/bindings/c++/image_input-c++.h | 6 +++--- src/bindings/c++/image_output-c++.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/bindings/c++/image_input-c++.h b/src/bindings/c++/image_input-c++.h index f820c5bc..b90f4ffe 100644 --- a/src/bindings/c++/image_input-c++.h +++ b/src/bindings/c++/image_input-c++.h @@ -61,7 +61,7 @@ class SAIL_EXPORT image_input /* * Constructs a new image input from the specified image file. */ - image_input(const std::string &path); + explicit image_input(const std::string &path); /* * Constructs a new image input from the specified memory buffer. @@ -71,12 +71,12 @@ class SAIL_EXPORT image_input /* * Constructs a new image input from the specified memory buffer. */ - image_input(const sail::arbitrary_data &arbitrary_data); + explicit image_input(const sail::arbitrary_data &arbitrary_data); /* * Constructs a new image input from the specified I/O source. */ - image_input(sail::abstract_io &abstract_io); + explicit image_input(sail::abstract_io &abstract_io); /* * Stops loading and destroys the image input. diff --git a/src/bindings/c++/image_output-c++.h b/src/bindings/c++/image_output-c++.h index 434e422a..68859699 100644 --- a/src/bindings/c++/image_output-c++.h +++ b/src/bindings/c++/image_output-c++.h @@ -60,7 +60,7 @@ class SAIL_EXPORT image_output * Constructs a new image output to the specified image file. * Detects the image format based on the file extension. */ - image_output(const std::string &path); + explicit image_output(const std::string &path); /* * Constructs a new image output to the specified memory buffer. From 53b87f36c3cff039f992326a099d8146f7cd7a44 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshev Date: Sat, 16 Jul 2022 17:02:18 -0700 Subject: [PATCH 5/6] BINDINGS/C++: Added explicit to io_memory --- src/bindings/c++/io_memory-c++.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/bindings/c++/io_memory-c++.h b/src/bindings/c++/io_memory-c++.h index c385d2fa..54f9bf7d 100644 --- a/src/bindings/c++/io_memory-c++.h +++ b/src/bindings/c++/io_memory-c++.h @@ -63,12 +63,12 @@ class SAIL_EXPORT io_memory : public io_base /* * Opens the specified memory buffer for reading and writing. */ - io_memory(sail::arbitrary_data &arbitrary_data); + explicit io_memory(sail::arbitrary_data &arbitrary_data); /* * Opens the specified memory buffer for reading. */ - io_memory(const sail::arbitrary_data &arbitrary_data); + explicit io_memory(const sail::arbitrary_data &arbitrary_data); /* * Opens the specified memory buffer for the specified I/O operations. From 4a509c9b273512dbc5fccb463909e9c045957b54 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshev Date: Sun, 17 Jul 2022 10:51:35 -0700 Subject: [PATCH 6/6] BINDINGS/C++: Make image_output::next_frame() non-const --- src/bindings/c++/image_output-c++.cpp | 2 +- src/bindings/c++/image_output-c++.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/bindings/c++/image_output-c++.cpp b/src/bindings/c++/image_output-c++.cpp index 2d0ef60e..08be925c 100644 --- a/src/bindings/c++/image_output-c++.cpp +++ b/src/bindings/c++/image_output-c++.cpp @@ -143,7 +143,7 @@ image_output& image_output::with(const sail::save_options &save_options) return *this; } -sail_status_t image_output::next_frame(const sail::image &image) const +sail_status_t image_output::next_frame(const sail::image &image) { if (d->state == nullptr) { SAIL_TRY(d->start()); diff --git a/src/bindings/c++/image_output-c++.h b/src/bindings/c++/image_output-c++.h index 68859699..18ab54d4 100644 --- a/src/bindings/c++/image_output-c++.h +++ b/src/bindings/c++/image_output-c++.h @@ -110,7 +110,7 @@ class SAIL_EXPORT image_output * * Returns SAIL_OK on success. */ - sail_status_t next_frame(const sail::image &image) const; + sail_status_t next_frame(const sail::image &image); private: class pimpl;