SlideIO 2.0.0
Open-source library for reading of medical images
Loading...
Searching...
No Matches
tiffconverter.hpp
1// This file is part of slideio project.
2// It is subject to the license terms in the LICENSE file found in the top-level directory
3// of this distribution and at http://slideio.com/license.html.
4#pragma once
5#include "slideio/converter/converter_def.hpp"
6#include "slideio/imagetools/tiffkeeper.hpp"
7#include "slideio/converter/converterparameters.hpp"
8#include "slideio/converter/tiffstructure.hpp"
9#include "slideio/core/tools/boundedqueue.hpp"
10#include <mutex>
11#include <chrono>
12#include <atomic>
13
14#include "slideio/core/cvslide.hpp"
15
16namespace slideio
17{
18 class Slide;
19 class Scene;
20 class CVScene;
21
22 namespace converter
23 {
24 class ConverterParameters;
25
26 class SLIDEIO_CONVERTER_EXPORTS TiffConverter
27 {
28 public:
29 TiffConverter() = default;
30 TiffConverter(const TiffConverter& other)
31 : m_pages(other.m_pages)
32 , m_file(other.m_file)
33 , m_scene(other.m_scene)
34 , m_parameters(other.m_parameters)
35 , m_cropRect(other.m_cropRect)
36 , m_filePath(other.m_filePath)
37 , m_totalTiles(other.m_totalTiles)
38 , m_currentTile(other.m_currentTile)
39 , m_lastProgress(other.m_lastProgress)
40 , m_readersIdleTimeNs(other.m_readersIdleTimeNs.load())
41 , m_encodersIdleTimeNs(other.m_encodersIdleTimeNs.load())
42 , m_writerIdleTimeNs(other.m_writerIdleTimeNs.load())
43 , m_numReaderThreads(other.m_numReaderThreads)
44 , m_numEncoderThreads(other.m_numEncoderThreads) {}
45 TiffConverter& operator=(const TiffConverter& other) {
46 if (this != &other) {
47 m_pages = other.m_pages;
48 m_file = other.m_file;
49 m_scene = other.m_scene;
50 m_parameters = other.m_parameters;
51 m_cropRect = other.m_cropRect;
52 m_filePath = other.m_filePath;
53 m_totalTiles = other.m_totalTiles;
54 m_currentTile = other.m_currentTile;
55 m_lastProgress = other.m_lastProgress;
56 m_readersIdleTimeNs.store(other.m_readersIdleTimeNs.load());
57 m_encodersIdleTimeNs.store(other.m_encodersIdleTimeNs.load());
58 m_writerIdleTimeNs.store(other.m_writerIdleTimeNs.load());
59 m_numReaderThreads = other.m_numReaderThreads;
60 m_numEncoderThreads = other.m_numEncoderThreads;
61 }
62 return *this;
63 }
64 TiffConverter(TiffConverter&&) = default;
65 TiffConverter& operator=(TiffConverter&&) = default;
66
67 struct Block {
68 cv::Rect rect; // Block rectangle in the source image
69 size_t firstTileSequenceId; // Preserves original read order
70 };
71 struct Tile {
72 size_t sequenceId; // Preserves original read order
73 cv::Mat raster; // Tile pixel data
74 cv::Point2i location; // Location of the tile in the target image
75 };
76 struct EncodedTile {
77 size_t sequenceId; // Preserves original read order
78 std::vector<uint8_t> encodedData; // Encoded tile data
79 cv::Point2i location; // Location of the tile in the target image
80 };
81 public:
82 void createFileLayout(const std::shared_ptr<CVScene>& scene, const ConverterParameters& parameters);
83 void createTiff(const std::string& filePath, const std::function<void(int)>& cb, int tileBatchSize);
84 int getNumTiffPages() const {
85 return static_cast<int>(m_pages.size());
86 }
87
88 const TiffPageStructure& getTiffPage(int index) const;
89 Rect getSceneRect() const {
90 return m_cropRect;
91 }
92
93 int getTotalTiles() const {
94 return m_totalTiles;
95 }
96
97 const ConverterParameters& getParameters() const {
98 return m_parameters;
99 }
100 std::chrono::nanoseconds getReadersIdleTime() const {
101 return std::chrono::nanoseconds(m_readersIdleTimeNs.load());
102 }
103 std::chrono::nanoseconds getEncodersIdleTime() const {
104 return std::chrono::nanoseconds(m_encodersIdleTimeNs.load());
105 }
106 std::chrono::nanoseconds getWriterIdleTime() const {
107 return std::chrono::nanoseconds(m_writerIdleTimeNs.load());
108 }
109 int getNumReaderThreads() const {
110 return m_numReaderThreads;
111 }
112 int getNumEncoderThreads() const {
113 return m_numEncoderThreads;
114 }
115 int getNumWriterThreads() const {
116 return 1;
117 }
118 void createTileQueue(const TiffDirectory& dir, const TiffDirectoryStructure& page, int tileBatchSize, std::queue<Block>& queue);
119 virtual std::pair<std::shared_ptr<Slide>, std::shared_ptr<Scene>> cloneScene() const;
120 protected:
121 std::shared_ptr<CVScene> getScene() const {
122 return m_scene;
123 }
124 private:
125 TiffPageStructure& appendPage() {
126 return m_pages.emplace_back();
127 }
128 DataType getChannelRangeDataType(const Range& channelRange) const;
129 int computeChannelChunk(int firstChannel, const std::shared_ptr<CVScene>& scene) const;
130 std::string createSVSImageDescription() const;
131 std::string createImageDescriptionTag() const;
132 std::string createOMETiffDescription() const;
133 TiffDirectory setUpDirectory(const TiffDirectoryStructure& page);
134 void writeDirectoryData(TiffDirectory& dir, const TiffDirectoryStructure& page,
135 const std::function<void(int)>& cb, int param);
136 void writeDirectoryDataST(TiffDirectory& dir, const TiffDirectoryStructure& page,
137 const std::function<void(int)>& cb, int tileBatchSize);
138 void writeDirectoryDataMT(TiffDirectory& dir, const TiffDirectoryStructure& page,
139 const std::function<void(int)>& cb, int tileBatchSize);
140 void computeCropRect();
141 void makeSureValid() const;
142 static std::string SVSDateString();
143 static std::string SVSTimeString();
144 void checkSVSRequirements() const;
145 void checkJpegRequirements() const;
146 void checkEncodingRequirements() const;
147 void checkContainerRequirements() const;
148 void updateNotDefinedParameters();
149 // --- Multithreaded conversion helpers ---
150 void readTiles(const TiffDirectory& dir, const TiffDirectoryStructure& page, BoundedQueue<Tile>& inputQueue,
151 std::queue<Block>& blockQueue, std::mutex& blockQueueMutex, std::atomic<size_t>& activeReaders,
152 std::exception_ptr& readerException, std::mutex& exceptionMutex);
153 void encodeTiles(BoundedQueue<Tile>& inputQueue, BoundedQueue<EncodedTile>& outputQueue,
154 std::atomic<size_t>& activeEncoders, std::exception_ptr& encoderException, std::mutex& exceptionMutex);
155 void writeTile(const EncodedTile& tile);
156 void writeTiles(BoundedQueue<Tile>& inputQueue, BoundedQueue<EncodedTile>& outputQueue, const std::function<void(int)>& cb,
157 std::exception_ptr& writerException, std::mutex& exceptionMutex);
158 std::vector<uint8_t> encodeTile(const cv::Mat& tile);
159 private:
160 std::vector<TiffPageStructure> m_pages;
161 TIFFKeeperPtr m_file;
162 std::shared_ptr<CVScene> m_scene;
163 ConverterParameters m_parameters;
164 Rect m_cropRect;
165 std::string m_filePath;
166 int m_totalTiles = 0;
167 int m_currentTile = 0;
168 int m_lastProgress = 0;
169 std::atomic<int64_t> m_readersIdleTimeNs{0};
170 std::atomic<int64_t> m_encodersIdleTimeNs{0};
171 std::atomic<int64_t> m_writerIdleTimeNs{0};
172 int m_numReaderThreads = 0;
173 int m_numEncoderThreads = 0;
174 };
175 }
176}
Definition: exceptions.hpp:15