aimsdata 6.0.0
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>
40#include <aims/data/pheader.h>
41#include <aims/data/data.h>
42#include <cartobase/exception/file.h>
43#include <cartobase/exception/ioexcept.h>
44#include <stdio.h>
45extern "C"
46{
47#include <tiffio.h>
48}
49
50namespace aims
51{
52
53 template<class T>
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 std::string name = carto::DataTypeCode<T>().name();
119 uint16_t sampleformat = SAMPLEFORMAT_UINT;
120 uint16_t extrasampletype = EXTRASAMPLE_UNASSALPHA;
121 uint16_t extrasamplescount = 0;
122
123 if ( name == "U8" )
124 {
125 spp = 1;
126 bps = 8;
127 photometric = PHOTOMETRIC_MINISBLACK;
128 }
129 else if ( name == "S8" )
130 {
131 spp = 1;
132 bps = 8;
133 photometric = PHOTOMETRIC_MINISBLACK;
134 sampleformat = SAMPLEFORMAT_INT;
135 }
136 else if ( name == "U16" )
137 {
138 spp = 1;
139 bps = 16;
140 photometric = PHOTOMETRIC_MINISBLACK;
141 }
142 else if ( name == "S16" )
143 {
144 spp = 1;
145 bps = 16;
146 photometric = PHOTOMETRIC_MINISBLACK;
147 sampleformat = SAMPLEFORMAT_INT;
148 }
149 else if ( name == "U32" )
150 {
151 spp = 1;
152 bps = 32;
153 photometric = PHOTOMETRIC_MINISBLACK;
154 }
155 else if ( name == "S32" )
156 {
157 spp = 1;
158 bps = 32;
159 photometric = PHOTOMETRIC_MINISBLACK;
160 sampleformat = SAMPLEFORMAT_INT;
161 }
162 else if ( name == "FLOAT" )
163 {
164 spp = 1;
165 bps = 32;
166 photometric = PHOTOMETRIC_MINISBLACK;
167 sampleformat = SAMPLEFORMAT_IEEEFP;
168 }
169 else if ( name == "DOUBLE" )
170 {
171 spp = 1;
172 bps = 64;
173 photometric = PHOTOMETRIC_MINISBLACK;
174 sampleformat = SAMPLEFORMAT_IEEEFP;
175 }
176 else if ( name == "CFLOAT" )
177 {
178 spp = 2;
179 bps = 32;
180 photometric = PHOTOMETRIC_MINISBLACK;
181 sampleformat = SAMPLEFORMAT_COMPLEXIEEEFP;
182 }
183 else if ( name == "CDOUBLE" )
184 {
185 spp = 2;
186 bps = 64;
187 photometric = PHOTOMETRIC_MINISBLACK;
188 sampleformat = SAMPLEFORMAT_COMPLEXIEEEFP;
189 }
190 else if ( name == "RGBA" )
191 {
192 spp = 4;
193 bps = 8;
194 photometric = PHOTOMETRIC_RGB;
195 extrasamplescount = 1;
196 }
197 else
198 {
199 spp = 3;
200 bps = 8;
201 photometric = PHOTOMETRIC_RGB;
202 }
203
204 // std::cout << "-- TIFF Filename : " << filename << std::endl;
205 // std::cout << "-- TIFF Type : " << name << ", Size : " << sizeof(T) << ", Spp : " << spp << ", Bps : " << bps << std::endl;
206 // std::cout << "-- TIFF DimX : " << data.dimX() << ", DimY : " << data.dimY() << std::endl;
207 // std::cout << "-- TIFF SizeX : " << data.sizeX() << ", SizeY : " << data.sizeY() << std::endl;
208 // std::cout << "-- TIFF Photometric : " << photometric << std::endl;
209 // std::cout << "-- TIFF data size: " << carto::toString((long)spp * data.dimX() * data.dimY()) << std::endl << std::flush;
210 // std::cout << "-- TIFF data size limit: " << carto::toString(std::numeric_limits<uint32_t>::max()) << std::endl << std::flush;
211
212 // Define an image
213 TIFF *tif;
214
215 if (((long)(bps / 8) * spp * data.dimX() * data.dimY()) <= std::numeric_limits<uint32_t>::max()) {
216 // Use standard tiff
217 // std::cout << "-- TIFF support: standard" << std::endl;
218 tif = TIFFOpen(filename.c_str(), "w");
219 }
220 else {
221 // Use big tiff
222 // std::cout << "-- TIFF support: big tiff" << std::endl;
223 tif = TIFFOpen(filename.c_str(), "w8");
224 }
225
226 // Open the TIFF file
227 if(tif == NULL){
228 std::cout << "Could not open '" << filename << "' for writing." << std::endl;
229 throw carto::file_not_found_error( _name );
230 }
231
232 // We need to set some values for basic tags before we can add any data
233 TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, data.dimX() );
234 TIFFSetField(tif, TIFFTAG_IMAGELENGTH, data.dimY());
235 TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, bps);
236 TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, spp );
237 TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, 1 );
238
239 TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, photometric);
240 TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
241
242 TIFFSetField(tif, TIFFTAG_XRESOLUTION, 10. / data.sizeX());
243 TIFFSetField(tif, TIFFTAG_YRESOLUTION, 10. / data.sizeY());
244 TIFFSetField(tif, TIFFTAG_RESOLUTIONUNIT, RESUNIT_CENTIMETER);
245 TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, sampleformat);
246
247 if (extrasamplescount > 0) {
248 TIFFSetField(tif, TIFFTAG_EXTRASAMPLES, extrasamplescount, &extrasampletype);
249 }
250
251 tsize_t res;
252 int y, ny = data.dimY(), nx = data.dimX();
253
254 long stride = &data( 1 ) - &data( 0 );
255 std::vector<T> buffer;
256 if( stride != 1 )
257 // allocate buffer for un-strided data
258 buffer.resize( nx );
259 void *ptr;
260
261 // Write the information to the file
262 for( y=0; y<ny; ++y )
263 {
264 if( stride == 1 )
265 ptr = (void *) &data(0, y, z, t);
266 else
267 {
268 // stides along X axis: must copy things
269 const T* p = &data( 0, y, z, t );
270 for( long x=0; x<nx; ++x, p+=stride )
271 buffer[x] = *p;
272 ptr = (void *) &buffer[0];
273 }
274
275 // std::cout << "-- TIFF writing strip (data size: "
276 // << carto::toString((bps / 8) * spp * data.dimX())
277 // << ")" << std::endl << std::flush;
278 res = TIFFWriteEncodedStrip(tif, y, ptr, (bps / 8) * spp * data.dimX() );
279 // std::cout << "-- TIFF strip written (result: " << carto::toString(res)
280 // << ")" << std::endl << std::flush;
281
282 if( res < 0 )
283 throw carto::file_error( filename );
284 }
285
286 // Close the file
287 TIFFClose(tif);
288 }
289}
290
291#endif
292
float sizeX() const
float sizeT() const
int dimY() const
int dimX() const
int dimT() const
float sizeZ() const
float sizeY() const
int dimZ() const
const aims::Header * header() const
Attributed python-like header, stores all needed information about an object, currently used for volu...
Definition pheader.h:52
virtual void copy(const PythonHeader &, bool keepUuid=false)
virtual bool writeMinf(const std::string &filename)
write meta-info header, non-const version (may change some attributes)
virtual std::vector< std::string > outputFilenames() const
The descriptor class of the .dim GIS header.
Definition tiffheader.h:49
virtual std::string extension() const
standard file format extension of specialized headers
TiffWriter(const std::string &name)
Definition tiffW.h:57
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
void write(const AimsData< T > &thing)
Definition tiffW.h:81
std::string name()
static char separator()
static std::string dirname(const std::string &)
static std::string removeExtension(const std::string &)
virtual void setProperty(const std::string &, Object)
The class for EcatSino data write operation.
AIMSDATA_API PovWriter< D, T > & operator<<(PovWriter< D, T > &writer, const AimsTimeSurface< D, T > &thing)
Definition povW.h:72
static _Tp max()