15 #ifdef BORNAGAIN_TIFF_SUPPORT
21 OutputDataReadWriteTiff::OutputDataReadWriteTiff()
26 , m_samplesPerPixel(0)
31 OutputDataReadWriteTiff::~OutputDataReadWriteTiff()
36 void OutputDataReadWriteTiff::read(std::istream& input_stream)
38 m_tiff = TIFFStreamOpen(
"MemTIFF", &input_stream);
40 throw std::runtime_error(
"OutputDataReadWriteTiff::read() -> Can't open the file.");
47 OutputData<double>* OutputDataReadWriteTiff::readOutputData(std::istream& input_stream)
50 return m_data->clone();
54 std::ostream& output_stream)
56 m_data.reset(data.
clone());
57 if (m_data->rank() != 2)
58 throw std::runtime_error(
"OutputDataReadWriteTiff::write -> Error. "
59 "Only 2-dim arrays supported");
60 m_tiff = TIFFStreamOpen(
"MemTIFF", &output_stream);
61 m_width = m_data->axis(0).size();
62 m_height = m_data->axis(1).size();
68 void OutputDataReadWriteTiff::read_header()
73 if (!TIFFGetField(m_tiff, TIFFTAG_IMAGEWIDTH, &width)
74 || !TIFFGetField(m_tiff, TIFFTAG_IMAGELENGTH, &height)) {
75 throw std::runtime_error(
"OutputDataReadWriteTiff::read_header() -> Error. "
76 "Can't read width/height.");
79 m_width = (size_t)width;
80 m_height = (size_t)height;
82 uint16 orientationTag(0);
83 TIFFGetField(m_tiff, TIFFTAG_ORIENTATION, &orientationTag);
88 if (!TIFFGetField(m_tiff, TIFFTAG_BITSPERSAMPLE, &m_bitsPerSample))
90 if (8 != m_bitsPerSample && 16 != m_bitsPerSample && 32 != m_bitsPerSample)
94 if (!TIFFGetField(m_tiff, TIFFTAG_SAMPLESPERPIXEL, &m_samplesPerPixel))
95 m_samplesPerPixel = 1;
96 if (m_samplesPerPixel != 1)
99 if (!TIFFGetField(m_tiff, TIFFTAG_SAMPLEFORMAT, &m_sampleFormat))
102 switch (m_sampleFormat) {
107 if (32 != m_bitsPerSample)
115 std::ostringstream message;
116 message <<
"OutputDataReadWriteTiff::read_header() -> Error. "
117 <<
"Can't read tiff image with following parameters:" << std::endl
118 <<
" TIFFTAG_BITSPERSAMPLE: " << m_bitsPerSample << std::endl
119 <<
" TIFFTAG_SAMPLESPERPIXEL: " << m_samplesPerPixel << std::endl
120 <<
" TIFFTAG_SAMPLEFORMAT: " << m_sampleFormat << std::endl;
121 throw std::runtime_error(message.str());
125 void OutputDataReadWriteTiff::read_data()
129 ASSERT(0 == m_bitsPerSample % 8);
130 uint16 bytesPerSample = m_bitsPerSample / 8;
131 tmsize_t buf_size = TIFFScanlineSize(m_tiff);
132 tmsize_t expected_size = bytesPerSample * m_width;
133 if (buf_size != expected_size)
134 throw std::runtime_error(
135 "OutputDataReadWriteTiff::read_data() -> Error. Wrong scanline size.");
137 tdata_t buf = _TIFFmalloc(buf_size);
139 throw std::runtime_error(
140 "OutputDataReadWriteTiff::read_data() -> Error. Can't allocate buffer.");
142 create_output_data();
144 std::vector<int8> line_buf;
145 line_buf.resize(buf_size, 0);
147 std::vector<unsigned> axes_indices(2);
149 for (uint32 row = 0; row < (uint32)m_height; row++) {
150 if (TIFFReadScanline(m_tiff, buf, row) < 0)
151 throw std::runtime_error(
152 "OutputDataReadWriteTiff::read_data() -> Error. Error in scanline.");
154 memcpy(&line_buf[0], buf, buf_size);
156 for (
unsigned col = 0; col < m_width; ++col) {
157 axes_indices[0] = col;
158 axes_indices[1] =
static_cast<unsigned>(m_height) - 1 - row;
159 size_t global_index = m_data->toGlobalIndex(axes_indices);
161 void* incoming = &line_buf[col * bytesPerSample];
164 switch (m_sampleFormat) {
166 switch (m_bitsPerSample) {
168 sample = *
reinterpret_cast<uint8*
>(incoming);
171 sample = *
reinterpret_cast<uint16*
>(incoming);
174 sample = *
reinterpret_cast<uint32*
>(incoming);
179 switch (m_bitsPerSample) {
181 sample = *
reinterpret_cast<int8*
>(incoming);
184 sample = *
reinterpret_cast<int16*
>(incoming);
187 sample = *
reinterpret_cast<int32*
>(incoming);
192 sample = double(*
reinterpret_cast<float*
>(incoming));
195 throw std::runtime_error(
"OutputDataReadWriteTiff: unexpected sample format");
198 (*m_data)[global_index] = sample;
204 void OutputDataReadWriteTiff::write_header()
207 TIFFSetField(m_tiff, TIFFTAG_ARTIST,
"BornAgain.IOFactory");
209 TIFFSetField(m_tiff, TIFFTAG_IMAGEDESCRIPTION,
210 "Image converted from BornAgain intensity file.");
211 TIFFSetField(m_tiff, TIFFTAG_SOFTWARE,
"BornAgain");
213 uint32 width =
static_cast<uint32
>(m_width);
214 uint32 height =
static_cast<uint32
>(m_height);
215 TIFFSetField(m_tiff, TIFFTAG_IMAGEWIDTH, width);
216 TIFFSetField(m_tiff, TIFFTAG_IMAGELENGTH, height);
219 uint16 bitPerSample = 32, samplesPerPixel = 1;
220 TIFFSetField(m_tiff, TIFFTAG_BITSPERSAMPLE, bitPerSample);
221 TIFFSetField(m_tiff, TIFFTAG_SAMPLESPERPIXEL, samplesPerPixel);
223 TIFFSetField(m_tiff, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISWHITE);
226 void OutputDataReadWriteTiff::write_data()
228 typedef int sample_t;
229 tmsize_t buf_size =
sizeof(sample_t) * m_width;
230 tdata_t buf = _TIFFmalloc(buf_size);
232 throw std::runtime_error(
233 "OutputDataReadWriteTiff::write_data() -> Error. Can't allocate buffer.");
235 std::vector<sample_t> line_buf;
236 line_buf.resize(m_width, 0);
237 std::vector<unsigned> axes_indices(2);
238 for (
unsigned row = 0; row < (uint32)m_height; row++) {
239 for (
unsigned col = 0; col < line_buf.size(); ++col) {
240 axes_indices[0] = col;
241 axes_indices[1] =
static_cast<unsigned>(m_height) - 1 - row;
242 size_t global_index = m_data->toGlobalIndex(axes_indices);
243 line_buf[col] =
static_cast<sample_t
>((*m_data)[global_index]);
245 memcpy(buf, &line_buf[0], buf_size);
247 if (TIFFWriteScanline(m_tiff, buf, row) < 0)
248 throw std::runtime_error(
249 "OutputDataReadWriteTiff::write_data() -> Error. Error in TIFFWriteScanline.");
255 void OutputDataReadWriteTiff::close()
265 void OutputDataReadWriteTiff::create_output_data()
269 m_data->addAxis(
"x", m_width, 0.0,
double(m_width));
270 m_data->addAxis(
"y", m_height, 0.0,
double(m_height));
#define ASSERT(condition)
Defines class OutputDataReadWriteTiff.
Defines various stuff in namespace Utils.
OutputData * clone() const
std::string getCurrentDateAndTime()