aimsdata  5.0.5
Neuroimaging data handling
tiffW.h
Go to the documentation of this file.
1 /* This software and supporting documentation are distributed by
2  * Institut Federatif de Recherche 49
3  * CEA/NeuroSpin, Batiment 145,
4  * 91191 Gif-sur-Yvette cedex
5  * France
6  *
7  * This software is governed by the CeCILL-B license under
8  * French law and abiding by the rules of distribution of free software.
9  * You can use, modify and/or redistribute the software under the
10  * terms of the CeCILL-B license as circulated by CEA, CNRS
11  * and INRIA at the following URL "http://www.cecill.info".
12  *
13  * As a counterpart to the access to the source code and rights to copy,
14  * modify and redistribute granted by the license, users are provided only
15  * with a limited warranty and the software's author, the holder of the
16  * economic rights, and the successive licensors have only limited
17  * liability.
18  *
19  * In this respect, the user's attention is drawn to the risks associated
20  * with loading, using, modifying and/or developing or reproducing the
21  * software by the user in light of its specific status of free software,
22  * that may mean that it is complicated to manipulate, and that also
23  * therefore means that it is reserved for developers and experienced
24  * professionals having in-depth computer knowledge. Users are therefore
25  * encouraged to load and test the software's suitability as regards their
26  * requirements in conditions enabling the security of their systems and/or
27  * data to be ensured and, more generally, to use and operate it in the
28  * same conditions as regards security.
29  *
30  * The fact that you are presently reading this means that you have had
31  * knowledge of the CeCILL-B license and that you accept its terms.
32  */
33 
34 #ifndef AIMS_IO_TIFFW_H
35 #define AIMS_IO_TIFFW_H
36 
37 #include <cstdlib>
38 #include <aims/io/tiffheader.h>
39 #include <aims/io/datatypecode.h>
40 #include <aims/data/pheader.h>
41 #include <aims/data/data.h>
44 #include <stdio.h>
45 extern "C"
46 {
47 #include <tiffio.h>
48 }
49 
50 namespace aims
51 {
52 
53  template<class T>
54  class TiffWriter
55  {
56  public:
57  TiffWriter( const std::string& name ) : _name( name ) {}
59 
60  void write( const AimsData<T> & thing );
63  void writeFrame( const AimsData<T> & thing, const std::string & filename,
64  unsigned zfame, unsigned tframe );
65 
66  private:
67  std::string _name;
68  };
69 
70  template <class T>
71  inline TiffWriter<T> &
72  operator << ( TiffWriter<T> & writer, const AimsData<T> & thing )
73  {
74  writer.write( thing );
75  return writer;
76  }
77 
78 
79  template <class T>
80  inline
81  void TiffWriter<T>::write( const AimsData<T>& thing )
82  {
83  unsigned t, z, dt = thing.dimT(), dz = thing.dimZ();
84  TiffHeader hdr( _name, carto::DataTypeCode<T>().dataType(), thing.dimX(),
85  thing.dimY(), thing.dimZ(), thing.dimT(), thing.sizeX(),
86  thing.sizeY(), thing.sizeZ(), thing.sizeT() );
87  const PythonHeader
88  *ph = dynamic_cast<const PythonHeader *>( thing.header() );
89  if( ph )
90  hdr.copy( *ph );
91 
92  std::string dir = carto::FileUtil::dirname( _name );
93  std::vector<std::string> files = hdr.outputFilenames();
94 
95  hdr.setProperty( "file_type", std::string( "TIFF" ) );
96  hdr.setProperty( "filenames", files );
97  if( !dir.empty() )
99 
100  unsigned i = 0;
101  for( t=0; t<dt; ++t )
102  for( z=0; z<dz; ++z, ++i ) {
103  writeFrame( thing, dir + files[i], z, t );
104  }
105 
106  hdr.writeMinf( dir + carto::FileUtil::removeExtension( files[0] )
107  + hdr.extension() + ".minf" );
108  }
109 
110  template<class T>
111  inline
113  const std::string & filename,
114  unsigned z,
115  unsigned t )
116  {
117  int bps, spp, photometric;
118  // Define an image
119  TIFF *tif;
120 
121  // Open the TIFF file
122  if((tif = TIFFOpen(filename.c_str(), "w")) == NULL){
123  std::cout << "Could not open '" << filename << "' for writing." << std::endl;
124  throw carto::file_not_found_error( _name );
125  }
126 
127  std::string name = carto::DataTypeCode<T>().name();
128  uint16_t sampleformat = SAMPLEFORMAT_UINT;
129 
130  if ( name == "U8" )
131  {
132  spp = 1;
133  bps = 8;
134  photometric = PHOTOMETRIC_MINISBLACK;
135  }
136  else if ( name == "S8" )
137  {
138  spp = 1;
139  bps = 8;
140  photometric = PHOTOMETRIC_MINISBLACK;
141  sampleformat = SAMPLEFORMAT_INT;
142  }
143  else if ( name == "U16" )
144  {
145  spp = 1;
146  bps = 16;
147  photometric = PHOTOMETRIC_MINISBLACK;
148  }
149  else if ( name == "S16" )
150  {
151  spp = 1;
152  bps = 16;
153  photometric = PHOTOMETRIC_MINISBLACK;
154  sampleformat = SAMPLEFORMAT_INT;
155  }
156  else if ( name == "FLOAT" )
157  {
158  spp = 1;
159  bps = 32;
160  photometric = PHOTOMETRIC_MINISBLACK;
161  sampleformat = SAMPLEFORMAT_IEEEFP;
162  }
163  else if ( name == "DOUBLE" )
164  {
165  spp = 1;
166  bps = 64;
167  photometric = PHOTOMETRIC_MINISBLACK;
168  sampleformat = SAMPLEFORMAT_IEEEFP;
169  }
170  else if ( name == "CFLOAT" )
171  {
172  spp = 2;
173  bps = 32;
174  photometric = PHOTOMETRIC_MINISBLACK;
175  sampleformat = SAMPLEFORMAT_COMPLEXIEEEFP;
176  }
177  else if ( name == "CDOUBLE" )
178  {
179  spp = 2;
180  bps = 64;
181  photometric = PHOTOMETRIC_MINISBLACK;
182  sampleformat = SAMPLEFORMAT_COMPLEXIEEEFP;
183  }
184  else if ( name == "RGBA" )
185  {
186  spp = 4;
187  bps = 8;
188  photometric = PHOTOMETRIC_RGB;
189  }
190  else
191  {
192  spp = 3;
193  bps = 8;
194  photometric = PHOTOMETRIC_RGB;
195  }
196 
197 // std::cout << "Filename : " << filename << std::endl;
198 // std::cout << "Type : " << name << ", Size : " << sizeof(T) << ", Spp : " << spp << ", Bps : " << bps << std::endl;
199 // std::cout << "DimX : " << data.dimX() << ", DimY : " << data.dimY() << std::endl;
200 // std::cout << "SizeX : " << data.sizeX() << ", SizeY : " << data.sizeY() << std::endl;
201 // std::cout << "Photometric : " << photometric << std::endl;
202 
203  // We need to set some values for basic tags before we can add any data
204  TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, data.dimX() );
205  TIFFSetField(tif, TIFFTAG_IMAGELENGTH, data.dimY());
206  TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, bps);
207  TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, spp );
208  TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, 1 );
209 
210  TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, photometric);
211  TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
212 
213  TIFFSetField(tif, TIFFTAG_XRESOLUTION, 10. / data.sizeX());
214  TIFFSetField(tif, TIFFTAG_YRESOLUTION, 10. / data.sizeY());
215  TIFFSetField(tif, TIFFTAG_RESOLUTIONUNIT, RESUNIT_CENTIMETER);
216  TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, sampleformat);
217 
218  // Write the information to the file
219  tsize_t res;
220  int y, ny = data.dimY();
221  for( y=0; y<ny; ++y )
222  {
223  res = TIFFWriteEncodedStrip(tif, y, (byte *)&data(0, y, z, t),
224  (bps / 8) * spp * data.dimX() );
225 
226  if( res < 0 )
227  throw carto::file_error( filename );
228  }
229 
230  // Close the file
231  TIFFClose(tif);
232  }
233 }
234 
235 #endif
236 
The descriptor class of the .dim GIS header.
Definition: tiffheader.h:48
TiffWriter(const std::string &name)
Definition: tiffW.h:57
int dimZ() const
Attributed python-like header, stores all needed information about an object, currently used for volu...
Definition: pheader.h:51
float sizeZ() const
int dimY() const
virtual void copy(const PythonHeader &, bool keepUuid=false)
float sizeT() const
The class for EcatSino data write operation.
Definition: border.h:44
static std::string removeExtension(const std::string &)
void write(const AimsData< T > &thing)
Definition: tiffW.h:81
float sizeX() const
static char separator()
static std::string dirname(const std::string &)
const aims::Header * header() const
void writeFrame(const AimsData< T > &thing, const std::string &filename, unsigned zfame, unsigned tframe)
called by write(), but you can call it for single frame writing (axial slice)
Definition: tiffW.h:112
float sizeY() const
int dimT() const
uint8_t byte
int dimX() const