SlideIO 2.9.0
Open-source library for reading of medical images
Loading...
Searching...
No Matches
tiffkeeper.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
5#pragma once
6#include <string>
7#include <memory>
8#include <cstdint>
9
10#include "tifftools.hpp"
11#include "slideio/imagetools/slideio_imagetools_def.hpp"
12#include "slideio/imagetools/imagetools.hpp"
13
14namespace libtiff
15{
16 struct tiff;
17 typedef tiff TIFF;
18}
19
20namespace slideio
21{
22 class TIFFMessageHandler;
23
24 // Both constructors install a TIFFMessageHandler, which swaps libtiff's
25 // PROCESS-GLOBAL error and warning handlers for the keeper's lifetime and restores
26 // them on destruction. Move assignment deliberately keeps the destination's own
27 // handler rather than taking the source's (see the .cpp), so the one remaining
28 // hazard is keepers whose lifetimes overlap out of order: with overlapping,
29 // non-LIFO keeper lifetimes, one destructor can restore a handler while another
30 // keeper is still alive, after which libtiff messages go to stderr instead of the
31 // log. There is no dangling pointer -- both handlers are static functions -- so the
32 // consequence is lost log routing, not a crash.
33 class SLIDEIO_IMAGETOOLS_EXPORTS TIFFKeeper
34 {
35 public:
36 explicit TIFFKeeper(libtiff::TIFF* hFile = nullptr);
37 explicit TIFFKeeper(const std::string& filePath, bool readOnly = true);
38 ~TIFFKeeper();
39
40 // An owning handle must not be copied: two owners means two closes, and the
41 // second one operates on a pointer libtiff has already freed.
42 TIFFKeeper(const TIFFKeeper&) = delete;
43 TIFFKeeper& operator=(const TIFFKeeper&) = delete;
44 // After the move, `other` owns nothing: m_hFile is null and m_messageHandler
45 // has been transferred away, so `other` holds no message handler either. A
46 // moved-from keeper must not be revived via reset()/openTiffFile() -- doing so
47 // would hand it a live TIFF handle with no handler installed. It is fit only
48 // to be destroyed or move-/copy-assigned over.
49 TIFFKeeper(TIFFKeeper&& other) noexcept;
50 TIFFKeeper& operator=(TIFFKeeper&& other) noexcept;
51
52 libtiff::TIFF* getHandle() const {
53 return m_hFile;
54 }
55 bool isValid() const {
56 return m_hFile != nullptr;
57 }
58 // Takes ownership of a raw handle, closing any handle already held. Replaces the
59 // old operator=(TIFF*), which overwrote the member and leaked what it replaced.
60 void reset(libtiff::TIFF* hFile = nullptr);
61 // Gives up ownership without closing: the caller closes it from here on.
62 libtiff::TIFF* release();
63 void openTiffFile(const std::string& filePath, bool readOnly = true);
64 void closeTiffFile();
65 void writeDirectory();
66 void setTags(const TiffDirectory& dir);
67 void writeTile(int x, int y, Compression compression, const EncodeParameters& params, const cv::Mat& mat,
68 uint8_t* buffer, int bufferSize);
69 void readTile(const slideio::TiffDirectory& dir, int tile,
70 const std::vector<int>& channelIndices, cv::OutputArray output);
71 std::string readStringTag(uint16_t tag);
72 void initSubDirs(int numDirs);
73 void writeRawTile(int x, int y, const uint8_t* data, int size);
74
75 private:
76 // Shared initialiser for m_messageHandler, used by both constructors.
77 void initMessageHandler();
78
79 libtiff::TIFF* m_hFile = nullptr;
80 std::shared_ptr<TIFFMessageHandler> m_messageHandler;
81
82 };
83
84 using TIFFKeeperPtr = std::shared_ptr<TIFFKeeper>;
85}
Definition: exceptions.hpp:15