cmtkFileFormat.cxx

Go to the documentation of this file.
00001 /*
00002 //
00003 //  Copyright 1997-2009 Torsten Rohlfing
00004 //
00005 //  Copyright 2004-2010 SRI International
00006 //
00007 //  This file is part of the Computational Morphometry Toolkit.
00008 //
00009 //  http://www.nitrc.org/projects/cmtk/
00010 //
00011 //  The Computational Morphometry Toolkit is free software: you can
00012 //  redistribute it and/or modify it under the terms of the GNU General Public
00013 //  License as published by the Free Software Foundation, either version 3 of
00014 //  the License, or (at your option) any later version.
00015 //
00016 //  The Computational Morphometry Toolkit is distributed in the hope that it
00017 //  will be useful, but WITHOUT ANY WARRANTY; without even the implied
00018 //  warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019 //  GNU General Public License for more details.
00020 //
00021 //  You should have received a copy of the GNU General Public License along
00022 //  with the Computational Morphometry Toolkit.  If not, see
00023 //  <http://www.gnu.org/licenses/>.
00024 //
00025 //  $Revision: 2398 $
00026 //
00027 //  $LastChangedDate: 2010-10-05 14:54:37 -0700 (Tue, 05 Oct 2010) $
00028 //
00029 //  $LastChangedBy: torstenrohlfing $
00030 //
00031 */
00032 
00033 #include "cmtkFileFormat.h"
00034 
00035 #include <Base/cmtkTypes.h>
00036 #include <System/cmtkCompressedStream.h>
00037 
00038 #ifdef HAVE_SYS_TYPES_H
00039 #  include <sys/types.h>
00040 #endif
00041 
00042 #ifdef HAVE_SYS_STAT_H
00043 #  include <sys/stat.h>
00044 #endif
00045 
00046 #include <stdio.h>
00047 #include <string.h>
00048 #include <limits.h>
00049 
00050 namespace
00051 cmtk
00052 {
00053 
00056 
00058 typedef 
00059 struct
00060 {
00062   unsigned short offset;
00064   const char *magicString;
00066   const size_t magicStringLength;
00067 } FileFormatMagic;
00068 
00070 const FileFormatMagic FileFormatMagicNumbers[] = {
00071   { 0, NULL, 0 }, // NEXIST
00072   { 0, NULL, 0 }, // ARCHIVE
00073   { 0, NULL, 0 }, // STUDY
00074   { 0, NULL, 0 }, // STUDYLIST
00075   { 0, "! TYPEDSTREAM", 13 }, // TypedStream archive
00076   { 0, "P5", 2 }, // PGM
00077   { 128, "DICM", 4 }, // DICOM
00078   { 0, "Modality :=", 11 }, // VANDERBILT
00079   { 0, "# AmiraMesh 3D", 14 },
00080   { 0, NULL, 0 }, // RAW
00081   { 0, NULL, 0 }, // RAW3D
00082   { 54, "\x39\x30", 2 }, // BIORAD
00083   { 344, "ni1\x00", 4 }, // Nifti, detached header
00084   { 344, "n+1\x00", 4 }, // Nifti, single file
00085   { 0, "AVW_ImageFile", 13 }, // Analyze AVW file.
00086   { 0, NULL, 0 }, // MetaImage
00087   { 0, "NRRD", 4 }, //NRRD
00088   { 0, "\x5C\x01\x00\x00", 4 }, // Analyze little endian
00089   { 0, "\x00\x00\x01\x5C", 4 }, // Analyze big endian
00090   { 0, "#Insight Transform File V1.0", 28 }, // ITK transformation file
00091   { 0, NULL, 0 }  // Unknown.
00092 };
00093 
00094 const char* FileFormatName[] =
00095 {
00097   "",
00099   "COMPRESSED-ARCHIVE",
00101   "STUDY",
00103   "STUDYLIST",
00105   "TYPEDSTREAM",
00107   "PGM",
00109   "DICOM",
00111   "VANDERBILT",
00113   "AMIRA",
00115   "RAW-DATA",
00117   "RAW3D",
00119   "BIORAD",
00121   "NIFTI-DETACHED-HEADER",
00123   "NIFTI-SINGLE-FILE",
00125   "ANALYZE-AVW",
00127   "METAIMAGE",
00129   "NRRD",
00131   "ANALYZE-HDR-LITTLEENDIAN",
00133   "ANALYZE-HDR-BIGENDIAN",
00137   NULL
00138 };
00139 
00140 FileFormatID 
00141 FileFormat::Identify( const char* path, const bool decompress )
00142 {
00143   struct stat buf;
00144   if ( CompressedStream::Stat( path, &buf ) < 0 ) 
00145     return FILEFORMAT_NEXIST;
00146 
00147   if ( buf.st_mode & S_IFDIR ) 
00148     return FileFormat::IdentifyDirectory( path );
00149   else if ( buf.st_mode & S_IFREG ) 
00150     return FileFormat::IdentifyFile( path, decompress );
00151 
00152   return FILEFORMAT_NEXIST;
00153 }
00154 
00155 FileFormatID 
00156 FileFormat::GetID( const char* name )
00157 {
00158   if ( name ) 
00159     {
00160     for ( unsigned int idx = 0; FileFormatName[idx]; ++idx ) 
00161       {
00162       if ( ! strcmp( FileFormatName[idx], name ) )
00163         return static_cast<FileFormatID>( idx );
00164       }
00165     }
00166   return FILEFORMAT_UNKNOWN;
00167 }
00168 
00169 const char* 
00170 FileFormat::Describe( const FileFormatID id )
00171 {
00172   switch ( id ) 
00173     {
00174     case FILEFORMAT_NEXIST:
00175       return "File or directory does not exist.";
00176     case FILEFORMAT_STUDY:
00177       return "Typedstream study archive [Directory].";
00178     case FILEFORMAT_STUDYLIST:
00179       return "Typedstream studylist archive [Directory].";
00180     case FILEFORMAT_PGM:
00181       return "PGM image file [File].";
00182     case FILEFORMAT_DICOM:
00183       return "DICOM image file [File].";
00184     case FILEFORMAT_VANDERBILT:
00185       return "Vanderbilt header/image file combination [File].";
00186     case FILEFORMAT_AMIRA:
00187       return "AmiraMesh image file [File].";
00188     case FILEFORMAT_BIORAD:
00189       return "BioRad image file [File].";
00190     case FILEFORMAT_NIFTI_DETACHED:
00191       return "NIFTI detached header+image [File]";      
00192     case FILEFORMAT_NIFTI_SINGLEFILE:
00193       return "NIFTI single file [File]";      
00194     case FILEFORMAT_ANALYZE_HDR:
00195       return "Analyze 7.5 file [Header+Binary File/Little Endian].";
00196     case FILEFORMAT_ANALYZE_HDR_BIGENDIAN:
00197       return "Analyze 7.5 file [Header+Binary File/Big Endian].";
00198     case FILEFORMAT_ANALYZE_AVW:
00199       return "Analyze AVW file [File].";
00200     case FILEFORMAT_RAW:
00201       return "RAW image file [File].";
00202     case FILEFORMAT_NRRD:
00203       return "Nrrd image file [File].";
00204     case FILEFORMAT_UNKNOWN:
00205     default:
00206       return "Unknown format.";
00207     }
00208   return "ILLEGAL ID tag in FileFormat::Describe().";
00209 }
00210 
00211 FileFormatID 
00212 FileFormat::IdentifyDirectory( const char* path )
00213 {
00214   char filename[PATH_MAX];
00215   struct stat buf;
00216 
00217   snprintf( filename, sizeof( filename ), "%s/images", path );
00218   if ( (!stat( filename, &buf )) && ( buf.st_mode & S_IFREG ) )
00219     return FILEFORMAT_STUDY;
00220 
00221   snprintf( filename, sizeof( filename ), "%s/images.gz", path );
00222   if ( (!stat( filename, &buf )) && ( buf.st_mode & S_IFREG ) )
00223     return FILEFORMAT_STUDY;
00224 
00225   snprintf( filename, sizeof( filename ), "%s/studylist", path );
00226   if ( (!stat( filename, &buf )) && ( buf.st_mode & S_IFREG ) )
00227     return FILEFORMAT_STUDYLIST;
00228 
00229   snprintf( filename, sizeof( filename ), "%s/studylist.gz", path );
00230   if ( (!stat( filename, &buf )) && ( buf.st_mode & S_IFREG ) )
00231     return FILEFORMAT_STUDYLIST;
00232 
00233   return FILEFORMAT_UNKNOWN;
00234 }
00235 
00236 FileFormatID 
00237 FileFormat::IdentifyFile( const char* path, const bool decompress )
00238 {
00239   CompressedStream stream( path );
00240   if ( ! stream.IsValid() )
00241     return FILEFORMAT_NEXIST;
00242 
00243   if ( stream.IsCompressed() && !decompress )
00244     return FILEFORMAT_COMPRESSED_ARCHIVE;
00245     
00246   char buffer[348];
00247   memset( buffer, 0, sizeof( buffer ) );
00248   stream.Read( buffer, 1, 348 );
00249   
00250   FileFormatID id = FILEFORMAT_NEXIST; 
00251   while ( id != FILEFORMAT_UNKNOWN ) 
00252     {
00253     if ( FileFormatMagicNumbers[id].magicString ) 
00254       {
00255       if ( !memcmp( buffer+FileFormatMagicNumbers[id].offset, FileFormatMagicNumbers[id].magicString, FileFormatMagicNumbers[id].magicStringLength ) )
00256         return id;
00257       }
00258     char cid = static_cast<char>( id );
00259     id = static_cast<FileFormatID>( ++cid );
00260     }
00261   
00262   return FILEFORMAT_UNKNOWN;
00263 }
00264 
00265 } // namespace cmtk
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines