dust3d/thirdparty/cgal/CGAL-5.1/include/CGAL/ImageIO/analyze_impl.h

841 lines
27 KiB
C
Raw Normal View History

// Copyright (c) 2005-2008 ASCLEPIOS Project, INRIA Sophia-Antipolis (France)
// All rights reserved.
//
2020-10-13 12:44:25 +00:00
// This file is part of the ImageIO Library, and as been adapted for CGAL (www.cgal.org).
//
2020-10-13 12:44:25 +00:00
// $URL: https://github.com/CGAL/cgal/blob/v5.1/CGAL_ImageIO/include/CGAL/ImageIO/analyze_impl.h $
// $Id: analyze_impl.h 0779373 2020-03-26T13:31:46+01:00 Sébastien Loriot
// SPDX-License-Identifier: LGPL-3.0-or-later
//
//
// Author(s) : ASCLEPIOS Project (INRIA Sophia-Antipolis), Laurent Rineau
#include <cstring>
#ifdef CGAL_HEADER_ONLY
#define CGAL_INLINE_FUNCTION inline
#else
#define CGAL_INLINE_FUNCTION
#endif
/* compile time endianness */
/* replaced by _getEndianness()
see below
#if (defined (_ALPHA_) || defined (_LINUX_))
#define ARCHITECTURE_ENDIANNESS END_LITTLE
#else
#define ARCHITECTURE_ENDIANNESS END_BIG
#endif
*/
/** Magic header for ANALYZE files written in little endian format */
#define ANALYZE_LE_MAGIC "\000\000\001\134"
/** Magic header for ANALYZE files written in big endian format */
#define ANALYZE_BE_MAGIC "\134\001\000\000"
2020-10-13 12:44:25 +00:00
#define DT_NONE 0
#define DT_UNKNOWN 0 /*Unknown data type*/
#define DT_BINARY 1 /*Binary (1 bit per voxel)*/
#define DT_UNSIGNED_CHAR 2 /*Unsigned character (8 bits per voxel)*/
#define DT_SIGNED_SHORT 4 /*Signed short (16 bits per voxel)*/
#define DT_SIGNED_INT 8 /*Signed integer (32 bits per voxel)*/
#define DT_FLOAT 16 /*Floating point (32 bits per voxel)*/
#define DT_COMPLEX 32 /*Complex (64 bits per voxel; 2 floating point numbers) */
2020-10-13 12:44:25 +00:00
#define DT_DOUBLE 64 /*Double precision (64 bits per voxel)*/
#define DT_RGB 128 /* */
#define DT_ALL 255 /* */
#include <cstring>
struct header_key /* header_key */
{ /* off + size*/
int sizeof_hdr; /* 0 + 4 */
char data_type[10]; /* 4 + 10 */
char db_name[18]; /* 14 + 18 */
int extents; /* 32 + 4 */
short int session_error; /* 36 + 2 */
char regular; /* 38 + 1 */
char hkey_un0; /* 39 + 1 */
}; /* total=40 */
struct image_dimension /* image_dimension */
{ /* off + size*/
short int dim[8]; /* 0 + 16 */
char vox_units[4]; /* 16 + 4 */
char cal_units[8]; /* 20 + 4 */
short int unused1; /* 24 + 2 */
short int datatype; /* 30 + 2 */
short int bitpix; /* 32 + 2 */
short int dim_un0; /* 34 + 2 */
float pixdim[8]; /* 36 + 32 */
2020-10-13 12:44:25 +00:00
/*
pixdim[] specifies the voxel dimensions:
pixdim[1] - voxel width
pixdim[2] - voxel height
pixdim[3] - interslice distance
..etc
*/
float vox_offset; /* 68 + 4 */
float funused1; /* 72 + 4 */
float funused2; /* 76 + 4 */
float funused3; /* 80 + 4 */
float cal_max; /* 84 + 4 */
float cal_min; /* 88 + 4 */
int compressed; /* 92 + 4 */
int verified; /* 96 + 4 */
int glmax, glmin; /* 100 + 8 */
}; /* total=108 */
2020-10-13 12:44:25 +00:00
struct data_history /* data_history */
{ /* off + size*/
char descrip[80]; /* 0 + 80 */
char aux_file[24]; /* 80 + 24 */
char orient; /* 104 + 1 */
char originator[10]; /* 105 + 10 */
char generated[10]; /* 115 + 10 */
char scannum[10]; /* 125 + 10 */
char patient_id[10]; /* 135 + 10 */
char exp_date[10]; /* 145 + 10 */
char exp_time[10]; /* 155 + 10 */
char hist_un0[3]; /* 165 + 3 */
int views; /* 168 + 4 */
int vols_added; /* 172 + 4 */
int start_field; /* 176 + 4 */
int field_skip; /* 180 + 4 */
int omax,omin; /* 184 + 8 */
int smax,smin; /* 192 + 8 */
2020-10-13 12:44:25 +00:00
};
struct dsr /* dsr */
{ /* off + size*/
struct header_key hk; /* 0 + 40 */
struct image_dimension dime; /* 40 + 108 */
struct data_history hist; /* 148 + 200 */
}; /* total=348 */
2020-10-13 12:44:25 +00:00
/*---------------- _swapLong ------------------------------------------------*/
CGAL_INLINE_FUNCTION
static void _swapLong( unsigned char *pntr)
{
unsigned char b0, b1, b2, b3;
2020-10-13 12:44:25 +00:00
b0 = *pntr;
b1 = *(pntr+1);
b2 = *(pntr+2);
b3 = *(pntr+3);
2020-10-13 12:44:25 +00:00
*pntr = b3;
*(pntr+1) = b2;
*(pntr+2) = b1;
*(pntr+3) = b0;
}
2020-10-13 12:44:25 +00:00
/*---------------- _swapShort -----------------------------------------------*/
CGAL_INLINE_FUNCTION
static void _swapShort( unsigned char *pntr)
{
unsigned char b0, b1;
2020-10-13 12:44:25 +00:00
b0 = *pntr;
b1 = *(pntr+1);
*pntr = b1;
*(pntr+1) = b0;
}
/*---------------- _swapAnalyzeHdr ------------------------------------------*/
CGAL_INLINE_FUNCTION
static void _swapAnalyzeHdr( struct dsr *pntr)
{
2020-10-13 12:44:25 +00:00
_swapLong((unsigned char*) &pntr->hk.sizeof_hdr) ;
_swapLong((unsigned char*) &pntr->hk.extents) ;
_swapShort((unsigned char*) &pntr->hk.session_error) ;
_swapShort((unsigned char*) &pntr->dime.dim[0]) ;
_swapShort((unsigned char*) &pntr->dime.dim[1]) ;
_swapShort((unsigned char*) &pntr->dime.dim[2]) ;
_swapShort((unsigned char*) &pntr->dime.dim[3]) ;
_swapShort((unsigned char*) &pntr->dime.dim[4]) ;
_swapShort((unsigned char*) &pntr->dime.dim[5]) ;
_swapShort((unsigned char*) &pntr->dime.dim[6]) ;
_swapShort((unsigned char*) &pntr->dime.dim[7]) ;
_swapShort((unsigned char*) &pntr->dime.unused1) ;
_swapShort((unsigned char*) &pntr->dime.datatype) ;
_swapShort((unsigned char*) &pntr->dime.bitpix) ;
_swapLong((unsigned char*) &pntr->dime.pixdim[0]) ;
_swapLong((unsigned char*) &pntr->dime.pixdim[1]) ;
_swapLong((unsigned char*) &pntr->dime.pixdim[2]) ;
_swapLong((unsigned char*) &pntr->dime.pixdim[3]) ;
_swapLong((unsigned char*) &pntr->dime.pixdim[4]) ;
_swapLong((unsigned char*) &pntr->dime.pixdim[5]) ;
_swapLong((unsigned char*) &pntr->dime.pixdim[6]) ;
_swapLong((unsigned char*) &pntr->dime.pixdim[7]) ;
_swapLong((unsigned char*) &pntr->dime.vox_offset) ;
_swapLong((unsigned char*) &pntr->dime.funused1) ;
_swapLong((unsigned char*) &pntr->dime.funused2) ;
_swapLong((unsigned char*) &pntr->dime.cal_max) ;
_swapLong((unsigned char*) &pntr->dime.cal_min) ;
_swapLong((unsigned char*) &pntr->dime.compressed) ;
_swapLong((unsigned char*) &pntr->dime.verified) ;
_swapShort((unsigned char*) &pntr->dime.dim_un0) ;
_swapLong((unsigned char*) &pntr->dime.glmax) ;
_swapLong((unsigned char*) &pntr->dime.glmin) ;
}
CGAL_INLINE_FUNCTION
PTRIMAGE_FORMAT createAnalyzeFormat() {
PTRIMAGE_FORMAT f=(PTRIMAGE_FORMAT) ImageIO_alloc(sizeof(IMAGE_FORMAT));
f->testImageFormat=&testAnalyzeHeader;
f->readImageHeader=&readAnalyzeHeader;
f->writeImage=&writeAnalyze;
strcpy(f->fileExtension,".hdr,.hdr.gz,.img,.img.gz");
strcpy(f->realName,"Analyze");
return f;
}
CGAL_INLINE_FUNCTION
int testAnalyzeHeader(char *magic,const char *) {
/* opened image is an ANALYZE */
if( !memcmp(magic,ANALYZE_LE_MAGIC,4) ||
2020-10-13 12:44:25 +00:00
!memcmp(magic,ANALYZE_BE_MAGIC,4))
return 0;
2020-10-13 12:44:25 +00:00
else
return -1;
}
CGAL_INLINE_FUNCTION
int writeAnalyze( char *name, _image* im) {
char *outputName;
std::size_t length, extLength=0;
length=strlen(name);
outputName= (char *)ImageIO_alloc(length+8);
2020-10-13 12:44:25 +00:00
if ( strncmp( name+length-4, ".hdr", 4 ) == 0 ) {
extLength = 4;
}
else if ( strncmp( name+length-4, ".img", 4 ) == 0 ) {
extLength = 4;
}
else if ( strncmp( name+length-7, ".img.gz", 7 ) == 0 ) {
extLength = 7;
}
else if ( strncmp( name+length-7, ".hdr.gz", 7 ) == 0 ) {
extLength = 7;
}
strncpy( outputName, name, length-extLength );
if ( strncmp( name+length-7, ".hdr.gz", 7 ) == 0 )
strcpy( outputName+length-extLength, ".hdr.gz" );
else
strcpy( outputName+length-extLength, ".hdr" );
2020-10-13 12:44:25 +00:00
_openWriteImage(im, outputName);
if( !im->fd ) {
fprintf(stderr, "writeAnalyze: error: unable to open file \'%s\'\n", outputName);
2020-10-13 12:44:25 +00:00
if ( outputName != nullptr ) ImageIO_free( outputName );
return ImageIO_OPENING;
}
int res = writeAnalyzeHeader(im);
if ( res < 0 ) {
fprintf(stderr, "writeAnalyze: error: unable to write header of \'%s\'\n",
2020-10-13 12:44:25 +00:00
outputName);
if ( outputName != nullptr ) ImageIO_free( outputName );
ImageIO_close( im );
2020-10-13 12:44:25 +00:00
im->fd = nullptr;
im->openMode = OM_CLOSE;
return( res );
}
2020-10-13 12:44:25 +00:00
ImageIO_close(im);
2020-10-13 12:44:25 +00:00
strncpy( outputName, name, length-extLength );
if ( strncmp( name+length-3, ".gz", 3 ) == 0 ) {
strcpy( outputName+length-extLength, ".img.gz" );
}
else {
strcpy( outputName+length-extLength, ".img" );
}
_openWriteImage(im, outputName);
if( !im->fd ) {
fprintf(stderr, "writeAnalyze: error: unable to open file \'%s\'\n", outputName);
2020-10-13 12:44:25 +00:00
if ( outputName != nullptr ) ImageIO_free( outputName );
return ImageIO_OPENING;
}
res = writeAnalyzeData(im);
if (res < 0) {
fprintf(stderr, "writeAnalyze: error: unable to write data in \'%s\'\n",
2020-10-13 12:44:25 +00:00
outputName );
ImageIO_close( im );
2020-10-13 12:44:25 +00:00
im->fd = nullptr;
im->openMode = OM_CLOSE;
return( res );
}
2020-10-13 12:44:25 +00:00
if ( outputName != nullptr ) ImageIO_free( outputName );
ImageIO_close( im );
2020-10-13 12:44:25 +00:00
im->fd = nullptr;
im->openMode = OM_CLOSE;
return ( res );
}
2020-10-13 12:44:25 +00:00
/*
return:
-1: error
0: success
*/
CGAL_INLINE_FUNCTION
2020-10-13 12:44:25 +00:00
int _readAnalyzeHeader( _image* im, const char* name,
struct dsr *analyzeHeader )
{
unsigned int i ;
/* compile time endianness */
ENDIANNESS ARCHITECTURE_ENDIANNESS = _getEndianness();
if(im->openMode != OM_CLOSE) {
2020-10-13 12:44:25 +00:00
ImageIO_read( im, analyzeHeader, sizeof(struct dsr) );
2020-10-13 12:44:25 +00:00
if( analyzeHeader->hk.sizeof_hdr == sizeof(struct dsr) )
{
2020-10-13 12:44:25 +00:00
im->endianness = ARCHITECTURE_ENDIANNESS ;
}
else
{
2020-10-13 12:44:25 +00:00
_swapAnalyzeHdr( analyzeHeader );
if( analyzeHeader->hk.sizeof_hdr != sizeof(struct dsr) )
{
fprintf (stderr,
"_readAnalyzeHeader: error: unknown magic (%d)...\n",
analyzeHeader->hk.sizeof_hdr );
return -1;
}
if( ARCHITECTURE_ENDIANNESS == END_LITTLE )
{
im->endianness = END_BIG;
}
else
{
im->endianness = END_LITTLE;
}
}
2020-10-13 12:44:25 +00:00
if ( analyzeHeader->dime.dim[0] > 4 ) {
2020-10-13 12:44:25 +00:00
fprintf (stderr,
"_readAnalyzeHeader: error: dimensionality not supported (%d)...\n",
analyzeHeader->dime.dim[0] );
return -1;
}
2020-10-13 12:44:25 +00:00
im->xdim = analyzeHeader->dime.dim[1];
im->ydim = analyzeHeader->dime.dim[2];
im->zdim = analyzeHeader->dime.dim[3];
/* 0 time-points is a convention for one volume only at MNI */
/* Corrected by X. Pennec following a bug report by Irina Kezele at MNI */
if( analyzeHeader->dime.dim[4] == 0 ){
2020-10-13 12:44:25 +00:00
fprintf (stderr,
"_readAnalyzeHeader: warning: time dimension / number if volume (dim[4]) is 0. Assuming this means 1 (otherwise there would be no image...). \n");
analyzeHeader->dime.dim[4] = 1;
}
/* Analyze doesn't support vector images.
2020-10-13 12:44:25 +00:00
The forth dimension relates to time. */
if( analyzeHeader->dime.dim[4] != 1 )
{
2020-10-13 12:44:25 +00:00
fprintf (stderr,
"_readAnalyzeHeader: error: time dimension not supported (%d)...\n",
analyzeHeader->dime.dim[4] );
return -1;
}
im->vectMode = VM_SCALAR;
2020-10-13 12:44:25 +00:00
im->vx = analyzeHeader->dime.pixdim[1];
im->vy = analyzeHeader->dime.pixdim[2];
im->vz = analyzeHeader->dime.pixdim[3];
if( im->vx == 0.0 ) im->vx = 1.0 ;
if( im->vy == 0.0 ) im->vy = im->vx ;
if( im->vz == 0.0 ) im->vz = im->vy ;
2020-10-13 12:44:25 +00:00
switch(analyzeHeader->dime.datatype)
{
2020-10-13 12:44:25 +00:00
case DT_BINARY:
case DT_UNSIGNED_CHAR:
case DT_SIGNED_SHORT:
case DT_SIGNED_INT:
case DT_FLOAT:
case DT_COMPLEX:
case DT_DOUBLE:
im->vdim = 1;
break ;
case DT_RGB:
im->vdim = 3;
break ;
default:
fprintf (stderr,
"_readAnalyzeHeader: error: data type not supported (%d)...\n",
analyzeHeader->dime.datatype );
return -1;
}
2020-10-13 12:44:25 +00:00
switch(analyzeHeader->dime.datatype)
{
2020-10-13 12:44:25 +00:00
case DT_BINARY:
case DT_UNSIGNED_CHAR:
case DT_SIGNED_SHORT:
case DT_SIGNED_INT:
case DT_RGB:
im->wordKind = WK_FIXED;
break ;
case DT_FLOAT:
case DT_COMPLEX:
case DT_DOUBLE:
im->wordKind = WK_FLOAT;
break ;
default:
fprintf (stderr,
"_readAnalyzeHeader: error: data type not supported (%d)...\n",
analyzeHeader->dime.datatype );
return -1;
}
2020-10-13 12:44:25 +00:00
switch(analyzeHeader->dime.datatype)
{
2020-10-13 12:44:25 +00:00
case DT_BINARY:
case DT_UNSIGNED_CHAR:
case DT_RGB:
im->sign = SGN_UNSIGNED;
break ;
case DT_SIGNED_SHORT:
case DT_SIGNED_INT:
case DT_FLOAT:
case DT_COMPLEX:
case DT_DOUBLE:
im->sign = SGN_SIGNED;
break ;
default:
fprintf (stderr,
"_readAnalyzeHeader: error: data type not supported (%d)...\n",
analyzeHeader->dime.datatype );
return -1;
}
2020-10-13 12:44:25 +00:00
im->wdim = analyzeHeader->dime.bitpix;
if( analyzeHeader->dime.datatype == DT_RGB )
{
2020-10-13 12:44:25 +00:00
im->wdim /= 3 ;
}
if(im->wdim != 8 && im->wdim != 16 && im->wdim != 32 && im->wdim != 64)
{
2020-10-13 12:44:25 +00:00
fprintf (stderr,
"_readAnalyzeHeader: error: pixel size not supported (%d)...\n",
analyzeHeader->dime.bitpix );
return -1;
}
im->wdim >>= 3 ;
2020-10-13 12:44:25 +00:00
/* There are 17 optional data fields
be careful in the allocation
*/
im->nuser = 1 + 17 ;
im->user = (char **) ImageIO_alloc(im->nuser * sizeof(char *));
2020-10-13 12:44:25 +00:00
for ( i=0; i<im->nuser; i++ ) im->user[i] = nullptr;
i = 0 ;
2020-10-13 12:44:25 +00:00
im->user[i] = (char *) ImageIO_alloc((strlen("Data lost in the Analyze -> ImageIO conversion:") + 1));
sprintf( im->user[i++], "Data lost in the Analyze -> ImageIO conversion:" );
2020-10-13 12:44:25 +00:00
im->user[i] = (char *) ImageIO_alloc((strlen(" descrip: ") + 1 + strlen(analyzeHeader->hist.descrip) ));
sprintf( im->user[i++], " descrip: %s", analyzeHeader->hist.descrip );
2020-10-13 12:44:25 +00:00
im->user[i] = (char *) ImageIO_alloc((strlen(" aux_file: ") + 1 + strlen(analyzeHeader->hist.descrip) ));
sprintf( im->user[i++], " aux_file: %s", analyzeHeader->hist.descrip );
2020-10-13 12:44:25 +00:00
im->user[i] = (char *) ImageIO_alloc((strlen(" orient: ") + 1+ 2));
sprintf( im->user[i++], " orient: %d", analyzeHeader->hist.orient );
2020-10-13 12:44:25 +00:00
im->user[i] = (char *) ImageIO_alloc((strlen(" originator: ") + 1 + strlen(analyzeHeader->hist.originator) ));
sprintf( im->user[i++], " originator: %s", analyzeHeader->hist.originator );
2020-10-13 12:44:25 +00:00
im->user[i] = (char *) ImageIO_alloc((strlen(" generated: ") + 1 + strlen(analyzeHeader->hist.generated) ));
sprintf( im->user[i++], " generated: %s", analyzeHeader->hist.generated );
2020-10-13 12:44:25 +00:00
im->user[i] = (char *) ImageIO_alloc((strlen(" scannum: ") + 1 + strlen(analyzeHeader->hist.scannum) ));
sprintf( im->user[i++], " scannum: %s", analyzeHeader->hist.scannum );
2020-10-13 12:44:25 +00:00
im->user[i] = (char *) ImageIO_alloc((strlen(" patient_id: ") + 1 + strlen(analyzeHeader->hist.patient_id) ));
sprintf( im->user[i++], " patient_id: %s", analyzeHeader->hist.patient_id );
2020-10-13 12:44:25 +00:00
im->user[i] = (char *) ImageIO_alloc((strlen(" exp_date: ") + 1 + strlen(analyzeHeader->hist.exp_date) ));
sprintf( im->user[i++], " exp_date: %s", analyzeHeader->hist.exp_date );
2020-10-13 12:44:25 +00:00
im->user[i] = (char *) ImageIO_alloc((strlen(" exp_time: ") + 1 + strlen(analyzeHeader->hist.exp_time) ));
sprintf( im->user[i++], " exp_time: %s", analyzeHeader->hist.exp_time );
/* A 32 bit int doesn't print on more than 11 chars */
im->user[i] = (char *) ImageIO_alloc((strlen(" views: ") + 11 + 1));
sprintf( im->user[i++], " views: %d", analyzeHeader->hist.views );
2020-10-13 12:44:25 +00:00
im->user[i] = (char *) ImageIO_alloc((strlen(" vols_added: ") + 11 + 1));
sprintf( im->user[i++], " vols_added: %d", analyzeHeader->hist.vols_added );
2020-10-13 12:44:25 +00:00
im->user[i] = (char *) ImageIO_alloc((strlen(" start_field: ") + 11 + 1));
sprintf( im->user[i++], " start_field: %d", analyzeHeader->hist.start_field );
2020-10-13 12:44:25 +00:00
im->user[i] = (char *) ImageIO_alloc((strlen(" field_skip: ") + 11 + 1));
sprintf( im->user[i++], " field_skip: %d", analyzeHeader->hist.field_skip );
2020-10-13 12:44:25 +00:00
im->user[i] = (char *) ImageIO_alloc((strlen(" omax: ") + 11 + 1));
sprintf( im->user[i++], " omax: %d", analyzeHeader->hist.omax );
2020-10-13 12:44:25 +00:00
im->user[i] = (char *) ImageIO_alloc((strlen(" omin: ") + 11 + 1));
sprintf( im->user[i++], " omin: %d", analyzeHeader->hist.omin );
2020-10-13 12:44:25 +00:00
im->user[i] = (char *) ImageIO_alloc((strlen(" smax: ") + 11 + 1));
sprintf( im->user[i++], " smax: %d", analyzeHeader->hist.smax );
2020-10-13 12:44:25 +00:00
im->user[i] = (char *) ImageIO_alloc((strlen(" smin: ") + 11 + 1));
sprintf( im->user[i++], " smin: %d", analyzeHeader->hist.smin );
/* header is read. close header file and open data file. */
2020-10-13 12:44:25 +00:00
if( name != nullptr ) {
std::size_t length = strlen(name) ;
2020-10-13 12:44:25 +00:00
char* data_filename = (char *) ImageIO_alloc(length+4) ;
if( strcmp( name+length-4, ".hdr" ) )
{
fprintf (stderr,
"_readAnalyzeHeader: error: file header extension must be .hdr\n");
ImageIO_free( data_filename );
return -1;
}
ImageIO_close(im);
strcpy(data_filename,name);
strcpy(data_filename+length-3, "img.gz");
_openReadImage(im,data_filename);
if(!im->fd) {
strcpy(data_filename,name);
strcpy(data_filename+length-3, "img");
_openReadImage(im,data_filename);
if(!im->fd) {
fprintf(stderr, "_readAnalyzeHeader: error: unable to open data file \'%s\'\n", data_filename);
ImageIO_free( data_filename );
return -1;
}
}
ImageIO_free( data_filename );
}
2020-10-13 12:44:25 +00:00
/* check header validity */
if(im->xdim > 0 && im->ydim > 0 && im->zdim > 0 && im->vdim > 0 &&
2020-10-13 12:44:25 +00:00
im->vx > 0.0 && im->vy > 0.0 && im->vz > 0.0 &&
(im->wordKind == WK_FLOAT || (im->wordKind == WK_FIXED &&
im->sign != SGN_UNKNOWN)) &&
im->endianness != END_UNKNOWN) {
return 0;
}
else return -1;
}
else return -1;
}
CGAL_INLINE_FUNCTION
int readAnalyzeHeader( const char* name, _image* im)
{
struct dsr analyzeHeader ;
return( _readAnalyzeHeader( im, name, &analyzeHeader ) );
}
CGAL_INLINE_FUNCTION
int
writeAnalyzeHeader( const _image* im )
{
const char *proc = "writeAnalyzeHeader";
struct dsr hdr;
int i ;
int imin = 0;
int imax = 0;
2020-10-13 12:44:25 +00:00
memset(&hdr,0, sizeof(struct dsr));
2020-10-13 12:44:25 +00:00
for(i=0;i<8;i++) {
hdr.dime.pixdim[i] = 0.0;
}
hdr.dime.vox_offset = 0.0;
hdr.dime.funused1 = 0.0;
hdr.dime.funused2 = 0.0;
hdr.dime.funused3 = 0.0;
hdr.dime.cal_max = 0.0;
hdr.dime.cal_min = 0.0;
hdr.dime.dim[0] = 4;
hdr.dime.dim[1] = short(im->xdim);
hdr.dime.dim[2] = short(im->ydim);
hdr.dime.dim[3] = short(im->zdim);
hdr.dime.dim[4] = 1 ;
if ( im->wordKind == WK_FIXED && im->sign == SGN_UNSIGNED ) {
if( im->wdim == 1 ) {
2020-10-13 12:44:25 +00:00
if ( im->vdim == 1 ) {
hdr.dime.datatype = DT_UNSIGNED_CHAR ;
}
else if ( im->vdim == 3 ) {
hdr.dime.datatype = DT_RGB ;
}
else {
fprintf( stderr, "%s: unsupported image type\n", proc );
return -1;
}
{
unsigned char *buf = (unsigned char *)im->data;
std::size_t size = std::size_t(im->xdim) * im->ydim * im->zdim * im->vdim;
2020-10-13 12:44:25 +00:00
imin = imax = *buf;
for (std::size_t i=0; i<size; i++, buf++) {
if ( imax < *buf ) imax = *buf;
if ( imin > *buf ) imin = *buf;
}
}
}
else if ( im->wdim == 2 ) {
2020-10-13 12:44:25 +00:00
if ( im->vdim == 1 ) {
unsigned short int *buf = (unsigned short int*)im->data;
std::size_t size = std::size_t(im->xdim) * im->ydim *im->zdim;
2020-10-13 12:44:25 +00:00
imin = imax = *buf;
for (std::size_t i=0; i<size; i++, buf++) {
if ( imax < *buf ) imax = *buf;
if ( imin > *buf ) imin = *buf;
}
if ( imax < 32768 ) {
hdr.dime.datatype = DT_SIGNED_SHORT ;
}
else {
fprintf( stderr, "%s: conversion from unsigned short to short impossible, max=%d\n", proc, imax );
return -1;
}
}
else {
fprintf( stderr, "%s: unsupported image type\n", proc );
return -1;
}
}
2020-10-13 12:44:25 +00:00
else {
2020-10-13 12:44:25 +00:00
fprintf( stderr, "%s: unsupported image type\n", proc );
return -1;
}
2020-10-13 12:44:25 +00:00
} /* if ( im->wordKind == WK_FIXED && im->sign == SGN_UNSIGNED ) */
else if( im->wordKind == WK_FIXED && im->sign == SGN_SIGNED ) {
if ( im->vdim != 1 ) {
fprintf( stderr, "%s: unsupported image type\n", proc );
return -1;
}
if( im->wdim == 2 ) {
short int *buf = (short int*)im->data;
std::size_t size = std::size_t(im->xdim) * im->ydim *im->zdim;
imin = imax = *buf;
for (std::size_t i=0; i<size; i++, buf++) {
2020-10-13 12:44:25 +00:00
if ( imax < *buf ) imax = *buf;
if ( imin > *buf ) imin = *buf;
}
hdr.dime.datatype = DT_SIGNED_SHORT ;
}
else if( im->wdim == 4 ) {
int *buf = (int*)im->data;
std::size_t size = std::size_t(im->xdim) * im->ydim *im->zdim;
imin = imax = *buf;
for (std::size_t i=0; i<size; i++, buf++) {
2020-10-13 12:44:25 +00:00
if ( imax < *buf ) imax = *buf;
if ( imin > *buf ) imin = *buf;
}
hdr.dime.datatype = DT_SIGNED_INT ;
}
else {
fprintf( stderr, "%s: unsupported image type\n", proc );
return -1;
}
}
else if( im->wordKind == WK_FLOAT ) {
if ( im->vdim != 1 ) {
fprintf( stderr, "%s: unsupported image type\n", proc );
return -1;
}
if( im->wdim == 4 ) {
hdr.dime.datatype = DT_FLOAT ;
}
else if( im->wdim == 8 ) {
hdr.dime.datatype = DT_DOUBLE ;
}
else {
fprintf( stderr, "%s: unsupported image type\n", proc );
return -1;
}
}
else
{
fprintf( stderr, "%s: unsupported image type\n", proc );
return -1;
}
2020-10-13 12:44:25 +00:00
hdr.dime.bitpix = short(8*im->wdim*im->vdim) ;
hdr.hk.regular = 'r';
hdr.hk.sizeof_hdr = sizeof(struct dsr);
/* this is probably bad and should be changed to the
real values, but I'm too lazy to do it now. AG */
hdr.dime.glmax = 0 ; /* maximum voxel value */
hdr.dime.glmin = 0 ; /* minimum voxel value */
2020-10-13 12:44:25 +00:00
/* corrected GM
*/
hdr.dime.glmax = imax ; /* maximum voxel value */
hdr.dime.glmin = imin ; /* minimum voxel value */
2020-10-13 12:44:25 +00:00
/* Set the voxel dimension fields:
A value of 0.0 for these fields implies that the value is unknown.
Change these values to what is appropriate for your data
2020-10-13 12:44:25 +00:00
or pass additional command line arguments */
hdr.dime.pixdim[1] = (float)im->vx;
hdr.dime.pixdim[2] = (float)im->vy;
hdr.dime.pixdim[3] = (float)im->vz;
2020-10-13 12:44:25 +00:00
/* Assume zero offset in .img file, byte at which pixel
data starts in the image file */
2020-10-13 12:44:25 +00:00
hdr.dime.vox_offset = 0.0;
/* Planar Orientation; */
/* Movie flag OFF: 0 = transverse, 1 = coronal, 2 = sagittal
2020-10-13 12:44:25 +00:00
Movie flag ON: 3 = transverse, 4 = coronal, 5 = sagittal */
hdr.hist.orient = 0;
/* up to 3 characters for the voxels units label; i.e. mm., um., cm. */
strcpy(hdr.dime.vox_units,"mm.");
2020-10-13 12:44:25 +00:00
/* up to 7 characters for the calibration units label; i.e. HU */
2020-10-13 12:44:25 +00:00
strcpy(hdr.dime.cal_units," ");
/* Calibration maximum and minimum values;
values of 0.0 for both fields imply that no
calibration max and min values are used */
2020-10-13 12:44:25 +00:00
hdr.dime.cal_max = 0.0;
hdr.dime.cal_min = 0.0;
if(ImageIO_write(im, &hdr, sizeof(struct dsr)) !=sizeof(struct dsr) )
return -1;
return 1 ;
}
/* Writes the given image body in an already opened file.*/
CGAL_INLINE_FUNCTION
int writeAnalyzeData(const _image *im) {
std::size_t lineSize = std::size_t(im->wdim) * im->xdim * im->vdim ;
std::size_t size = lineSize * im->ydim * im->zdim;
std::size_t nwrt ;
if(im->openMode != OM_CLOSE) {
#ifdef _REVERSE_LINES_IN_ANALYZE_
char* data = (char *)im->data ;
char* buf = data + size - lineSize ;
2020-10-13 12:44:25 +00:00
while( buf >= data )
{
2020-10-13 12:44:25 +00:00
nwrt = ImageIO_write(im, buf, lineSize);
if(nwrt != lineSize) return -1;
buf -= lineSize ;
}
#else
nwrt = ImageIO_write(im, im->data, size);
if(nwrt != size) return -1;
2020-10-13 12:44:25 +00:00
#endif
return 1 ;
}
else return -1;
}
/* Writes the given image body in an already opened file.*/
CGAL_INLINE_FUNCTION
int printAnalyzeHeader( const char* name )
{
_image *im;
struct dsr analyzeHeader ;
im = _initImage();
_openReadImage(im, name);
if(!im->fd) {
fprintf(stderr, "printAnalyzeHeader: error: unable to open file \'%s\'\n", name);
_freeImage(im);
return -1;
}
if ( _readAnalyzeHeader( im, name, &analyzeHeader ) != 1 ) {
fprintf(stderr, "printAnalyzeHeader: error: unable to read header in file \'%s\'\n", name);
_freeImage(im);
return -1;
}
2020-10-13 12:44:25 +00:00
ImageIO_close(im);
2020-10-13 12:44:25 +00:00
im->fd = nullptr;
im->openMode = OM_CLOSE;
_freeImage(im);
return( 1 );
}