// Copyright (c) 2005-2008 ASCLEPIOS Project, INRIA Sophia-Antipolis (France) // All rights reserved. // // This file is part of the ImageIO Library, and as been adapted for CGAL (www.cgal.org). // // $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 #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" #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) */ #define DT_DOUBLE 64 /*Double precision (64 bits per voxel)*/ #define DT_RGB 128 /* */ #define DT_ALL 255 /* */ #include 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 */ /* 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 */ 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 */ }; 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 */ /*---------------- _swapLong ------------------------------------------------*/ CGAL_INLINE_FUNCTION static void _swapLong( unsigned char *pntr) { unsigned char b0, b1, b2, b3; b0 = *pntr; b1 = *(pntr+1); b2 = *(pntr+2); b3 = *(pntr+3); *pntr = b3; *(pntr+1) = b2; *(pntr+2) = b1; *(pntr+3) = b0; } /*---------------- _swapShort -----------------------------------------------*/ CGAL_INLINE_FUNCTION static void _swapShort( unsigned char *pntr) { unsigned char b0, b1; b0 = *pntr; b1 = *(pntr+1); *pntr = b1; *(pntr+1) = b0; } /*---------------- _swapAnalyzeHdr ------------------------------------------*/ CGAL_INLINE_FUNCTION static void _swapAnalyzeHdr( struct dsr *pntr) { _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) || !memcmp(magic,ANALYZE_BE_MAGIC,4)) return 0; 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); 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" ); _openWriteImage(im, outputName); if( !im->fd ) { fprintf(stderr, "writeAnalyze: error: unable to open file \'%s\'\n", outputName); 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", outputName); if ( outputName != nullptr ) ImageIO_free( outputName ); ImageIO_close( im ); im->fd = nullptr; im->openMode = OM_CLOSE; return( res ); } ImageIO_close(im); 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); 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", outputName ); ImageIO_close( im ); im->fd = nullptr; im->openMode = OM_CLOSE; return( res ); } if ( outputName != nullptr ) ImageIO_free( outputName ); ImageIO_close( im ); im->fd = nullptr; im->openMode = OM_CLOSE; return ( res ); } /* return: -1: error 0: success */ CGAL_INLINE_FUNCTION 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) { ImageIO_read( im, analyzeHeader, sizeof(struct dsr) ); if( analyzeHeader->hk.sizeof_hdr == sizeof(struct dsr) ) { im->endianness = ARCHITECTURE_ENDIANNESS ; } else { _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; } } if ( analyzeHeader->dime.dim[0] > 4 ) { fprintf (stderr, "_readAnalyzeHeader: error: dimensionality not supported (%d)...\n", analyzeHeader->dime.dim[0] ); return -1; } 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 ){ 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. The forth dimension relates to time. */ if( analyzeHeader->dime.dim[4] != 1 ) { fprintf (stderr, "_readAnalyzeHeader: error: time dimension not supported (%d)...\n", analyzeHeader->dime.dim[4] ); return -1; } im->vectMode = VM_SCALAR; 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 ; switch(analyzeHeader->dime.datatype) { 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; } switch(analyzeHeader->dime.datatype) { 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; } switch(analyzeHeader->dime.datatype) { 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; } im->wdim = analyzeHeader->dime.bitpix; if( analyzeHeader->dime.datatype == DT_RGB ) { im->wdim /= 3 ; } if(im->wdim != 8 && im->wdim != 16 && im->wdim != 32 && im->wdim != 64) { fprintf (stderr, "_readAnalyzeHeader: error: pixel size not supported (%d)...\n", analyzeHeader->dime.bitpix ); return -1; } im->wdim >>= 3 ; /* There are 17 optional data fields be careful in the allocation */ im->nuser = 1 + 17 ; im->user = (char **) ImageIO_alloc(im->nuser * sizeof(char *)); for ( i=0; inuser; i++ ) im->user[i] = nullptr; i = 0 ; 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:" ); im->user[i] = (char *) ImageIO_alloc((strlen(" descrip: ") + 1 + strlen(analyzeHeader->hist.descrip) )); sprintf( im->user[i++], " descrip: %s", analyzeHeader->hist.descrip ); im->user[i] = (char *) ImageIO_alloc((strlen(" aux_file: ") + 1 + strlen(analyzeHeader->hist.descrip) )); sprintf( im->user[i++], " aux_file: %s", analyzeHeader->hist.descrip ); im->user[i] = (char *) ImageIO_alloc((strlen(" orient: ") + 1+ 2)); sprintf( im->user[i++], " orient: %d", analyzeHeader->hist.orient ); im->user[i] = (char *) ImageIO_alloc((strlen(" originator: ") + 1 + strlen(analyzeHeader->hist.originator) )); sprintf( im->user[i++], " originator: %s", analyzeHeader->hist.originator ); im->user[i] = (char *) ImageIO_alloc((strlen(" generated: ") + 1 + strlen(analyzeHeader->hist.generated) )); sprintf( im->user[i++], " generated: %s", analyzeHeader->hist.generated ); im->user[i] = (char *) ImageIO_alloc((strlen(" scannum: ") + 1 + strlen(analyzeHeader->hist.scannum) )); sprintf( im->user[i++], " scannum: %s", analyzeHeader->hist.scannum ); 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 ); 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 ); 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 ); im->user[i] = (char *) ImageIO_alloc((strlen(" vols_added: ") + 11 + 1)); sprintf( im->user[i++], " vols_added: %d", analyzeHeader->hist.vols_added ); im->user[i] = (char *) ImageIO_alloc((strlen(" start_field: ") + 11 + 1)); sprintf( im->user[i++], " start_field: %d", analyzeHeader->hist.start_field ); im->user[i] = (char *) ImageIO_alloc((strlen(" field_skip: ") + 11 + 1)); sprintf( im->user[i++], " field_skip: %d", analyzeHeader->hist.field_skip ); im->user[i] = (char *) ImageIO_alloc((strlen(" omax: ") + 11 + 1)); sprintf( im->user[i++], " omax: %d", analyzeHeader->hist.omax ); im->user[i] = (char *) ImageIO_alloc((strlen(" omin: ") + 11 + 1)); sprintf( im->user[i++], " omin: %d", analyzeHeader->hist.omin ); im->user[i] = (char *) ImageIO_alloc((strlen(" smax: ") + 11 + 1)); sprintf( im->user[i++], " smax: %d", analyzeHeader->hist.smax ); 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. */ if( name != nullptr ) { std::size_t length = strlen(name) ; 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 ); } /* check header validity */ if(im->xdim > 0 && im->ydim > 0 && im->zdim > 0 && im->vdim > 0 && 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; memset(&hdr,0, sizeof(struct dsr)); 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 ) { 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; imin = imax = *buf; for (std::size_t i=0; i *buf ) imin = *buf; } } } else if ( im->wdim == 2 ) { 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; imin = imax = *buf; for (std::size_t i=0; i *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; } } else { fprintf( stderr, "%s: unsupported image type\n", proc ); return -1; } } /* 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 *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 *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; } 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 */ /* corrected GM */ hdr.dime.glmax = imax ; /* maximum voxel value */ hdr.dime.glmin = imin ; /* minimum voxel value */ /* 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 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; /* Assume zero offset in .img file, byte at which pixel data starts in the image file */ hdr.dime.vox_offset = 0.0; /* Planar Orientation; */ /* Movie flag OFF: 0 = transverse, 1 = coronal, 2 = sagittal 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."); /* up to 7 characters for the calibration units label; i.e. HU */ 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 */ 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 ; while( buf >= data ) { 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; #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; } ImageIO_close(im); im->fd = nullptr; im->openMode = OM_CLOSE; _freeImage(im); return( 1 ); }