File: writer.hpp

package info (click to toggle)
sight 25.1.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 43,252 kB
  • sloc: cpp: 310,629; xml: 17,622; ansic: 9,960; python: 1,379; sh: 144; makefile: 33
file content (162 lines) | stat: -rw-r--r-- 7,182 bytes parent folder | download | duplicates (2)
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