34 #ifndef AIMS_IO_TIFFR_H
35 #define AIMS_IO_TIFFR_H
66 int zframe,
unsigned tframe );
74 inline TiffReader<T> &
86 const carto::AllocatorContext & context,
94 catch( std::exception & e )
100 int frame = -1, border = 0;
101 options->getProperty(
"frame", frame );
102 options->getProperty(
"border", border );
105 std::vector<int> dims;
108 if( dims.size() < 1 )
109 dims.push_back( hdr->
dimX() );
110 if( dims.size() < 2 )
111 dims.push_back( hdr->
dimY() );
112 if( dims.size() < 3 )
113 dims.push_back( hdr->
dimZ() );
114 if( dims.size() < 4 )
115 dims.push_back( hdr->
dimT() );
117 unsigned tmin = 0, tmax = dims[3] - 1;
120 if( tmax < (
unsigned) frame )
123 throw std::domain_error(
"frame higher than file dimT" );
125 if( (
unsigned) frame < tmax )
126 files.erase( files.begin() + ( frame + 1 ) * hdr->
dimZ(),
129 files.erase( files.begin(), files.begin() + frame * hdr->
dimZ() );
134 carto::AllocatorContext al
135 ( context.accessMode(),
137 (
new carto::FileDataSource( *files.begin(), 0,
138 carto::DataSource::Read ) ),
139 false, context.useFactor() );
159 dims[3] = tmax - tmin + 1;
169 unsigned i = 0, s, t, ns = (unsigned) data.
dimZ(),
nt = tmax - tmin + 1;
171 if ( files.size() == ns *
nt )
174 for( t=0; t<
nt; ++t ) {
175 for( s=0; s<ns; ++s, ++i ) {
177 readFrame( data, dir + files[i], s, t );
181 }
else if ( files.size() ==
nt )
184 for( t=0; t<
nt; ++t ) {
186 readFrame( data, dir + files[t], -1, t );
199 template <
typename T,
typename U>
inline
200 T tiff_scaled_value_single(
const U* buffer )
203 int shift =
sizeof(U) <=
sizeof(T) ?
204 0 : ((
sizeof(U) -
sizeof(T)) * 8);
205 item = *buffer >> shift;
209 template <
typename T,
typename U>
inline
210 T tiff_scaled_value_items(
const U* buffer, uint16_t nitems )
213 int shift =
sizeof(U) * nitems <=
sizeof(T) ?
214 0 : ((
sizeof(U) -
sizeof(T) / nitems) * 8);
215 for( uint16_t i=0; i<nitems; ++i )
217 item[i] = *buffer++ >> shift;
222 template <
typename T,
typename U>
223 class tiff_scaled_value_u
226 static inline T scale(
const U* buffer )
228 return tiff_scaled_value_single<T, U>( buffer );
232 template <
typename U>
233 class tiff_scaled_value_u<
AimsRGB, U>
236 static inline AimsRGB scale(
const U* buffer )
238 return tiff_scaled_value_items<AimsRGB, U>( buffer, 3 );
242 template <
typename U>
243 class tiff_scaled_value_u<
AimsRGBA, U>
246 static inline AimsRGBA scale(
const U* buffer )
248 return tiff_scaled_value_items<AimsRGBA, U>( buffer, 4 );
252 template <
typename T>
inline
253 T tiff_scaled_value(
const char *buffer, uint16_t bits )
256 return tiff_scaled_value_u<T, uint8_t>::scale(
257 (
const uint8_t *) buffer );
258 else if( bits == 16 )
259 return tiff_scaled_value_u<T, uint16_t>::scale(
260 (
const uint16_t *) buffer );
262 return tiff_scaled_value_u<T, uint32_t>::scale(
263 (
const uint32_t *) buffer );
271 const std::string & name,
int zframe,
274 int tiled, stripSize, rowsPerStrip;
275 uint i, s, zmin, zmax, dx = data.
dimX(), dy = data.
dimY();
278 TIFFSetWarningHandler( 0 );
279 TIFF* tif = TIFFOpen(name.c_str(),
"r");
286 tiled = TIFFIsTiled(tif);
290 "Not a tiled TIFF image : can't read" );
304 zmax = (
uint)zframe + 1;
307 for (
uint z = zmin; z < zmax; z++ )
309 TIFFSetDirectory(tif, z );
310 stripSize = TIFFStripSize(tif);
311 uint16_t bits, samplesize;
314 TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &rowsPerStrip);
315 TIFFGetFieldDefaulted(tif, TIFFTAG_PHOTOMETRIC, &photometric);
316 TIFFGetFieldDefaulted(tif, TIFFTAG_BITSPERSAMPLE, &bits);
317 samplesize = stripSize / dx / rowsPerStrip;
320 if( photometric != PHOTOMETRIC_PALETTE )
322 std::vector<char> buffer( stripSize, 0 );
323 for(s=0, i=0; s < dy; s += rowsPerStrip, ++i)
325 TIFFReadEncodedStrip(tif, i, &buffer[0], stripSize);
326 if( samplesize ==
sizeof(T) )
327 for(
uint y=s; y<std::min(s+rowsPerStrip, dy); ++y )
328 memcpy( &data(0, y, z, tframe),
329 &buffer[(y-s) * dx * samplesize],
332 for(
uint y=s; y<std::min(s+rowsPerStrip, dy); ++y )
334 T* ibuf = &data( 0, y, z, tframe );
335 for(
uint x=0; x<dx; ++x, ++ibuf )
336 *ibuf = tiff_scaled_value<T>(
337 &buffer[((y-s) * dx + x) * samplesize], bits );
341 if(photometric == PHOTOMETRIC_MINISWHITE)
346 for(
int y = 0; y < data.
dimY(); ++y) {
347 buffer = (
byte*)&data(0, y, z, tframe);
348 for(
unsigned index=0; index<(dx *
sizeof(T)); index++ )
350 buffer[index] =~ buffer[index];
359 uint32_t * rgba_data = (uint32_t *)&data(0, 0, z, tframe);
360 TIFFReadRGBAImageOriented(tif, dx, data.
dimY(),
361 rgba_data, ORIENTATION_TOPLEFT);
void setSizeY(float sizey)
const carto::AllocatorContext & allocator() const
void setSizeT(float sizet)
void setHeader(aims::Header *hdr)
void setSizeZ(float sizez)
void setSizeX(float sizex)
void readFrame(AimsData< T > &thing, const std::string &filename, int zframe, unsigned tframe)
called by read(), but you can call it for single frame reading (axial slice)
void read(AimsData< T > &thing, const carto::AllocatorContext &context, carto::Object options)
TiffReader(const std::string &name)
static std::string dirname(const std::string &)
static std::string fileStat(const std::string &)
virtual bool getProperty(const std::string &, Object &) const
virtual bool removeProperty(const std::string &)
virtual void setProperty(const std::string &, Object)
virtual bool hasProperty(const std::string &) const
The class for EcatSino data write operation.
GenesisReader< T > & operator>>(GenesisReader< T > &reader, AimsData< T > &thing)