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()