1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162
|
/************************************************************************
*
* Copyright (C) 2023-2024 IRCAD France
*
* This file is part of Sight.
*
* Sight is free software: you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Sight is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with Sight. If not, see <https://www.gnu.org/licenses/>.
*
***********************************************************************/
#pragma once
#include <sight/io/bitmap/config.hpp>
#include "backend.hpp"
#include <core/location/single_file.hpp>
#include <core/tools/progress_adviser.hpp>
#include <data/image.hpp>
#include <io/__/writer/generic_object_writer.hpp>
#include <ostream>
// cspell:ignore nvjpeg LIBJPEG OPENJPEG
namespace sight::io::bitmap::detail
{
class writer_impl;
}
namespace sight::io::bitmap
{
/**
* @brief Fast generic bitmap writer. It supports JPEG2000, JPEG, PNG and TIFF format.
*
* If a NVIDIA GPU is available and the support has been compiled in, NVidia nvJPEG / nvJPEG2000 library is used to
* achieve very fast encoding. Otherwise, libjpeg-turbo, openJPEG, libtiff or libPNG are used as fallback.
* The performance should still be better than VTK or even OpenCV because of direct API calls and avoided unneeded
* buffer copy.
*
* Some backends have a FAST and a BEST mode. FAST compress faster and BEST compress better, at the expanse of the
* speed. For lossy codecs, the configuration will always provide the maximum possible quality, which may reduce
* compression.
*
* For lossless mode, TIFF "BEST" currently provide the best mix between speed and compression ratio (350 FPS), while
* "FAST" mode is the fastest backend, but does not compress very well data (450 FPS).
*
* When a GPU is available, nothing beats the speed of nvJPEG (>1300 FPS) while preserving "visually" lossless quality.
* On the contrary, nvJPEG2000 is fully lossless and provides a very good compression ratio, but is, of course, slower
* (still 60 fps guaranteed on nowadays computers).
*/
class SIGHT_IO_BITMAP_CLASS_API writer final : public io::writer::generic_object_writer<data::image>,
public core::location::single_file,
public core::tools::progress_adviser
{
public:
enum class mode : std::uint8_t
{
fast = 1,
best = 2
};
SIGHT_DECLARE_CLASS(writer, io::writer::generic_object_writer<data::image>);
SIGHT_ALLOW_SHARED_FROM_THIS();
/// Delete default constructors and assignment operators
writer(const writer&) = delete;
writer(writer&&) = delete;
writer& operator=(const writer&) = delete;
writer& operator=(writer&&) = delete;
/// Constructor/Destructor
SIGHT_IO_BITMAP_API writer();
SIGHT_IO_BITMAP_API ~writer() override;
/// Main writing method from generic_object_writer
SIGHT_IO_BITMAP_API void write() override;
/// Specialized writing method that allows to specify the backend and the mode (Fast or Best compression)
/// @arg backend: the backend to use. Can be LIBJPEG, LIBTIFF, LIBPNG, OPENJPEG or, if available, NVJPEG and
/// NVJPEG2K. DEFAULT is LIBTIFF and ANY will guess using the file extension. "*J2K" variant are
/// JPEG2000 "stream", without normal meta-data and is only useful for DICOM
/// @arg mode: The mode to use. Can be FAST or BEST. FAST emphasise speed and BEST emphasise file size
SIGHT_IO_BITMAP_API std::size_t write(backend _backend, mode _mode = mode::fast);
/// Specialized writing method that allows to write to a ostream
/// @arg ostream: the stream to write to. It is up to the user to open it.
/// @arg backend: the backend to use. Can be LIBJPEG, LIBTIFF, LIBPNG, OPENJPEG or, if available, NVJPEG and
/// NVJPEG2K. DEFAULT is LIBTIFF. "*_J2K" variant are
/// JPEG2000 "stream", without normal meta-data and is only useful for DICOM
/// @arg mode: The mode to use. Can be FAST or BEST. FAST emphasise speed and BEST emphasise file size
SIGHT_IO_BITMAP_API std::size_t write(
std::ostream& _ostream,
backend _backend = backend::libtiff,
mode _mode = mode::fast
);
/// Specialized writing method that allows to write to a std::uint8_t* buffer
/// @arg buffer: the buffer to write to. It will be allocated.
/// @arg backend: the backend to use. Can be LIBJPEG, LIBTIFF, LIBPNG, OPENJPEG or, if available, NVJPEG and
/// NVJPEG2K. DEFAULT is LIBTIFF. "*_J2K" variant are
/// JPEG2000 "stream", without normal meta-data and is only useful for DICOM
/// @arg mode: The mode to use. Can be FAST or BEST. FAST emphasise speed and BEST emphasise file size
SIGHT_IO_BITMAP_API std::size_t write(
std::uint8_t** _buffer,
backend _backend = backend::libtiff,
mode _mode = mode::fast
);
/// Specialized writing method that allows to write to a std::uint8_t* buffer
/// @arg buffer: the buffer to write to. It is up to the user to allocate it (1.5x input size should be enough).
/// @arg backend: the backend to use. Can be LIBJPEG, LIBTIFF, LIBPNG, OPENJPEG or, if available, NVJPEG and
/// NVJPEG2K. DEFAULT is LIBTIFF. "*_J2K" variant are
/// JPEG2000 "stream", without normal meta-data and is only useful for DICOM
/// @arg mode: The mode to use. Can be FAST or BEST. FAST emphasise speed and BEST emphasise file size
SIGHT_IO_BITMAP_API std::size_t write(
std::uint8_t* _buffer,
backend _backend = backend::libtiff,
mode _mode = mode::fast
);
/// Specialized writing method that allows to write to a std::uint8_t* buffer
/// @arg buffer: the buffer to write to. It will be resized if it is not big enough.
/// @arg backend: the backend to use. Can be LIBJPEG, LIBTIFF, LIBPNG, OPENJPEG or, if available, NVJPEG and
/// NVJPEG2K. DEFAULT is LIBTIFF. "*_J2K" variant are
/// JPEG2000 "stream", without normal meta-data and is only useful for DICOM
/// @arg mode: The mode to use. Can be FAST or BEST. FAST emphasise speed and BEST emphasise file size
SIGHT_IO_BITMAP_API std::size_t write(
std::vector<uint8_t>& _buffer,
backend _backend = backend::libtiff,
mode _mode = mode::fast
);
/// Return the extension to use, by default, or the one from file set by single_file::set_file(), if valid
/// @return an extension as string
[[nodiscard]] SIGHT_IO_BITMAP_API std::string extension() const override;
private:
/// PImpl
std::unique_ptr<detail::writer_impl> m_pimpl;
};
} // namespace sight::io::bitmap
|