Xmipp  v3.23.11-Nereus
Classes | Functions
Collaboration diagram for TIFF File format:

Classes

struct  TIFFDirHead
 
struct  ImageBase::TIFFDirHead
 

Functions

DataType datatypeH5 (hid_t dataset)
 
void castTiffTile2T (size_t offset, char *tif_buf, unsigned int x, unsigned int y, unsigned int imageWidth, unsigned int imageLength, unsigned int tileWidth, unsigned int tileLength, unsigned short samplesPerPixel, DataType datatype)
 
void castTiffLine2T (size_t offset, char *tif_buf, unsigned int y, unsigned int imageWidth, unsigned int imageLength, unsigned short samplesPerPixel, DataType datatype)
 
DataType datatypeTIFF (TIFFDirHead dHead)
 
int readTIFF (size_t select_img, bool isStack=false)
 
int writeTIFF (size_t select_img, bool isStack=false, int mode=WRITE_OVERWRITE, String bitDepth="", CastWriteMode castMode=CW_CAST)
 
void ImageBase::castTiffTile2T (size_t offset, char *tif_buf, unsigned int x, unsigned int y, unsigned int imageWidth, unsigned int imageLength, unsigned int tileWidth, unsigned int tileLength, unsigned short samplesPerPixel, DataType datatype)
 
void ImageBase::castTiffLine2T (size_t offset, char *tif_buf, unsigned int y, unsigned int imageWidth, unsigned int imageLength, unsigned short samplesPerPixel, DataType datatype)
 
DataType ImageBase::datatypeTIFF (TIFFDirHead dHead)
 
int ImageBase::readTIFF (size_t select_img, bool isStack=false)
 
int ImageBase::writeTIFF (size_t select_img, bool isStack=false, int mode=WRITE_OVERWRITE, String bitDepth="", CastWriteMode castMode=CW_CAST)
 
DataType ImageBase::datatypeH5 (hid_t dataset)
 

Detailed Description

Function Documentation

◆ castTiffLine2T() [1/2]

void castTiffLine2T ( size_t  offset,
char *  tif_buf,
unsigned int  y,
unsigned int  imageWidth,
unsigned int  imageLength,
unsigned short  samplesPerPixel,
DataType  datatype 
)

castTiffLine2T write the content of a line from a TIFF file to an image array

◆ castTiffLine2T() [2/2]

void ImageBase::castTiffLine2T ( size_t  offset,
char *  tif_buf,
unsigned int  y,
unsigned int  imageWidth,
unsigned int  imageLength,
unsigned short  samplesPerPixel,
DataType  datatype 
)
protected

castTiffLine2T write the content of a line from a TIFF file to an image array

Definition at line 67 of file rwTIFF.cpp.

74 {
75  unsigned int x;
76  int typeSize = gettypesize(datatype);
77 
78  for (x = 0; x < imageWidth; x++)
79  setPage2T(offset+(y*imageWidth + x), (char*) tif_buf+(samplesPerPixel*typeSize * x), datatype, (size_t) 1);
80 }
virtual void setPage2T(size_t offset, char *page, DataType datatype, size_t pageSize)=0
static double * y
doublereal * x
DataType datatype() const
size_t gettypesize(DataType type)
Returns memory size of datatype.

◆ castTiffTile2T() [1/2]

void castTiffTile2T ( size_t  offset,
char *  tif_buf,
unsigned int  x,
unsigned int  y,
unsigned int  imageWidth,
unsigned int  imageLength,
unsigned int  tileWidth,
unsigned int  tileLength,
unsigned short  samplesPerPixel,
DataType  datatype 
)

castTiffTile2T write the content of a tile from a TIFF file to an image array

◆ castTiffTile2T() [2/2]

void ImageBase::castTiffTile2T ( size_t  offset,
char *  tif_buf,
unsigned int  x,
unsigned int  y,
unsigned int  imageWidth,
unsigned int  imageLength,
unsigned int  tileWidth,
unsigned int  tileLength,
unsigned short  samplesPerPixel,
DataType  datatype 
)
protected

castTiffTile2T write the content of a tile from a TIFF file to an image array

Definition at line 38 of file rwTIFF.cpp.

46 {
47  int typeSize = gettypesize(datatype);
48  unsigned int i, j;
49  unsigned int x_max = x + tileWidth,
50  y_max = y + tileLength;
51 
52  if (x_max > imageWidth)
53  x_max = imageWidth;
54  if (y_max > imageLength)
55  y_max = imageLength;
56 
57 
58  for (j = y; j < y_max; j++)
59  for (i = x; i < x_max; i++)
60  setPage2T(offset+(j*imageWidth + i), (char*) tif_buf+((j-y)*samplesPerPixel*typeSize*tileWidth+(i-x)*samplesPerPixel*typeSize), datatype, (size_t) 1);
61 }
virtual void setPage2T(size_t offset, char *page, DataType datatype, size_t pageSize)=0
static double * y
doublereal * x
#define i
#define j
DataType datatype() const
size_t gettypesize(DataType type)
Returns memory size of datatype.

◆ datatypeH5() [1/2]

DataType datatypeH5 ( hid_t  dataset)

Determine datatype of a HDF5 dataset.

◆ datatypeH5() [2/2]

DataType ImageBase::datatypeH5 ( hid_t  dataset)
protected

Determine datatype of a HDF5 dataset.

Definition at line 33 of file rwHDF5.cpp.

34 {
35  H5T_sign_t h5sign = H5Tget_sign(h5datatype);
36 
37  // if (h5sign == H5T_SGN_ERROR)
38  // REPORT_ERROR(ERR_IO, "datatypeHDF5: Integer sign error in dataset.");
39  bool sign = (h5sign > H5T_SGN_NONE);
40  size_t size = H5Tget_size(h5datatype);
41 
42  DataType dt;
43  switch(H5Tget_class(h5datatype))
44  {
45  case H5T_FLOAT:
46  {
47  switch(size)
48  {
49  case 4:
50  dt = DT_Float;
51  break;
52  case 8:
53  dt = DT_Double;
54  break;
55  default:
56  REPORT_ERROR(ERR_IO_SIZE, "datatypeHDF5: bad datatype size");
57  }
58  }
59  break;
60  case H5T_INTEGER:
61  {
62  switch(size)
63  {
64  case 1:
65  dt = (sign)? DT_SChar : DT_UChar;
66  break;
67  case 2:
68  dt = (sign)? DT_Short : DT_UShort;
69  break;
70  case 4:
71  dt = (sign)? DT_Int : DT_UInt;
72  break;
73  case 8:
74  dt = (sign)? DT_Long : DT_ULong;
75  break;
76  default:
77  REPORT_ERROR(ERR_IO_SIZE, "datatypeHDF5: bad datatype size");
78  }
79  }
80  break;
81  case H5T_NO_CLASS:
82  default:
83  dt = DT_Unknown;
84  break;
85  }
86  return dt;
87 }
#define REPORT_ERROR(nerr, ErrormMsg)
Definition: xmipp_error.h:211
double sign
DataType
Incorrect file size.
Definition: xmipp_error.h:145

◆ datatypeTIFF() [1/2]

DataType datatypeTIFF ( TIFFDirHead  dHead)

Determine datatype of the TIFF format file.

◆ datatypeTIFF() [2/2]

DataType ImageBase::datatypeTIFF ( TIFFDirHead  dHead)
protected

Determine datatype of the TIFF format file.

Definition at line 85 of file rwTIFF.cpp.

86 {
88 
89  switch (dHead.bitsPerSample)
90  {
91  case 8:
92  if (dHead.imageSampleFormat == SAMPLEFORMAT_INT)
93  datatype = DT_SChar;
94  else
95  datatype = DT_UChar;
96  break;
97  case 16:
98  if (dHead.imageSampleFormat == SAMPLEFORMAT_INT)
99  datatype = DT_Short;
100  else
101  datatype = DT_UShort;
102 
103  // else if (dHead.imageSampleFormat == SAMPLEFORMAT_UINT ||
104  // dHead.imageSampleFormat == SAMPLEFORMAT_IEEEFP ) //Don't know why
105  // datatype = DT_UShort;
106  // // else if (dHead.imageSampleFormat == 0 ||
107  // // dHead.imageSampleFormat == 32767 ) // Format 0 and 32767 are not declared in TIFF 6.0 specifications
108  // else
109  // datatype = DT_UShort;
110  break;
111  case 32:
112  if (dHead.imageSampleFormat == SAMPLEFORMAT_INT)
113  datatype = DT_Int;
114  else if (dHead.imageSampleFormat == SAMPLEFORMAT_UINT )
115  datatype = DT_UInt;
116  else if (dHead.imageSampleFormat == SAMPLEFORMAT_IEEEFP )
117  datatype = DT_Float;
118  else
119  //datatype = DT_Unknown;
120  datatype = DT_Float; // Eman2 does not write the datatype
121  break;
122  default:
123  datatype = DT_Unknown;
124  (void)datatype; // to suppress dead assignment warning
125  // REPORT_ERROR(ERR_TYPE_INCORRECT,"rwTIFF: Unsupported TIFF sample format.");
126  break;
127  }
128  return datatype;
129 }
unsigned short bitsPerSample
Definition: rwTIFF.h:37
DataType
DataType datatype() const
uint16_t imageSampleFormat
Definition: rwTIFF.h:41

◆ readTIFF() [1/2]

int readTIFF ( size_t  select_img,
bool  isStack = false 
)

Read TIFF format files.

◆ readTIFF() [2/2]

int ImageBase::readTIFF ( size_t  select_img,
bool  isStack = false 
)
protected

Read TIFF format files.

Definition at line 134 of file rwTIFF.cpp.

135 {
136 #undef DEBUG
137  //#define DEBUG
138 #ifdef DEBUG
139  printf("DEBUG readTIFF: Reading TIFF file\n");
140 #endif
141 
142  // TIFFSetWarningHandler(NULL); // Switch off warning messages
143 
144  char* tif_buf = NULL;
145  std::vector<TIFFDirHead> dirHead;
146  TIFFDirHead dhRef;
147 
148  /* Get TIFF image properties */
149  do
150  {
151  dhRef.imageSampleFormat = SAMPLEFORMAT_VOID;
152  if (TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &dhRef.bitsPerSample) == 0)
153  REPORT_ERROR(ERR_IO_NOREAD,"rwTIFF: Error reading TIFFTAG_BITSPERSAMPLE");
154  if (TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL,&dhRef.samplesPerPixel) == 0)
155  dhRef.samplesPerPixel = 1;
156 
157  if (TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &dhRef.imageWidth) == 0)
158  REPORT_ERROR(ERR_IO_NOREAD,"rwTIFF: Error reading TIFFTAG_IMAGEWIDTH");
159  if (TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &dhRef.imageLength) == 0)
160  REPORT_ERROR(ERR_IO_NOREAD,"rwTIFF: Error reading TIFFTAG_IMAGELENGTH");
161  if (TIFFGetField(tif, TIFFTAG_SUBFILETYPE, &dhRef.subFileType) == 0)
162  dhRef.subFileType = 0; // Some scanners does not provide this label. So, we set this to zero
163  // REPORT_ERROR(ERR_IO_NOREAD,"rwTIFF: Error reading TIFFTAG_SUBFILETYPE");
164  TIFFGetField(tif, TIFFTAG_SAMPLEFORMAT, &dhRef.imageSampleFormat);
165  TIFFGetField(tif, TIFFTAG_RESOLUTIONUNIT, &dhRef.resUnit);
166  TIFFGetField(tif, TIFFTAG_XRESOLUTION, &dhRef.xTiffRes);
167  TIFFGetField(tif, TIFFTAG_YRESOLUTION, &dhRef.yTiffRes);
168  TIFFGetField(tif, TIFFTAG_PAGENUMBER, &dhRef.pNumber, &dhRef.pTotal);
169 
170  if ((dhRef.subFileType & 0x00000001) != 0x00000001) //add image if not a thumbnail
171  dirHead.push_back(dhRef);
172  }
173  while(TIFFReadDirectory(tif));
174 
175  swap = TIFFIsByteSwapped(tif);
176 
177  //Check select_img is lower than stack size
178  if (select_img > dirHead.size())
179  REPORT_ERROR(ERR_INDEX_OUTOFBOUNDS, formatString("readTIFF (%s): Image number %lu exceeds stack size %lu", filename.c_str(), select_img, dirHead.size()));
180  else if (select_img == ALL_IMAGES)// Check images dimensions. Need to be the same
181  {
182  for (size_t i = 1; i < dirHead.size(); i++)
183  {
184  if (dirHead[0].imageLength != dirHead[i].imageLength || \
185  dirHead[0].imageWidth != dirHead[i].imageWidth)
186  dirHead.resize(i);
187  /*REPORT_ERROR(ERR_IMG_NOREAD, formatString("readTIFF: %s file contains %lu images with, at least,"\
188  " two of them with different dimensions. Try to read them individually.",filename.c_str(), dirHead.size()));*/
189  }
190  }
191 
192  // Calculate x,y space dimension resolution
193  double xRes=1.0, yRes=1.0;
194 
195  if (dirHead[0].xTiffRes>0 && dirHead[0].yTiffRes>0)
196  {
197  switch (dirHead[0].resUnit)
198  {
199  case RESUNIT_NONE:
200  {
201  xRes = yRes = -1;
202  break;
203  }
204  case RESUNIT_INCH:
205  {
206  xRes = 2.54e8/dirHead[0].xTiffRes;
207  yRes = 2.54e8/dirHead[0].yTiffRes;
208  break;
209  }
210  case RESUNIT_CENTIMETER:
211  {
212  xRes = 1e8/dirHead[0].xTiffRes;
213  yRes = 1e8/dirHead[0].yTiffRes;
214  break;
215  }
216  }
217  }
218 
219  // cast image data to image class datatypes
220  ArrayDim aDim;
221 
222  size_t imgStart = IMG_INDEX(select_img);
223 
224  aDim.xdim = (int) dirHead[imgStart].imageWidth;
225  aDim.ydim = (int) dirHead[imgStart].imageLength;
226  aDim.zdim = 1;
227  aDim.ndim = replaceNsize = (select_img == ALL_IMAGES)? dirHead.size() : 1;
228  setDimensions(aDim);
229 
230  size_t imgEnd = (select_img != ALL_IMAGES) ? imgStart + 1 : aDim.ndim;
231 
232  DataType datatype = datatypeTIFF(dirHead[0]);
233 
234  //Set main header
239 
240  //Read header only
241  if( dataMode < DATA ||( dataMode == _HEADER_ALL && aDim.ndim > 1) )
242  return 0;
243 
244  /* As we cannot mmap a TIFF File, when this option is passed we are going to mmap
245  * the multidimarray of Image
246  */
247  if (mmapOnRead)
248  {
249  mmapOnRead = false;
250  if (aDim.nzyxdim*gettypesize(datatype) > tiff_map_min_size)
251  mdaBase->setMmap(true);
252  }
253 
254  // Allocate memory for image data (Assume xdim, ydim, zdim and ndim are already set
255  //if memory already allocated use it (no resize allowed)
257 
258  size_t pad = aDim.yxdim;
259  int imReaded = 0;
260 
261  MD.clear();
262  for (size_t i = 0; i < aDim.ndim; i++)
263  MD.push_back(std::unique_ptr<MDRowVec>(new MDRowVec(MDL::emptyHeaderVec())));
264 
265  uint32_t rowsperstrip;
266  tsize_t scanline;
267 
268  unsigned int x, y;
269  // Dimensions of tiles
270  unsigned int tileWidth, tileLength;
271  tileWidth = tileLength = 0;
272 
273  for (size_t i = imgStart; i < imgEnd; ++i)
274  {
275  TIFFSetDirectory(tif,(tdir_t) i);
276 
277  // If samplesPerPixel is higher than 3 it means there are extra samples, as associated alpha data
278  // Greyscale images are usually samplesPerPixel=1
279  // RGB images are usually samplesPerPixel=3 (this is only implemented for untiled 8-bit tiffs)
280  if (dirHead[i].samplesPerPixel > 3)
281  dirHead[i].samplesPerPixel = 1;
282 
283  if (TIFFIsTiled(tif))
284  {
285  TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tileWidth);
286  TIFFGetField(tif, TIFFTAG_TILELENGTH,&tileLength);
287  tif_buf = (char*)_TIFFmalloc(TIFFTileSize(tif));
288  }
289  else
290  {
291  TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
292  scanline = TIFFScanlineSize(tif);
293  tif_buf = (char*)_TIFFmalloc(scanline);
294  }
295  if (tif_buf == 0)
296  {
297  TIFFError(TIFFFileName(tif), "No space for strip buffer");
298  exit(-1);
299  }
300 
301  /* Start to convert the TIFF image to type T */
302 
303  datatype = datatypeTIFF(dirHead[i]);
304 
305  if (TIFFIsTiled(tif))
306  {
307  for (y = 0; y < dirHead[0].imageLength; y += tileLength)
308  for (x = 0; x < dirHead[0].imageWidth; x += tileWidth)
309  {
310  TIFFReadTile(tif, tif_buf, x, y, 0, 0);
311  if (swap)
312  swapPage((char*)tif_buf, TIFFTileSize(tif)*sizeof(unsigned char), datatype);
313 
314  castTiffTile2T((pad*imReaded), tif_buf, x, y,
315  dirHead[i].imageWidth, dirHead[i].imageLength,
316  tileWidth, tileLength,
317  dirHead[i].samplesPerPixel,
318  datatype);
319  }
320  }
321  else
322  {
323  for (y = 0; y < dirHead[i].imageLength; y++)
324  {
325  TIFFReadScanline(tif, tif_buf, y);
326  castTiffLine2T((pad*imReaded), tif_buf, y,
327  dirHead[i].imageWidth, dirHead[i].imageLength,
328  dirHead[i].samplesPerPixel,
329  datatype);
330  }
331  }
332 
333  ++imReaded;
334  _TIFFfree(tif_buf);
335  }
336  return 0;
337 }
uint16_t pNumber
Definition: rwTIFF.h:45
Index out of bounds.
Definition: xmipp_error.h:132
unsigned int subFileType
Definition: rwTIFF.h:44
sampling rate in A/pixel (double)
size_t xdim
float xTiffRes
Definition: rwTIFF.h:43
sampling rate in A/pixel (double)
DataMode dataMode
#define REPORT_ERROR(nerr, ErrormMsg)
Definition: xmipp_error.h:211
virtual void coreAllocateReuse()=0
static double * y
unsigned short samplesPerPixel
Definition: rwTIFF.h:38
void setValue(const MDObject &object) override
void swapPage(char *page, size_t pageNrElements, DataType datatype, int swap=1)
std::vector< std::unique_ptr< MDRow > > MD
unsigned int imageWidth
Definition: rwTIFF.h:39
unsigned int imageLength
Definition: rwTIFF.h:40
void castTiffTile2T(size_t offset, char *tif_buf, unsigned int x, unsigned int y, unsigned int imageWidth, unsigned int imageLength, unsigned int tileWidth, unsigned int tileLength, unsigned short samplesPerPixel, DataType datatype)
Definition: rwTIFF.cpp:38
if read from file original image datatype, this is an struct defined in image
void castTiffLine2T(size_t offset, char *tif_buf, unsigned int y, unsigned int imageWidth, unsigned int imageLength, unsigned short samplesPerPixel, DataType datatype)
Definition: rwTIFF.cpp:67
unsigned short resUnit
Definition: rwTIFF.h:42
float yTiffRes
Definition: rwTIFF.h:43
doublereal * x
#define i
size_t nzyxdim
size_t zdim
const size_t tiff_map_min_size
void setMmap(bool mmap)
virtual void setDimensions(int Xdim, int Ydim, int Zdim, size_t Ndim)=0
size_t yxdim
DataType datatypeTIFF(TIFFDirHead dHead)
Definition: rwTIFF.cpp:85
unsigned short bitsPerSample
Definition: rwTIFF.h:37
Couldn&#39;t read from file.
Definition: xmipp_error.h:139
static MDRowVec emptyHeaderVec()
DataType
MDRowVec MDMainHeader
size_t ndim
DataType datatype() const
#define ALL_IMAGES
String formatString(const char *format,...)
uint16_t pTotal
Definition: rwTIFF.h:45
#define IMG_INDEX(select_img)
size_t ydim
FileName filename
uint16_t imageSampleFormat
Definition: rwTIFF.h:41
void clear() override
size_t replaceNsize
MultidimArrayBase * mdaBase
size_t gettypesize(DataType type)
Returns memory size of datatype.

◆ writeTIFF() [1/2]

int writeTIFF ( size_t  select_img,
bool  isStack = false,
int  mode = WRITE_OVERWRITE,
String  bitDepth = "",
CastWriteMode  castMode = CW_CAST 
)

Write TIFF format files.

◆ writeTIFF() [2/2]

int ImageBase::writeTIFF ( size_t  select_img,
bool  isStack = false,
int  mode = WRITE_OVERWRITE,
String  bitDepth = "",
CastWriteMode  castMode = CW_CAST 
)
protected

Write TIFF format files.

Definition at line 342 of file rwTIFF.cpp.

343 {
344 #undef DEBUG
345 
346  if (isComplexT())
347  {
348  REPORT_ERROR(ERR_TYPE_INCORRECT,"rwTIFF: Complex images are not supported by TIFF format.");
349  return 0;
350  }
351 
352  ArrayDim aDim;
353  mdaBase->getDimensions(aDim);
354 
355  // Volumes are not supported
356  if (aDim.zdim > 1)
357  REPORT_ERROR(ERR_MULTIDIM_DIM, "writeTIFF does not support volumes.");
358  // TIFF cannot open a file to read/write at the same time, so the file must be overwritten
359  // if (mode != WRITE_OVERWRITE)
360  // REPORT_ERROR(ERR_VALUE_INCORRECT, "writeTIFF: LIBTIFF cannot modify an existing file, only overwrite it.");
361 
362  TIFFDirHead dhMain; // Main header
363 
364  //Selection of output datatype
365 
366  DataType wDType,myTypeID = myT();
367 
368  if (bitDepth == "")
369  {
370  castMode = CW_CAST;
371  switch(myTypeID)
372  {
373  case DT_Double:
374  case DT_Float:
375  wDType = DT_Float;
376  dhMain.imageSampleFormat = SAMPLEFORMAT_IEEEFP;
377  break;
378  case DT_Int:
379  castMode = CW_CONVERT;
380  case DT_UInt:
381  wDType = DT_UInt;
382  dhMain.imageSampleFormat = SAMPLEFORMAT_UINT;
383  break;
384  case DT_Short:
385  castMode = CW_CONVERT;
386  case DT_UShort:
387  wDType = DT_UShort;
388  dhMain.imageSampleFormat = SAMPLEFORMAT_UINT;
389  break;
390  case DT_SChar:
391  castMode = CW_CONVERT;
392  case DT_UChar:
393  wDType = DT_UChar;
394  dhMain.imageSampleFormat = SAMPLEFORMAT_UINT;
395  break;
396  default:
397  wDType = DT_Unknown;
398  (void)wDType; // to suppress dead assignment warning
399  REPORT_ERROR(ERR_TYPE_INCORRECT,formatString("rwTIFF: cannot write TIFF format from %s\
400  datatype.",datatype2Str(myTypeID).c_str()));
401  }
402  }
403  else
404  {
405  // Default Value
406  wDType = (bitDepth == "default") ? DT_UChar : datatypeRAW(bitDepth);
407 
408  switch(wDType)
409  {
410  case DT_Float:
411  dhMain.imageSampleFormat = SAMPLEFORMAT_IEEEFP;
412  break;
413  case DT_UInt:
414  case DT_UShort:
415  case DT_UChar:
416  dhMain.imageSampleFormat = SAMPLEFORMAT_UINT;
417  break;
418  default:
419  wDType = DT_Unknown;
420  (void)wDType; // to suppress dead assignment warning
421  REPORT_ERROR(ERR_TYPE_INCORRECT,formatString("rwTIFF: TIFF format does not support %s " \
422  "datatype.",datatype2Str(myTypeID).c_str()));
423  }
424  }
425 
426  if (mmapOnWrite)
427  {
428  /* As we cannot mmap a TIFF File, when this option is passed we are going to mmap
429  * the multidimarray of Image
430  */
431  mmapOnWrite = false;
432  dataMode = DATA;
433  MDMainHeader.setValue(MDL_DATATYPE,(int) myTypeID);
434 
435  if (mdaBase->nzyxdim*gettypesize(myTypeID) > tiff_map_min_size)
436  mdaBase->setMmap(true);
437 
438  // Allocate memory for image data (Assume xdim, ydim, zdim and ndim are already set
439  //if memory already allocated use it (no resize allowed)
440 
442 
443  return 0;
444  }
445 
446  int nBytes = gettypesize(wDType);
447 
448  /* Set TIFF image properties */
449  dhMain.bitsPerSample = (unsigned short int) nBytes*8;
450  dhMain.samplesPerPixel = 1;
451  dhMain.imageWidth = aDim.xdim;
452  dhMain.imageLength = aDim.ydim;
453  dhMain.resUnit = RESUNIT_CENTIMETER;
454 
455  double aux=1.0;
456 
457  if (!MDMainHeader.empty())
458  {
459  dhMain.xTiffRes = (MDMainHeader.getValue(MDL_SAMPLINGRATE_X, aux)) ? (float) 1e8/aux : 0. ;
460  dhMain.yTiffRes = (MDMainHeader.getValue(MDL_SAMPLINGRATE_X, aux)) ? (float) 1e8/aux : 0. ;
461  }
462  else
463  {
464  dhMain.xTiffRes = 1.0;
465  dhMain.yTiffRes = 1.0;
466  }
467 
468  size_t imgStart = (mode == WRITE_APPEND)? replaceNsize : IMG_INDEX(select_img);
469 
470  size_t bufferSize, datasize_n;
471  bufferSize = aDim.xdim*nBytes;
472  datasize_n = aDim.zyxdim;
473 
474  char* tif_buf;
475 
476  if ((tif_buf = (char*)_TIFFmalloc(bufferSize)) == 0)
477  {
478  TIFFError(TIFFFileName(tif), "No space for strip buffer");
479  exit(-1);
480  }
481 
482  //Write each image in a directory
483  for (size_t i = 0; i < aDim.ndim; i++ )
484  {
485  TIFFSetDirectory(tif,(tdir_t) i + imgStart);
486 
487  // Image header
488  TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, dhMain.bitsPerSample);
489  TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL,dhMain.samplesPerPixel);
490  TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, dhMain.imageSampleFormat);
491  TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, dhMain.imageWidth);
492  TIFFSetField(tif, TIFFTAG_IMAGELENGTH, dhMain.imageLength);
493  TIFFSetField(tif, TIFFTAG_RESOLUTIONUNIT, dhMain.resUnit);
494  TIFFSetField(tif, TIFFTAG_XRESOLUTION, dhMain.xTiffRes);
495  TIFFSetField(tif, TIFFTAG_YRESOLUTION, dhMain.yTiffRes);
496  TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK);
497  TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_NONE);
498  TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, dhMain.imageLength);
499  TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
500  TIFFSetField(tif, TIFFTAG_SOFTWARE, "Xmipp 3.0");
501 
502  if (aDim.ndim == 1 && isStack == false)
503  {
504  TIFFSetField(tif, TIFFTAG_SUBFILETYPE, (unsigned int) 0x0);
505  TIFFSetField(tif, TIFFTAG_PAGENUMBER, (uint16_t) 0, (uint16_t) 0);
506  }
507  else
508  {
509  TIFFSetField(tif, TIFFTAG_SUBFILETYPE, (unsigned int) 0x2);
510  TIFFSetField(tif, TIFFTAG_PAGENUMBER, (uint16_t) i, (uint16_t) aDim.ndim);
511  }
512 
513  // Only write images when needed
514  if (dataMode >= DATA)
515  {
516  double min0, max0;
517 
518  if (castMode != CW_CAST)
519  mdaBase->computeDoubleMinMaxRange(min0, max0, i*datasize_n, datasize_n);
520 
521  for (uint32_t y = 0; y < aDim.ydim; y++)
522  {
523  if (castMode == CW_CAST)
524  getPageFromT(i*datasize_n + y*aDim.xdim, (char *)tif_buf, wDType, (size_t) aDim.xdim);
525  else
526  getCastConvertPageFromT(i*datasize_n + y*aDim.xdim,
527  (char *)tif_buf, wDType, (size_t) aDim.xdim, min0, max0, castMode);
528 
529  TIFFWriteScanline(tif, tif_buf,y,0);
530  }
531  }
532 
533  TIFFWriteDirectory(tif);
534  }
535 
536  _TIFFfree(tif_buf);
537  return(0);
538 }
std::string datatype2Str(DataType datatype)
size_t xdim
float xTiffRes
Definition: rwTIFF.h:43
sampling rate in A/pixel (double)
DataMode dataMode
#define REPORT_ERROR(nerr, ErrormMsg)
Definition: xmipp_error.h:211
virtual void coreAllocateReuse()=0
static double * y
unsigned short samplesPerPixel
Definition: rwTIFF.h:38
void setValue(const MDObject &object) override
unsigned int imageWidth
Definition: rwTIFF.h:39
unsigned int imageLength
Definition: rwTIFF.h:40
if read from file original image datatype, this is an struct defined in image
unsigned short resUnit
Definition: rwTIFF.h:42
float yTiffRes
Definition: rwTIFF.h:43
#define i
T & getValue(MDLabel label)
virtual void computeDoubleMinMaxRange(double &minval, double &maxval, size_t offset, size_t size) const =0
#define x0
size_t zdim
const size_t tiff_map_min_size
virtual void getPageFromT(size_t offset, char *page, DataType datatype, size_t pageSize)=0
void setMmap(bool mmap)
size_t zyxdim
virtual bool isComplexT() const =0
unsigned short bitsPerSample
Definition: rwTIFF.h:37
DataType
void mode
MDRowVec MDMainHeader
size_t ndim
virtual void getCastConvertPageFromT(size_t offset, char *page, DataType datatype, size_t pageSize, double min0, double max0, CastWriteMode castMode=CW_CONVERT) const =0
String formatString(const char *format,...)
bool empty() const override
#define IMG_INDEX(select_img)
size_t ydim
Incorrect MultidimArray dimensions.
Definition: xmipp_error.h:173
virtual DataType myT() const =0
Incorrect type received.
Definition: xmipp_error.h:190
uint16_t imageSampleFormat
Definition: rwTIFF.h:41
size_t replaceNsize
MultidimArrayBase * mdaBase
DataType datatypeRAW(String strDT)
Definition: rwRAW.cpp:31
size_t gettypesize(DataType type)
Returns memory size of datatype.
void getDimensions(size_t &Xdim, size_t &Ydim, size_t &Zdim, size_t &Ndim) const