Orfeo Toolbox  3.16
itkIPLCommonImageIO.cxx
Go to the documentation of this file.
1 /*=========================================================================
2 
3  Program: Insight Segmentation & Registration Toolkit
4  Module: $RCSfile: itkIPLCommonImageIO.cxx,v $
5  Language: C++
6  Date: $Date: 2008-01-24 16:04:39 $
7  Version: $Revision: 1.50 $
8 
9  Copyright (c) Insight Software Consortium. All rights reserved.
10  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.
11 
12  This software is distributed WITHOUT ANY WARRANTY; without even
13  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14  PURPOSE. See the above copyright notices for more information.
15 
16 =========================================================================*/
17 #ifdef _MSC_VER
18 #pragma warning ( disable : 4786 )
19 #pragma warning ( disable : 4284 ) // return type for 'identifier::operator ->'
20  // is not a UDT or reference
21 #endif
22 
23 #include <itksys/SystemTools.hxx>
24 #include "itkIOCommon.h"
25 #include "itkIPLCommonImageIO.h"
26 #include "itkExceptionObject.h"
27 #include "itkByteSwapper.h"
28 #include "itkGEImageHeader.h"
30 //#include "idbm_hdr_def.h"
31 #include "itkDirectory.h"
32 #include "itkMetaDataObject.h"
33 #include <iostream>
34 #include <fstream>
35 #include <string.h>
36 #include <limits.h>
37 #include <stdlib.h>
38 #include <stdio.h>
39 #include <time.h>
40 #include <assert.h>
41 #include <vector>
42 #ifdef __BORLANDC__
43 #include <dxtmpl.h>
44 #endif
45 
46 //From uiig library "The University of Iowa Imaging Group-UIIG"
47 
48 namespace itk
49 {
50 // Default constructor
52 {
55  m_ImageHeader = 0;
57 }
58 
60 {
61  if(m_ImageHeader != 0)
62  {
63  delete m_ImageHeader;
64  }
65  delete m_FilenameList;
66 }
67 
68 void IPLCommonImageIO::PrintSelf(std::ostream& os, Indent indent) const
69 {
70  Superclass::PrintSelf(os, indent);
71 }
72 
73 bool IPLCommonImageIO::CanWriteFile(const char * )
74 {
75  return false;
76 }
77 
78 const std::type_info& IPLCommonImageIO::GetPixelTypeInfo() const
79 {
80  return typeid(short int);
81 }
82 
83 const std::type_info& IPLCommonImageIO::GetComponentTypeInfo() const
84 {
85  return typeid(short int);
86 }
87 
89 {
90  return sizeof(short int);
91 }
92 #ifdef __THIS_CODE_BELONGS_ELSEWHERE__
93 static void SwapZeroCornerToIRP(const itk::IOCommon::ValidOriginFlags original, short int * const imageBuffer, const int XDim, const int YDim, const int ZDim)
94 {
95  short int *** pntrs = new (short int **) [ZDim];
96  for (int k=0;k<ZDim;k++)
97  {
98  pntrs[k] = new (short int *) [YDim];
99  for(int j=0; j<YDim;j++)
100  {
101  pntrs[k][j] = &(imageBuffer[k*(XDim*YDim)+j*XDim]);
102  }
103  }
104  // Apply three possible flips to the buffer.
105  // The 'Half variables are loop limits in the case of folding.
106  int ZHalf = ZDim/2;
107  switch (original)
108  {
113  //break;
114  for (int k=0;k<ZHalf;k++)
115  {
116  for(int j=0; j<YDim;j++)
117  {
118  for(int i=0; i<XDim;i++)
119  {
120  const short int temp = pntrs[k][j][i];
121  pntrs[k][j][i] = pntrs[ZDim-k-1][j][i];
122  pntrs[ZDim-k-1][j][i] = temp;
123 
124  }
125  }
126  }
127  break;
132  default:
133  break;
134  }
135  int YHalf = YDim/2;
136  switch (original)
137  {
142  //break;
143  for (int k=0;k<ZDim;k++)
144  {
145  for(int j=0; j<YHalf;j++)
146  {
147  for(int i=0; i<XDim;i++)
148  {
149  const short int temp = pntrs[k][j][i];
150  pntrs[k][j][i] = pntrs[k][YDim-j-1][i];
151  pntrs[k][YDim-j-1][i] = temp;
152 
153  }
154  }
155  }
156  break;
161  default:
162  break;
163  }
164  int XHalf = XDim/2;
165  switch (original)
166  {
171  //break;
172  for (int k=0;k<ZDim;k++)
173  {
174  for(int j=0; j<YDim;j++)
175  {
176  for(int i=0; i<XHalf;i++)
177  {
178  const short int temp = pntrs[k][j][i];
179  pntrs[k][j][i] = pntrs[k][j][XDim-i-1];
180  pntrs[k][j][XDim-i-1] = temp;
181 
182  }
183  }
184  }
185  break;
190  default:
191  break;
192  }
193 }
194 #endif
195 void IPLCommonImageIO::Read(void* buffer)
196 {
197  short int *img_buffer = (short int *)buffer;
200 
201  for(;it != itend; it++)
202  {
203  std::string curfilename = (*it)->GetImageFileName();
204  std::ifstream f(curfilename.c_str(),std::ios::binary | std::ios::in);
205 
206  if(!f.is_open())
207  RAISE_EXCEPTION();
208  f.seekg ((*it)->GetSliceOffset(), std::ios::beg);
209  if(!this->ReadBufferAsBinary(f, img_buffer, m_FilenameList->GetXDim() * m_FilenameList->GetYDim() * sizeof(short int)))
210  {
211  f.close();
212  RAISE_EXCEPTION();
213  }
214  f.close();
215  // ByteSwapper::SwapRangeFromSystemToBigEndian is set up based on
216  // the FILE endian-ness, not as the name would lead you to believe.
217  // So, on LittleEndian systems, SwapFromSystemToBigEndian will swap.
218  // On BigEndian systems, SwapFromSystemToBigEndian will do nothing.
220  img_buffer += m_FilenameList->GetXDim() * m_FilenameList->GetYDim();
221  }
222 #if 0 // Debugging
223  std::ofstream f2("test.img",std::ios::binary | std::ios::out);
224  f2.write(buffer,(m_FilenameList->numImageInfoStructs *
225  m_FilenameList->GetXDim() * m_FilenameList->GetYDim() * sizeof(short int)));
226  f2.close();
227 #endif
228 }
229 
231 {
232  //
233  // must be redefined in a child class
234  //
235  return 0;
236 }
237 
238 bool IPLCommonImageIO::CanReadFile( const char* )
239 {
240  //
241  // must be redefined in child class or you'll never read anything ;-)
242  //
243  return false;
244 }
245 
247 {
248  std::string FileNameToRead = this->GetFileName();
249  //
250  // GE images are stored in separate files per slice.
251  //char imagePath[IOCommon::ITK_MAXPATHLEN+1];
252  //TODO -- use std::string instead of C strings
253  char imageMask[IOCommon::ITK_MAXPATHLEN+1];
254  char imagePath[IOCommon::ITK_MAXPATHLEN+1];
255  std::string _imagePath =
256  itksys::SystemTools::CollapseFullPath(FileNameToRead.c_str());
257 
258  FileNameToRead = _imagePath;
259 
260  this->m_ImageHeader = this->ReadHeader(FileNameToRead.c_str());
261  //
262  // if anything fails in the header read, just let
263  // exceptions propogate up.
264 
272 
273  // Add header info to metadictionary
274 
276  std::string classname(this->GetNameOfClass());
277  itk::EncapsulateMetaData<std::string>(thisDic,ITK_InputFilterName, classname);
278  itk::EncapsulateMetaData<std::string>(thisDic, ITK_OnDiskStorageTypeName, std::string("SHORT"));
279  itk::EncapsulateMetaData<short int>(thisDic,ITK_OnDiskBitPerPixel,(short int)16);
280 
281 #if defined(ITKIO_DEPRECATED_METADATA_ORIENTATION)
282  itk::EncapsulateMetaData<itk::SpatialOrientation::ValidCoordinateOrientationFlags>(thisDic,ITK_CoordinateOrientation,m_ImageHeader->coordinateOrientation);
283 #endif
284  //
285  // has to be set before setting dir cosines,
286  // otherwise the vector doesn't get allocated
287  this->SetNumberOfDimensions(3);
288 
289  itk::EncapsulateMetaData<std::string>(thisDic,ITK_PatientID,std::string(m_ImageHeader->patientId));
290  itk::EncapsulateMetaData<std::string>(thisDic,ITK_ExperimentDate,std::string(m_ImageHeader->date));
291 
292 
293  if(_imagePath == "")
294  RAISE_EXCEPTION();
295  strncpy(imagePath,_imagePath.c_str(),sizeof(imagePath));
296  imagePath[IOCommon::ITK_MAXPATHLEN] = '\0';
297  strncpy(imageMask,imagePath,sizeof(imageMask));
298  imageMask[IOCommon::ITK_MAXPATHLEN] = '\0';
299 
300  char *lastslash = strrchr(imagePath,'/');
301  if(lastslash == NULL)
302  {
303  strcpy(imagePath,".");
304  }
305  else
306  {
307  *lastslash = '\0';
308  }
310  if(Dir->Load(imagePath) == 0)
311  {
312  RAISE_EXCEPTION();
313  }
314  std::vector<std::string>::size_type i;
315  std::vector<std::string>::size_type numfiles;
316 
317  GEImageHeader *curImageHeader;
318 
319  for(i = 0, numfiles = Dir->GetNumberOfFiles(); i < numfiles; i++)
320  {
321  const char *curFname = Dir->GetFile(i);
322  char fullPath[IOCommon::ITK_MAXPATHLEN+1];
323  sprintf(fullPath,"%s/%s",imagePath,curFname);
324 
325  if(curFname == 0)
326  {
327  break;
328  }
329  else if (FileNameToRead == fullPath) //strcmp(curFname,FileNameToRead) == 0)
330  {
331  continue;
332  }
333  try
334  {
335  curImageHeader = this->ReadHeader(fullPath);
336  }
337  catch (itk::ExceptionObject &)
338  {
339  // ReadGE4XHeader throws an exception on any error.
340  // So if, for example we run into a subdirectory, it would
341  // throw an exception, and we'd just want to skip it.
342  continue;
343  }
344  if(curImageHeader->echoNumber == m_FilenameList->GetKey2() &&
345  curImageHeader->seriesNumber == m_FilenameList->GetKey1())
346  {
347  AddElementToList(curImageHeader->filename,
348  curImageHeader->sliceLocation,
349  curImageHeader->offset,
350  curImageHeader->imageXsize,
351  curImageHeader->imageYsize,
352  curImageHeader->seriesNumber,
353  curImageHeader->echoNumber);
354  }
355  delete curImageHeader;
356  }
357 
358  //sort image list
360 
361  //
362  //
363  // set the image properties
370 
371  //
372  // set direction cosines
373  typedef SpatialOrientationAdapter OrientAdapterType;
375  = OrientAdapterType().ToDirectionCosines(m_ImageHeader->coordinateOrientation);
376  std::vector<double> dirx(3,0), diry(3,0), dirz(3,0);
377  dirx[0] = dir[0][0];
378  dirx[1] = dir[1][0];
379  dirx[2] = dir[2][0];
380  diry[0] = dir[0][1];
381  diry[1] = dir[1][1];
382  diry[2] = dir[2][1];
383  dirz[0] = dir[0][2];
384  dirz[1] = dir[1][2];
385  dirz[2] = dir[2][2];
386 
387  this->SetDirection(0,dirx);
388  this->SetDirection(1,diry);
389  this->SetDirection(2,dirz);
390 
391  this->ModifyImageInformation();
392 
393 }
394 
395 
397 {
399 }
400 
402 {
404 }
405 
406 
410 void
413 {
414  RAISE_EXCEPTION();
415 }
416 
417 
421 void
423 ::Write( const void * )
424 {
425  RAISE_EXCEPTION();
426 }
427 
428 int
430 ::GetStringAt(std::ifstream &f,
431  std::streamoff Offset,
432  char *buf,
433  size_t amount,bool throw_exception)
434 {
435  f.seekg(Offset,std::ios::beg);
436  if( f.fail() )
437  {
438  if(throw_exception)
439  {
440  RAISE_EXCEPTION();
441  }
442  else
443  {
444  return -1;
445  }
446  }
447  if( !this->ReadBufferAsBinary( f, (void *)buf, amount ) )
448  {
449  if(throw_exception)
450  {
451  RAISE_EXCEPTION();
452  }
453  else
454  {
455  return -1;
456  }
457  }
458  return 0;
459 }
461 ::GetIntAt(std::ifstream &f,std::streamoff Offset,int *ip,
462  bool throw_exception)
463 {
464  int tmp;
465  if (this->GetStringAt(f,Offset,(char *)&tmp,sizeof(int),
466  throw_exception) == 0)
467  {
468  *ip = this->hdr2Int((char *)&tmp);
469  }
470  else
471  {
472  *ip = 0;
473  }
474  return 0;
475 }
477 ::GetShortAt(std::ifstream &f,std::streamoff Offset,short *ip,
478  bool throw_exception)
479 {
480  short tmp;
481  if (this->GetStringAt(f,Offset,(char *)&tmp,sizeof(short),
482  throw_exception) == 0)
483  {
484  *ip = this->hdr2Short((char *)&tmp);
485  }
486  else
487  {
488  *ip = 0;
489  }
490  return 0;
491 }
493 ::GetFloatAt(std::ifstream &f,std::streamoff Offset,float *ip,
494  bool throw_exception)
495 {
496  float tmp;
497  if (this->GetStringAt(f,Offset,(char *)&tmp,sizeof(float),
498  throw_exception) == 0)
499  {
500  *ip = this->hdr2Float((char *)&tmp);
501  }
502  else
503  {
504  *ip = 0.0f;
505  }
506  return 0;
507 }
509 ::GetDoubleAt(std::ifstream &f,std::streamoff Offset,double *ip,
510  bool throw_exception)
511 {
512  double tmp;
513  if (this->GetStringAt(f,Offset,(char *)&tmp,sizeof(double),
514  throw_exception) == 0)
515  {
516  *ip = this->hdr2Double((char *)&tmp);
517  }
518  else
519  {
520  *ip = 0.0;
521  }
522  return 0;
523 }
525 {
526  short shortValue;
527  memcpy (&shortValue, hdr, sizeof(short));
529  return (shortValue);
530 }
531 
533 ::hdr2Int (char *hdr)
534 {
535  int intValue;
536 
537  memcpy (&intValue, hdr, sizeof(int));
539  return (intValue);
540 }
541 
542 float IPLCommonImageIO
543 ::hdr2Float (char *hdr)
544 {
545  float floatValue;
546 
547  memcpy (&floatValue, hdr, 4);
549 
550  return (floatValue);
551 }
552 
553 double IPLCommonImageIO
554 ::hdr2Double (char *hdr)
555 {
556  double doubleValue;
557 
558  memcpy (&doubleValue, hdr, sizeof(double));
560 
561  return (doubleValue);
562 }
563 
565 ::AddElementToList(char const * const filename, const float sliceLocation, const int offset, const int XDim, const int YDim, const int Key1, const int Key2 )
566 {
567  if(m_FilenameList->NumFiles() == 0)
568  {
569  m_FilenameList->SetXDim(XDim);
570  m_FilenameList->SetYDim(YDim);
571  m_FilenameList->SetKey1(Key1);
572  m_FilenameList->SetKey2(Key2);
573  }
574  else if(XDim != m_FilenameList->GetXDim() || YDim != m_FilenameList->GetYDim() )
575  {
576  return 0;
577  }
578  else if (m_FilenameList->GetKey1() != Key1 || m_FilenameList->GetKey2() != Key2)
579  {
580  return 1; //It is OK for keys to not match, Just don't add.
581  }
582  m_FilenameList->AddElementToList(filename,sliceLocation,
583  offset,XDim,YDim,0,Key1,Key2);
584  return 1;
585 }
586 
587 void IPLCommonImageIO
589 {
590  m_FilenameList->sortImageListAscend();
591  return;
592 }
593 void IPLCommonImageIO
595 {
596  m_FilenameList->sortImageListDescend();
597  return;
598 }
600 ::statTimeToAscii (void *clock, char *timeString)
601 {
602  char *asciiTime;
603  unsigned int i;
604 #ifdef SGI
605  timespec_t *lclock;
606 #else
607 
608 #endif
609 
610 #ifdef SGI
611  lclock = (timespec_t *) clock;
612  asciiTime = ctime (&(lclock->tv_sec));
613 #else
614  time_t tclock = (time_t) *((int *) clock);
615  asciiTime = ctime (&tclock);
616 #endif
617 
618  strncpy (timeString, asciiTime, 64);
619 
620  for (i = 0; i < 26; i++)
621  {
622  if (timeString[i] == '\n')
623  {
624  timeString[i] = '\0';
625  }
626  }
627 
628  return 1;
629 
630 }
631 
632 } // end namespace itk

Generated at Sat Feb 2 2013 23:46:27 for Orfeo Toolbox with doxygen 1.8.1.1