15 #ifdef BORNAGAIN_TIFF_SUPPORT
21 TiffHandler::TiffHandler()
22 : m_tiff(0), m_width(0), m_height(0), m_bitsPerSample(0), m_samplesPerPixel(0),
27 TiffHandler::~TiffHandler()
32 void TiffHandler::read(std::istream& input_stream)
34 m_tiff = TIFFStreamOpen(
"MemTIFF", &input_stream);
50 m_data.reset(data.clone());
51 if (m_data->getRank() != 2)
53 "Only 2-dim arrays supported");
54 m_tiff = TIFFStreamOpen(
"MemTIFF", &output_stream);
55 m_width = m_data->getAxis(0).size();
56 m_height = m_data->getAxis(1).size();
62 void TiffHandler::read_header()
67 if (!TIFFGetField(m_tiff, TIFFTAG_IMAGEWIDTH, &width)
68 || !TIFFGetField(m_tiff, TIFFTAG_IMAGELENGTH, &height)) {
70 "Can't read width/height.");
73 m_width = (size_t)width;
74 m_height = (size_t)height;
76 uint16 orientationTag(0);
77 TIFFGetField(m_tiff, TIFFTAG_ORIENTATION, &orientationTag);
82 if (!TIFFGetField(m_tiff, TIFFTAG_BITSPERSAMPLE, &m_bitsPerSample))
84 if (8 != m_bitsPerSample && 16 != m_bitsPerSample && 32 != m_bitsPerSample)
88 if (!TIFFGetField(m_tiff, TIFFTAG_SAMPLESPERPIXEL, &m_samplesPerPixel))
89 m_samplesPerPixel = 1;
90 if (m_samplesPerPixel != 1)
93 if (!TIFFGetField(m_tiff, TIFFTAG_SAMPLEFORMAT, &m_sampleFormat))
96 switch (m_sampleFormat) {
101 if (32 != m_bitsPerSample)
109 std::ostringstream message;
110 message <<
"TiffHandler::read_header() -> Error. "
111 <<
"Can't read tiff image with following parameters:" << std::endl
112 <<
" TIFFTAG_BITSPERSAMPLE: " << m_bitsPerSample << std::endl
113 <<
" TIFFTAG_SAMPLESPERPIXEL: " << m_samplesPerPixel << std::endl
114 <<
" TIFFTAG_SAMPLEFORMAT: " << m_sampleFormat << std::endl;
119 void TiffHandler::read_data()
123 ASSERT(0 == m_bitsPerSample % 8);
124 uint16 bytesPerSample = m_bitsPerSample / 8;
125 tmsize_t buf_size = TIFFScanlineSize(m_tiff);
126 tmsize_t expected_size = bytesPerSample * m_width;
127 if (buf_size != expected_size)
129 "TiffHandler::read_data() -> Error. Wrong scanline size.");
131 tdata_t buf = _TIFFmalloc(buf_size);
134 "TiffHandler::read_data() -> Error. Can't allocate buffer.");
136 create_output_data();
138 std::vector<int8> line_buf;
139 line_buf.resize(buf_size, 0);
141 std::vector<unsigned> axes_indices(2);
143 for (uint32 row = 0; row < (uint32)m_height; row++) {
144 if (TIFFReadScanline(m_tiff, buf, row) < 0)
146 "TiffHandler::read_data() -> Error. Error in scanline.");
148 memcpy(&line_buf[0], buf, buf_size);
150 for (
unsigned col = 0; col < m_width; ++col) {
151 axes_indices[0] = col;
152 axes_indices[1] =
static_cast<unsigned>(m_height) - 1 - row;
153 size_t global_index = m_data->toGlobalIndex(axes_indices);
155 void* incoming = &line_buf[col * bytesPerSample];
158 switch (m_sampleFormat) {
160 switch (m_bitsPerSample) {
162 sample = *
reinterpret_cast<uint8*
>(incoming);
165 sample = *
reinterpret_cast<uint16*
>(incoming);
168 sample = *
reinterpret_cast<uint32*
>(incoming);
173 switch (m_bitsPerSample) {
175 sample = *
reinterpret_cast<int8*
>(incoming);
178 sample = *
reinterpret_cast<int16*
>(incoming);
181 sample = *
reinterpret_cast<int32*
>(incoming);
186 sample = double(*
reinterpret_cast<float*
>(incoming));
192 (*m_data)[global_index] = sample;
198 void TiffHandler::write_header()
201 TIFFSetField(m_tiff, TIFFTAG_ARTIST,
"BornAgain.IOFactory");
202 TIFFSetField(m_tiff, TIFFTAG_DATETIME, SysUtils::getCurrentDateAndTime().c_str());
203 TIFFSetField(m_tiff, TIFFTAG_IMAGEDESCRIPTION,
204 "Image converted from BornAgain intensity file.");
205 TIFFSetField(m_tiff, TIFFTAG_SOFTWARE,
"BornAgain");
207 uint32 width =
static_cast<uint32
>(m_width);
208 uint32 height =
static_cast<uint32
>(m_height);
209 TIFFSetField(m_tiff, TIFFTAG_IMAGEWIDTH, width);
210 TIFFSetField(m_tiff, TIFFTAG_IMAGELENGTH, height);
213 uint16 bitPerSample = 32, samplesPerPixel = 1;
214 TIFFSetField(m_tiff, TIFFTAG_BITSPERSAMPLE, bitPerSample);
215 TIFFSetField(m_tiff, TIFFTAG_SAMPLESPERPIXEL, samplesPerPixel);
217 TIFFSetField(m_tiff, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISWHITE);
220 void TiffHandler::write_data()
222 typedef int sample_t;
223 tmsize_t buf_size =
sizeof(sample_t) * m_width;
224 tdata_t buf = _TIFFmalloc(buf_size);
227 "TiffHandler::write_data() -> Error. Can't allocate buffer.");
229 std::vector<sample_t> line_buf;
230 line_buf.resize(m_width, 0);
231 std::vector<unsigned> axes_indices(2);
232 for (
unsigned row = 0; row < (uint32)m_height; row++) {
233 for (
unsigned col = 0; col < line_buf.size(); ++col) {
234 axes_indices[0] = col;
235 axes_indices[1] =
static_cast<unsigned>(m_height) - 1 - row;
236 size_t global_index = m_data->toGlobalIndex(axes_indices);
237 line_buf[col] =
static_cast<sample_t
>((*m_data)[global_index]);
239 memcpy(buf, &line_buf[0], buf_size);
241 if (TIFFWriteScanline(m_tiff, buf, row) < 0)
243 "TiffHandler::write_data() -> Error. Error in TIFFWriteScanline.");
249 void TiffHandler::close()
259 void TiffHandler::create_output_data()
263 m_data->addAxis(
"x", m_width, 0.0,
double(m_width));
264 m_data->addAxis(
"y", m_height, 0.0,
double(m_height));
Defines various stuff in namespace Utils.
Defines class TiffHandler.