Commit cb1059dd authored by wiebel's avatar wiebel
Browse files

[ADD] loader for NIfTI with in16_t data and some small test

 * By now the stylecheck will fail. This is because we need to exclude third party files like dataHandler/io/nifti/ from stylechecking
parent c91e658b
......@@ -4,8 +4,9 @@ ADD_SUBDIRECTORY( exceptions )
FILE( GLOB DATAHANDLER_SRC "*.cpp" "*.hpp" )
FILE( GLOB DATAHANDLER_EXCEPTIONS_SRC "exceptions/*.cpp" )
ADD_LIBRARY( dataHandler SHARED ${DATAHANDLER_SRC} ${DATAHANDLER_EXCEPTIONS_SRC} )
TARGET_LINK_LIBRARIES( dataHandler boost_thread niftiio boost_filesystem )
# Unit tests
IF( CXXTEST_FOUND )
CXXTEST_ADD_TESTS_FROM_LIST( "${DATAHANDLER_SRC}" dataHandler )
CXXTEST_ADD_TESTS_FROM_LIST( "${DATAHANDLER_SRC}" "dataHandler" )
ENDIF( CXXTEST_FOUND )
......@@ -27,6 +27,7 @@
/**
* Base class to all WLoaders which imports data from a given file and generate
* a WDataSet out of it.
* \ingroup dataHandler
*/
class WLoader
{
......
......@@ -21,5 +21,46 @@
//
//---------------------------------------------------------------------------
#include <iostream>
#include <string>
#include <boost/thread.hpp>
#include "WLoaderManager.h"
#include "WDataSet.h"
#include "WLoaderNIfTI.h"
std::string getSuffix( std::string name )
{
size_t position = name.find_last_of( '.' );
if( position == std::string::npos )
return "";
else
return name.substr( position + 1 );
}
void WLoaderManager::load( std::string fileName,
boost::shared_ptr< WDataHandler > dataHandler )
{
std::string suffix = getSuffix( fileName );
if( suffix == "nii" || suffix == "gz" )
{
WLoaderNIfTI niiLoader( fileName, dataHandler );
boost::thread loaderThread( niiLoader );
}
else if( suffix == "vtk" )
{
// This is a dummy implementation.
// You need to provide a real implementation here if you want to load vtk.
std::cout << "VTK not implemented yet" << std::endl;
assert( 0 );
}
else
{
std::cout << "Unknown file type." << std::endl;
assert( 0 );
}
}
......@@ -24,12 +24,22 @@
#ifndef WLOADERMANAGER_H
#define WLOADERMANAGER_H
#include <string>
#include <boost/shared_ptr.hpp>
class WDataSet;
class WDataHandler;
/**
* Decouples file loading from the rest of OpenWalnut into a single thread.
*/
class WLoaderManager
{
public:
/**
* Selects correct loader for fileName and creates loader thread.
*/
void load( std::string fileName, boost::shared_ptr< WDataHandler > dataHandler );
protected:
private:
};
......
......@@ -21,5 +21,78 @@
//
//---------------------------------------------------------------------------
#include <iostream>
#include <string>
#include <vector>
#include <boost/shared_ptr.hpp>
#include "WLoaderNIfTI.h"
#include "WDataHandler.h"
#include "WDataSet.h"
#include "WDataSetSingle.h"
#include "WGrid.h"
#include "WValueSetBase.h"
#include "WValueSet.hpp"
#include "WMetaInfo.h"
#include "io/nifti/nifti1_io.h"
WLoaderNIfTI::WLoaderNIfTI( std::string fileName, boost::shared_ptr< WDataHandler > dataHandler )
: m_fileName( fileName ), m_dataHandler( dataHandler )
{
}
void WLoaderNIfTI::operator()()
{
nifti_image* image = nifti_image_read( m_fileName.c_str(), 0 );
int columns = image->dim[1];
int rows = image->dim[2];
int frames = image->dim[3];
std::cout << "grid dimensions: " << columns << " " << rows << " " << frames
<< std::endl;
switch( image->datatype )
{
case DT_SIGNED_SHORT:
std::cout << "data type: DT_SIGNED_SHORT" << std::endl;
break;
default:
std::cout << "unknown data type " << image->datatype << std::endl;
assert( 0 );
}
boost::shared_ptr< WValueSetBase > newValueSet;
boost::shared_ptr<WGrid> newGrid;
nifti_image* filedata = nifti_image_read( m_fileName.c_str(), 1 );
unsigned int valueDim = image->dim[4];
unsigned int nbTens = columns * rows * frames;
unsigned int nbValues = nbTens * valueDim;
nifti_image_infodump( image );
if( image->datatype == DT_SIGNED_SHORT && valueDim == 1 )
{
std::cout << "DataType SIGNED_SHORT: " << image->datatype << std::endl;
int16_t* myImage = reinterpret_cast<int16_t*>( filedata->data );
std::vector< int16_t > data( nbValues );
for( unsigned int i = 0; i < nbValues; i++ )
{
data[i] = myImage[i];
}
newValueSet = boost::shared_ptr< WValueSetBase > (
new WValueSet< int16_t >( 0, valueDim, data ) );
newGrid = boost::shared_ptr< WGrid >( new WGrid( nbValues ) );
}
else
{
std::cout << "unknown data type " << image->datatype << std::endl;
newValueSet = boost::shared_ptr< WValueSetBase >();
newGrid = boost::shared_ptr< WGrid >();
}
boost::shared_ptr< WMetaInfo > metaInfo = boost::shared_ptr<WMetaInfo>(
new WMetaInfo() );
boost::shared_ptr< WDataSet > newDataSet = boost::shared_ptr< WDataSet >(
new WDataSetSingle( newValueSet, newGrid, metaInfo ) );
m_dataHandler->addDataSet( newDataSet );
}
......@@ -24,16 +24,37 @@
#ifndef WLOADERNIFTI_H
#define WLOADERNIFTI_H
#include <string>
#include <boost/shared_ptr.hpp>
#include "WLoader.h"
class WDataSet;
class WDataHandler;
/**
* Loader for the NIfTI file format. For NIfTI just see http://nifti.nimh.nih.gov/.
*/
class WLoaderNIfTI : public WLoader
{
public:
/**
* Constructs a loader to be executed in its own thread and ets the data needed
* for the loader when executed in its own thread.
*/
WLoaderNIfTI( std::string fileName, boost::shared_ptr< WDataHandler > dataHandler );
/**
* This function is automatically called when creating a new thread for the
* loader with boost::thread. It calls the methods of the NIfTI I/O library.
*/
void operator()();
protected:
private:
std::string m_fileName;
boost::shared_ptr< WDataHandler > m_dataHandler;
};
#endif // WLOADERNIFTI_H
......@@ -43,7 +43,8 @@ friend class WValueSetTest;
public:
/**
* Constructs an empty WValueSet instance holding size many values.
* Constructs a value set with values of type T. Sets order and dimension
* to allow to interprete the values as tensors of a certain order and dimension.
*/
WValueSet( char order, char dimension, const std::vector< T > data )
: WValueSetBase( order, dimension ),
......
ADD_SUBDIRECTORY( nifti )
\ No newline at end of file
## This file is somehow copy and pasted as well as edited from the original file from niftilib src-package
#PROJECT(NIFTILIB)
MESSAGE( STATUS "Inlcuded NIfTI lib building information." )
INCLUDE_DIRECTORIES(.)
OPTION ( BUILD_SHARED_LIBS "Toggle building shared libraries" ON)
ADD_DEFINITIONS(-DHAVE_ZLIB)
SET(ZNZLIB_SRC znzlib.c)
SET(NIFTI_ZNZLIB_NAME ${PACKAGE_PREFIX}znz)
ADD_LIBRARY(${NIFTI_ZNZLIB_NAME} ${ZNZLIB_SRC} )
TARGET_LINK_LIBRARIES( ${NIFTI_ZNZLIB_NAME} ${NIFTI_ZLIB_LIBRARIES} z)
# Set library version when building shared libs.
IF (BUILD_SHARED_LIBS)
SET(CPACK_PACKAGE_VERSION_MAJOR "1")
SET(CPACK_PACKAGE_VERSION_MINOR "1")
SET(CPACK_PACKAGE_VERSION_PATCH "0")
SET(NIFTI_SHAREDLIB_VERSION ${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH} )
STRING( REGEX MATCH "^[0-9]+" NIFTI_SHAREDLIB_SOVERSION ${NIFTI_SHAREDLIB_VERSION})
SET(NIFTI_LIBRARY_PROPERTIES VERSION ${NIFTI_SHAREDLIB_VERSION} SOVERSION ${NIFTI_SHAREDLIB_SOVERSION})
SET_TARGET_PROPERTIES(${NIFTI_NIFTILIB_NAME} PROPERTIES ${NIFTI_LIBRARY_PROPERTIES})
SET_TARGET_PROPERTIES(${NIFTI_ZNZLIB_NAME} PROPERTIES ${NIFTI_LIBRARY_PROPERTIES})
ENDIF (BUILD_SHARED_LIBS)
SET(NIFTILIB_SRC nifti1_io.c)
SET(NIFTI_NIFTILIB_NAME ${PACKAGE_PREFIX}niftiio)
ADD_LIBRARY(${NIFTI_NIFTILIB_NAME} ${NIFTILIB_SRC} )
TARGET_LINK_LIBRARIES( ${NIFTI_NIFTILIB_NAME} ${PACKAGE_PREFIX}znz)
IF(UNIX)
TARGET_LINK_LIBRARIES(${NIFTI_NIFTILIB_NAME} -lm)
ENDIF(UNIX)
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/** \file znzlib.c
\brief Low level i/o interface to compressed and noncompressed files.
Written by Mark Jenkinson, FMRIB
This library provides an interface to both compressed (gzip/zlib) and
uncompressed (normal) file IO. The functions are written to have the
same interface as the standard file IO functions.
To use this library instead of normal file IO, the following changes
are required:
- replace all instances of FILE* with znzFile
- change the name of all function calls, replacing the initial character
f with the znz (e.g. fseek becomes znzseek)
one exception is rewind() -> znzrewind()
- add a third parameter to all calls to znzopen (previously fopen)
that specifies whether to use compression (1) or not (0)
- use znz_isnull rather than any (pointer == NULL) comparisons in the code
for znzfile types (normally done after a return from znzopen)
NB: seeks for writable files with compression are quite restricted
*/
#include "znzlib.h"
/*
znzlib.c (zipped or non-zipped library)
***** This code is released to the public domain. *****
***** Author: Mark Jenkinson, FMRIB Centre, University of Oxford *****
***** Date: September 2004 *****
***** Neither the FMRIB Centre, the University of Oxford, nor any of *****
***** its employees imply any warranty of usefulness of this software *****
***** for any purpose, and do not assume any liability for damages, *****
***** incidental or otherwise, caused by any use of this document. *****
*/
/* Note extra argument (use_compression) where
use_compression==0 is no compression
use_compression!=0 uses zlib (gzip) compression
*/
znzFile znzopen(const char *path, const char *mode, int use_compression)
{
znzFile file;
file = (znzFile) calloc(1,sizeof(struct znzptr));
if( file == NULL ){
fprintf(stderr,"** ERROR: znzopen failed to alloc znzptr\n");
return NULL;
}
file->nzfptr = NULL;
#ifdef HAVE_ZLIB
file->zfptr = NULL;
if (use_compression) {
file->withz = 1;
if((file->zfptr = gzopen(path,mode)) == NULL) {
free(file);
file = NULL;
}
} else {
#endif
file->withz = 0;
if((file->nzfptr = fopen(path,mode)) == NULL) {
free(file);
file = NULL;
}
#ifdef HAVE_ZLIB
}
#endif
return file;
}
znzFile znzdopen(int fd, const char *mode, int use_compression)
{
znzFile file;
file = (znzFile) calloc(1,sizeof(struct znzptr));
if( file == NULL ){
fprintf(stderr,"** ERROR: znzdopen failed to alloc znzptr\n");
return NULL;
}
#ifdef HAVE_ZLIB
if (use_compression) {
file->withz = 1;
file->zfptr = gzdopen(fd,mode);
file->nzfptr = NULL;
} else {
#endif
file->withz = 0;
#ifdef HAVE_FDOPEN
file->nzfptr = fdopen(fd,mode);
#endif
#ifdef HAVE_ZLIB
file->zfptr = NULL;
};
#endif
return file;
}
int Xznzclose(znzFile * file)
{
int retval = 0;
if (*file!=NULL) {
#ifdef HAVE_ZLIB
if ((*file)->zfptr!=NULL) { retval = gzclose((*file)->zfptr); }
#endif
if ((*file)->nzfptr!=NULL) { retval = fclose((*file)->nzfptr); }
free(*file);
*file = NULL;
}
return retval;
}
size_t znzread(void* buf, size_t size, size_t nmemb, znzFile file)
{
if (file==NULL) { return 0; }
#ifdef HAVE_ZLIB
if (file->zfptr!=NULL)
return (size_t) (gzread(file->zfptr,buf,((int) size)*((int) nmemb)) / size);
#endif
return fread(buf,size,nmemb,file->nzfptr);
}
size_t znzwrite(const void* buf, size_t size, size_t nmemb, znzFile file)
{
if (file==NULL) { return 0; }
#ifdef HAVE_ZLIB
if (file->zfptr!=NULL)
{
/* NOTE: We must typecast const away from the buffer because
gzwrite does not have complete const specification */
return (size_t) ( gzwrite(file->zfptr,(void *)buf,size*nmemb) / size );
}
#endif
return fwrite(buf,size,nmemb,file->nzfptr);
}
long znzseek(znzFile file, long offset, int whence)
{
if (file==NULL) { return 0; }
#ifdef HAVE_ZLIB
if (file->zfptr!=NULL) return (long) gzseek(file->zfptr,offset,whence);
#endif
return fseek(file->nzfptr,offset,whence);
}
int znzrewind(znzFile stream)
{
if (stream==NULL) { return 0; }
#ifdef HAVE_ZLIB
/* On some systems, gzrewind() fails for uncompressed files.
Use gzseek(), instead. 10, May 2005 [rickr]
if (stream->zfptr!=NULL) return gzrewind(stream->zfptr);
*/
if (stream->zfptr!=NULL) return (int)gzseek(stream->zfptr, 0L, SEEK_SET);
#endif
rewind(stream->nzfptr);
return 0;
}
long znztell(znzFile file)
{
if (file==NULL) { return 0; }
#ifdef HAVE_ZLIB
if (file->zfptr!=NULL) return (long) gztell(file->zfptr);
#endif
return ftell(file->nzfptr);
}
int znzputs(const char * str, znzFile file)
{
if (file==NULL) { return 0; }
#ifdef HAVE_ZLIB
if (file->zfptr!=NULL) return gzputs(file->zfptr,str);
#endif
return fputs(str,file->nzfptr);
}
char * znzgets(char* str, int size, znzFile file)
{
if (file==NULL) { return NULL; }
#ifdef HAVE_ZLIB
if (file->zfptr!=NULL) return gzgets(file->zfptr,str,size);
#endif
return fgets(str,size,file->nzfptr);
}
int znzflush(znzFile file)
{
if (file==NULL) { return 0; }
#ifdef HAVE_ZLIB
if (file->zfptr!=NULL) return gzflush(file->zfptr,Z_SYNC_FLUSH);
#endif
return fflush(file->nzfptr);
}
int znzeof(znzFile file)
{
if (file==NULL) { return 0; }
#ifdef HAVE_ZLIB
if (file->zfptr!=NULL) return gzeof(file->zfptr);
#endif
return feof(file->nzfptr);
}
int znzputc(int c, znzFile file)
{
if (file==NULL) { return 0; }
#ifdef HAVE_ZLIB
if (file->zfptr!=NULL) return gzputc(file->zfptr,c);
#endif
return fputc(c,file->nzfptr);
}
int znzgetc(znzFile file)
{
if (file==NULL) { return 0; }
#ifdef HAVE_ZLIB
if (file->zfptr!=NULL) return gzgetc(file->zfptr);
#endif
return fgetc(file->nzfptr);
}
#if !defined (WIN32)
int znzprintf(znzFile stream, const char *format, ...)
{
int retval=0;
char *tmpstr;
va_list va;
if (stream==NULL) { return 0; }
va_start(va, format);
#ifdef HAVE_ZLIB
if (stream->zfptr!=NULL) {
int size; /* local to HAVE_ZLIB block */
size = strlen(format) + 1000000; /* overkill I hope */
tmpstr = (char *)calloc(1, size);
if( tmpstr == NULL ){
fprintf(stderr,"** ERROR: znzprintf failed to alloc %d bytes\n", size);
return retval;
}
vsprintf(tmpstr,format,va);
retval=gzprintf(stream->zfptr,"%s",tmpstr);
free(tmpstr);
} else
#endif
{
retval=vfprintf(stream->nzfptr,format,va);
}
va_end(va);
return retval;
}
#endif
#ifndef _ZNZLIB_H_
#define _ZNZLIB_H_
/*
znzlib.h (zipped or non-zipped library)
***** This code is released to the public domain. *****
***** Author: Mark Jenkinson, FMRIB Centre, University of Oxford *****
***** Date: September 2004 *****
***** Neither the FMRIB Centre, the University of Oxford, nor any of *****
***** its employees imply any warranty of usefulness of this software *****
***** for any purpose, and do not assume any liability for damages, *****
***** incidental or otherwise, caused by any use of this document. *****
*/
/*
This library provides an interface to both compressed (gzip/zlib) and
uncompressed (normal) file IO. The functions are written to have the
same interface as the standard file IO functions.
To use this library instead of normal file IO, the following changes
are required:
- replace all instances of FILE* with znzFile
- change the name of all function calls, replacing the initial character
f with the znz (e.g. fseek becomes znzseek)
- add a third parameter to all calls to znzopen (previously fopen)
that specifies whether to use compression (1) or not (0)
- use znz_isnull rather than any (pointer == NULL) comparisons in the code
NB: seeks for writable files with compression are quite restricted
*/
/*=================*/
#ifdef __cplusplus
extern "C" {
#endif
/*=================*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
/* include optional check for HAVE_FDOPEN here, from deleted config.h:
uncomment the following line if fdopen() exists for your compiler and
compiler options
*/
/* #define HAVE_FDOPEN */
#ifdef HAVE_ZLIB
#if defined(ITKZLIB)
#include "itk_zlib.h"
#else
#include "zlib.h"
#endif
#endif
struct znzptr {
int withz;
FILE* nzfptr;
#ifdef HAVE_ZLIB
gzFile zfptr;
#endif