1 /*****************************************************************************
2    Major portions of this software are copyrighted by the Medical College
3    of Wisconsin, 1994-2000, and are released under the Gnu General Public
4    License, Version 2.  See the file README.Copyright for details.
5 ******************************************************************************/
6 
7 #include "mrilib.h"
8 
9 /*** 7D SAFE ***/
10 
11 /***-------------------------- get a new 2D image --------------------------***/
12 
mri_new(int nx,int ny,MRI_TYPE kind)13 MRI_IMAGE *mri_new( int nx , int ny , MRI_TYPE kind )
14 {
15    MRI_IMAGE *newim ;
16 
17    newim = mri_new_7D_generic( nx,ny , 1,1,1,1,1 , kind , TRUE ) ;
18    return newim ;
19 }
20 
21 /***-------------- get a new 3D image, but with no data inside -------------***/
22 
mri_new_vol_empty(int nx,int ny,int nz,MRI_TYPE kind)23 MRI_IMAGE *mri_new_vol_empty( int nx , int ny , int nz , MRI_TYPE kind )
24 {
25    MRI_IMAGE *newim ;
26    newim = mri_new_7D_generic( nx,ny,nz , 1,1,1,1 , kind , FALSE ) ;
27    return newim ;
28 }
29 
30 /***------------------------ get a new 3D image ------------------------***/
31 
mri_new_vol(int nx,int ny,int nz,MRI_TYPE kind)32 MRI_IMAGE *mri_new_vol( int nx , int ny , int nz , MRI_TYPE kind )
33 {
34    MRI_IMAGE *newim ;
35    newim = mri_new_7D_generic( nx,ny,nz , 1,1,1,1 , kind , TRUE ) ;
36    return newim ;
37 }
38 
39 /***---------------------- make a new 7D image -------------------------***/
40 
mri_new_7D_generic(int nx,int ny,int nz,int nt,int nu,int nv,int nw,MRI_TYPE kind,int make_space)41 MRI_IMAGE *mri_new_7D_generic(
42             int nx, int ny, int nz, int nt, int nu, int nv, int nw,
43             MRI_TYPE kind , int make_space )
44 {
45    MRI_IMAGE *newim ;
46    int64_t npix ;
47 
48 ENTRY("mri_new_7D_generic") ;
49 
50    newim = (MRI_IMAGE *)calloc( 1, sizeof(MRI_IMAGE) ) ;
51 
52    if( newim == NULL ){
53      ERROR_message("** malloc failure for new image pointer") ;
54      MRI_FATAL_ERROR ;
55    }
56 
57    if( nx < 1 ) nx = 1 ;  /* 18 Mar 2005: fix stupid user problems */
58    if( ny < 1 ) ny = 1 ;
59    if( nz < 1 ) nz = 1 ;
60    if( nt < 1 ) nt = 1 ;
61    if( nu < 1 ) nu = 1 ;
62    if( nv < 1 ) nv = 1 ;
63    if( nw < 1 ) nw = 1 ;
64 
65    newim->nx   = nx ;
66    newim->ny   = ny ; newim->nxy   = nx*ny ;
67    newim->nz   = nz ;
68    newim->nt   = nt ;
69    newim->nu   = nu ;
70    newim->nv   = nv ;
71    newim->nw   = nw ;
72 
73    newim->nxyz  = (int64_t)nx*(int64_t)ny*(int64_t)nz ;
74    newim->nxyzt = (int64_t)nx*(int64_t)ny*(int64_t)nz*(int64_t)nt ;
75    newim->nvox  = newim->nxyzt * (int64_t)nu*(int64_t)nv*(int64_t)nw ;
76 
77    newim->kind = kind ;
78    newim->name = NULL ;
79 
80    newim->dx = newim->dy = newim->dz =
81    newim->dt = newim->du = newim->dv = 1.0f;  /* default dimensions */
82 
83    newim->dw = -666.0f;  /* 05 Feb 2001 - flag that dimensions aren't set */
84 
85    newim->xo = newim->yo = newim->zo =
86    newim->to = newim->uo = newim->vo = newim->wo = 0.0f;  /* default offsets */
87 
88    newim->was_swapped = 0 ;  /* 07 Mar 2002 - flag that bytes were swapped */
89    newim->vdim        = 0 ;
90 
91 #ifdef USE_MRI_LABELS
92    newim->xlab[0] = '\0' ;          /* default labels */
93    newim->ylab[0] = '\0' ;
94    newim->zlab[0] = '\0' ;
95    newim->tlab[0] = '\0' ;
96    newim->ulab[0] = '\0' ;
97    newim->vlab[0] = '\0' ;
98    newim->wlab[0] = '\0' ;
99 #endif
100 
101    newim->fname   = NULL ;
102    newim->foffset = newim->fondisk = 0 ;
103 
104    newim->comments = NULL ;         /* 03 Aug 2016 */
105 
106    npix = newim->nvox ;
107 
108    switch( kind ){
109       case MRI_byte:    newim->pixel_size = sizeof(byte)     ; break ;
110       case MRI_short:   newim->pixel_size = sizeof(short)    ; break ;
111       case MRI_int:     newim->pixel_size = sizeof(int)      ; break ;
112       case MRI_float:   newim->pixel_size = sizeof(float)    ; break ;
113       case MRI_double:  newim->pixel_size = sizeof(double)   ; break ;
114       case MRI_complex: newim->pixel_size = sizeof(complex)  ; break ;
115       case MRI_rgb:     newim->pixel_size = 3 * sizeof(byte) ; break ;
116       case MRI_rgba:    newim->pixel_size = sizeof(rgba)     ; break ;
117       case MRI_fvect:   newim->pixel_size = sizeof(float)    ;
118                         newim->vdim       = 1                ; break ;
119 
120       default:
121         ERROR_message("mri_new: unrecognized image kind %d",(int)kind) ;
122         MRI_FATAL_ERROR ;
123    }
124 
125    if( PRINT_TRACING ){
126      char str[245] ;
127      sprintf(str,"nx=%d ny=%d nz=%d kind=%d bytes=%lld %s",
128              nx,ny,nz,(int)kind,(long long)(npix*newim->pixel_size),
129              make_space ? "(calloc)" : "(null)" ) ;
130      STATUS(str) ;
131    }
132 
133    if( make_space ) newim->im = calloc( newim->pixel_size , npix ) ;
134    else             newim->im = NULL ;
135 
136    if( make_space && newim->im == NULL ){
137      ERROR_message("malloc failure for image space: %lld bytes\n",
138                    (long long)(npix*newim->pixel_size) );
139      ERROR_message(" nx=%d ny=%d nz=%d npix=%lld",nx,ny,nz,(long long)npix) ;
140      MRI_FATAL_ERROR ;
141    }
142 
143    RETURN(newim) ;
144 }
145 
146 /*---------------------------------------------------------------------*/
147 /* Should properly move old data around, if there is any. */
148 
mri_adjust_fvectim(MRI_IMAGE * im,int vdim)149 void mri_adjust_fvectim( MRI_IMAGE *im , int vdim )
150 {
151    void *vpt ; int vdold ;
152 
153    if( im == NULL || im->kind != MRI_fvect || vdim < 1 ) return ;
154 
155    vdold          = im->vdim ;
156    im->vdim       = vdim ;
157    im->pixel_size = sizeof(float)*vdim ;
158 
159    mri_unpurge(im) ;
160 
161    if( im->im == NULL ){       /** no data, so create some **/
162 
163      vpt = calloc( im->pixel_size , im->nvox ) ;
164 
165    } else if( vdold < vdim ){  /** making each vector longer **/
166 
167      vpt = realloc( im->im , im->pixel_size*im->nvox ) ;
168      if( vpt != NULL ){
169        int64_t nvox , ii,jj ; float *far ;
170        far = (float *)vpt ; nvox = im->nvox ;
171        for( ii=nvox-1 ; ii >= 0 ; ii-- ){  /* move each old vect to new spot */
172          for( jj=0 ; jj < vdold ; jj++ ) far[vdim*ii+jj] = far[vdold*ii+jj] ;
173          for(      ; jj < vdim  ; jj++ ) far[vdim*ii+jj] = 0.0f ;
174        }
175      }
176 
177    } else if( vdold > vdim ){  /** making each vector shorter **/
178 
179      vpt = calloc( im->pixel_size , im->nvox ) ;  /* new space */
180      if( vpt != NULL ){
181        int64_t nvox , ii,jj ; float *far , *gar ;
182        far = (float *)vpt ; gar = (float *)im->im ; nvox = im->nvox ;
183        for( ii=0 ; ii < nvox ; ii++ ){  /* move each old vect to new spot */
184          for( jj=0 ; jj < vdim ; jj++ ) far[vdim*ii+jj] = gar[vdold*ii+jj] ;
185        }
186      }
187      free(im->im) ; /* will be replaced below */
188 
189    } else {                    /** nothing to be done?! **/
190 
191      vpt = im->im ;
192 
193    }
194 
195    /** make sure modified image has data space ready **/
196 
197    if( vpt == NULL ){
198      ERROR_message("malloc failure for fvectim space: %lld bytes",
199                    im->pixel_size*im->nvox );
200      MRI_FATAL_ERROR ;
201    }
202 
203    im->im = vpt ; return ;
204 }
205 
206 /*---------------------------------------------------------------------*/
207 
mri_new_fvectim(int nx,int ny,int nz,int vdim)208 MRI_IMAGE * mri_new_fvectim( int nx , int ny , int nz , int vdim )
209 {
210    MRI_IMAGE *im ;
211 
212    im = mri_new_vol_empty( nx , ny , nz , MRI_fvect ) ;
213    mri_adjust_fvectim( im , vdim ) ;
214    return(im) ;
215 }
216