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 /*-------------------------------------------------------------------------*/
12 /*! Open a file for writing, if practicable.  Use fclose_maybe() to close. */
13 
fopen_maybe(char * fname)14 FILE * fopen_maybe( char *fname )  /* 05 Feb 2008 */
15 {
16    FILE *imfile ;
17    char *tname = NULL;
18    int   tlen;
19 
20    if( fname == NULL || *fname == '\0' ) return NULL ;  /* bad input */
21 
22    /* special case -- be sure not to fclose() stdout! */
23 
24    /* ------------------------------------------------------------- */
25    /* test file streams with tname, where any .1D has been stripped */
26    /* note: the .1D suffix might come from EDIT_dset_items()        */
27    /* problem noted by I Schwabacher            13 Nov 2012 [rickr] */
28    tlen = strlen(fname);
29    if( tlen > 3 && !strcmp(fname+tlen-3, ".1D") ) {
30       tname = strdup(fname);
31       tname[tlen-3] = '\0';
32    } else tname = fname;
33 
34    if( strcmp(tname,"-") == 0 || strcmp (tname,"stdout")    == 0
35                               || strncmp(tname,"stdout:",7) == 0 ) return stdout ;
36 
37    if( strcmp (tname,"stderr"   ) == 0 ||
38        strncmp(tname,"stderr:",7) == 0   ) return stderr ;
39 
40    if( tname != fname ) free(tname);             /* done with tname */
41    /* ------------------------------------------------------------- */
42 
43    if( THD_is_ondisk(fname) ){   /* check for existing file */
44      if( !THD_ok_overwrite() ){  /* if not allowed to overwrite */
45        ERROR_message("(FAILED) attempt to over-write file %s",fname) ;
46        return NULL ;
47      } else {
48        WARNING_message("over-writing file %s",fname) ;  /* tell the user */
49      }
50    }
51 
52    imfile = fopen(fname,"w") ;
53    if( imfile == NULL ){ NI_sleep(33) ; imfile = fopen(fname,"w") ; }
54    if( imfile == NULL ){ NI_sleep(66) ; imfile = fopen(fname,"w") ; }
55    if( imfile == NULL ){ NI_sleep(99) ; imfile = fopen(fname,"w") ; }
56    if( imfile == NULL ) ERROR_message("Can't open for output: %s",fname) ;
57    return imfile ;
58 }
59 
60 /*---------------------------------------------------------------------------*/
61 
fclose_maybe(FILE * fp)62 void fclose_maybe( FILE *fp )  /* 05 Feb 2008 */
63 {
64         if( fp == NULL   ) return ;
65         if( fp == stdout ) fflush(fp) ;
66    else if( fp != stderr ) fclose(fp) ;
67    return ;
68 }
69 
70 /*---------------------------------------------------------------------------*/
71 /* 28 Aug 1996: return value changed from void to int,
72                 which will be the number of files written to disk
73                 (either 0 or 1 at the present time).             */
74 
mri_write(char * fname,MRI_IMAGE * im)75 int mri_write( char *fname , MRI_IMAGE *im )
76 {
77    FILE  *imfile ;
78    void  *data ;
79    int   dsize , noheader = FALSE ;
80 
81 ENTRY("mri_write") ;
82 
83    /* bad inputs? */
84 
85    if( im == NULL || fname == NULL || *fname == '\0' ) RETURN(0) ;
86 
87    /* special cases */
88 
89    if( ! MRI_IS_2D(im)      ){ RETURN(mri_write_7D ( fname , im )) ; }
90    if( im->kind == MRI_rgb  ){ RETURN(mri_write_pnm( fname , im )) ; }
91    if( im->kind == MRI_byte ){ RETURN(mri_write_pnm( fname , im )) ; }
92 
93    /* open the file for output */
94 
95    imfile = fopen_maybe(fname) ;
96    if( imfile == NULL ) RETURN(0) ;
97 
98    /*** possibly write MRI header, unless a standard image type ***/
99 
100    dsize = im->pixel_size * im->nx * im->ny ;
101 
102    if( im->kind == MRI_short ){
103       switch( dsize ){
104          default: noheader = FALSE ; break ;
105 
106          case 8192:    /* raw 64x64 short */
107          case 32768:   /* raw 128x128 short */
108          case 131072:  /* raw 256x256 short */
109          case 524288:  /* raw 512x512 short -- RWC 3/21/95 */
110          case 2097152: /* raw 1024x1024 short -- RWC 3/21/95 */
111             noheader = TRUE ;
112             break ;
113       }
114    } else if( im->kind == MRI_byte ){
115       switch( dsize ){
116          default: noheader = FALSE ; break ;
117 
118          case 4096:    /* raw 64x64 byte -- RWC 3/21/95 */
119          case 16384:   /* raw 128x128 byte -- RWC 3/21/95 */
120          case 65536:   /* raw 256x256 8-bit -- Matthew Belmonte March 1995 */
121          case 262144:  /* raw 512x512 byte -- RWC 3/21/95 */
122          case 1048576: /* raw 1024x1024 byte -- RWC 3/21/95 */
123             noheader = TRUE ;
124             break ;
125       }
126    }
127 
128    if( !noheader ) fprintf( imfile , "MRI %d %d %d\n" ,
129                                      im->kind , im->nx , im->ny ) ;
130 
131    /*** special case: add Signa 4.x header (of all zeros) ***/
132 
133    if( noheader && dsize == 131072 && im->kind == MRI_short ){
134 #define HEADER (28*256)
135       int ii ;
136       short * qq ;
137       qq = (short *) malloc(sizeof(short)*HEADER) ;  /* header 256 x 256 */
138       for( ii=0 ; ii < HEADER ; ii++ ) qq[ii] = 0 ;
139       fwrite( qq , sizeof(short) , HEADER , imfile ) ;
140       free(qq) ;
141    }
142 
143    /*** write rest of data now ***/
144 
145    data = mri_data_pointer( im ) ;
146    fwrite( data , im->pixel_size , im->nx * im->ny , imfile ) ;
147 
148    fclose_maybe(imfile) ;
149    RETURN(1) ;
150 }
151 
152 /**************************************************************************/
153 
mri_write_7D(char * fname,MRI_IMAGE * im)154 int mri_write_7D( char *fname , MRI_IMAGE *im )
155 {
156    FILE  *imfile ;
157    void  *data ;
158 
159 ENTRY("mri_write_7D") ;
160 
161    if( im == NULL ) RETURN( 0 );
162 
163    imfile = fopen_maybe(fname) ;
164    if( imfile == NULL ) RETURN(0) ;
165 
166    /*** write MR7 header ***/
167 
168    switch( mri_dimensionality(im) ){
169       default:
170       case 1:
171          fprintf( imfile , "MR1 %d %d\n" ,
172                   im->kind , im->nx ) ;
173       break ;
174 
175       case 2:
176          fprintf( imfile , "MR2 %d %d %d\n" ,
177                   im->kind , im->nx,im->ny ) ;
178       break ;
179 
180       case 3:
181          fprintf( imfile , "MR2 %d %d %d %d\n" ,
182                   im->kind , im->nx,im->ny,im->nz ) ;
183       break ;
184 
185       case 4:
186          fprintf( imfile , "MR2 %d %d %d %d %d\n" ,
187                   im->kind , im->nx,im->ny,im->nz,im->nt ) ;
188       break ;
189 
190       case 5:
191          fprintf( imfile , "MR2 %d %d %d %d %d %d\n" ,
192                   im->kind , im->nx,im->ny,im->nz,im->nt,im->nu ) ;
193       break ;
194 
195       case 6:
196          fprintf( imfile , "MR2 %d %d %d %d %d %d %d\n" ,
197                   im->kind , im->nx,im->ny,im->nz,im->nt,im->nu,im->nv ) ;
198       break ;
199 
200       case 7:
201          fprintf( imfile , "MR2 %d %d %d %d %d %d %d %d\n" ,
202                   im->kind , im->nx,im->ny,im->nz,im->nt,im->nu,im->nv,im->nw ) ;
203       break ;
204    }
205 
206    /*** write rest of data now ***/
207 
208    data = mri_data_pointer( im ) ;
209    fwrite( data , im->pixel_size , im->nvox , imfile ) ;
210    fclose_maybe(imfile) ;
211 
212    RETURN( 1 );
213 }
214 
215 /**************************************************************************/
216 
mri_write_pnm(char * fname,MRI_IMAGE * im)217 int mri_write_pnm( char *fname , MRI_IMAGE *im )
218 {
219    FILE  *imfile ;
220    void  *data ;
221    int   dsize , noheader = FALSE ;
222 
223 ENTRY("mri_write_pnm") ;
224 
225    if( im == NULL || fname == NULL || *fname == '\0' ) RETURN( 0 );
226    if( im->nz > 1 ) RETURN( 0 );
227    if( im->kind != MRI_byte && im->kind != MRI_rgb   ) RETURN( 0 );
228 
229    if( STRING_HAS_SUFFIX_CASE(fname,".jpg") ){   /* 15 Apr 2005: quick hack */
230      RETURN( mri_write_jpg(fname,im) ) ;
231    } else if( STRING_HAS_SUFFIX_CASE(fname,".png") ){  /* 11 Dec 2006 */
232      RETURN( mri_write_png(fname,im) ) ;
233    } else if( *fname == '|' ){                   /* 15 Dec 2006: pipe */
234      RETURN( mri_write_filtered(fname+1,im) ) ;
235    }
236 
237    imfile = fopen_maybe(fname) ;
238    if( imfile == NULL ) RETURN(0) ;
239 
240    switch( im->kind ){
241 
242      default: break ;
243 
244      case MRI_byte:
245        fprintf( imfile , "P5\n%d %d\n255\n" , im->nx,im->ny ) ;     /* header */
246        fwrite( MRI_BYTE_PTR(im), sizeof(byte), im->nvox, imfile ) ; /* bytes */
247      break ;
248 
249      case MRI_rgb:
250        fprintf( imfile , "P6\n%d %d\n255\n" , im->nx,im->ny ) ;      /* header */
251        fwrite( MRI_RGB_PTR(im), sizeof(byte), 3*im->nvox, imfile ) ; /* bytes */
252      break ;
253 
254    }
255 
256    fclose_maybe(imfile) ;
257    RETURN( 1 );
258 }
259 
260 /*---------------------------------------------------------------------------------------*/
261 
mri_write_1D(char * fname,MRI_IMAGE * im)262 int mri_write_1D( char *fname , MRI_IMAGE *im )  /* 16 Nov 1999 */
263 {
264    MRI_IMAGE *fim ;
265    int jj ;
266 
267 ENTRY("mri_write_1D") ;
268 
269    if( im == NULL || im->nz > 1 ) RETURN( 0 ) ; /* stoopid user */
270 
271    if( STRING_HAS_SUFFIX_CASE(fname,".tsv") ){  /* 14 Sep 2018 */
272      NI_element *nel ;
273      nel = THD_mri_to_tsv_element(im,NULL) ;
274      if( nel == NULL ) RETURN( 0 ) ;
275      THD_write_tsv( fname , nel ) ;
276      NI_free_element( nel ) ;
277      RETURN( 1 ) ;
278    }
279 
280    fim = mri_transpose( im ) ;
281    jj  = mri_write_ascii( fname , fim ) ;
282    mri_free(fim) ;
283    RETURN( jj );
284 }
285 
286 /**------------------------ Only good for 1D and 2D images ---------------------------**/
287 
mri_write_ascii(char * fname,MRI_IMAGE * im)288 int mri_write_ascii( char *fname, MRI_IMAGE *im )
289 {
290    int ii , jj , nx , ny ;
291    FILE  *imfile ;
292 
293 ENTRY("mri_write_ascii") ;
294 
295    if( im == NULL || im->nz > 1 ) RETURN( 0 ) ; /* stoopid user */
296 
297    if( fname == NULL || *fname == '\0' ) fname = "-" ; /* to stdout */
298    imfile = fopen_maybe(fname) ;
299    if( imfile == NULL ) RETURN(0) ;
300 
301    ii = mri_floatscan( im ) ;  /* 05 Apr 2010 */
302    if( ii > 0 )
303      WARNING_message("Zeroed %d float error%s while writing 1D file %s",
304                      ii , (ii > 1) ? "s" : "\0" , fname ) ;
305 
306    nx = im->nx ; ny = im->ny ;
307 
308    for( jj=0 ; jj < ny ; jj++ ){
309 
310       switch( im->kind ){
311 
312          default: break ;
313 
314          case MRI_float:{
315            float *iar = MRI_FLOAT_PTR(im) + (jj*nx) ;
316            for( ii=0 ; ii < nx ; ii++ )
317              fprintf(imfile," %14g",iar[ii]) ;
318          }
319          break ;
320 
321          case MRI_short:{
322            short *iar = MRI_SHORT_PTR(im) + (jj*nx) ;
323            for( ii=0 ; ii < nx ; ii++ )
324              fprintf(imfile," %6d",iar[ii]) ;
325          }
326          break ;
327 
328          case MRI_byte:{
329            byte *iar = MRI_BYTE_PTR(im) + (jj*nx) ;
330            for( ii=0 ; ii < nx ; ii++ )
331              fprintf(imfile," %3d",iar[ii]) ;
332          }
333          break ;
334 
335          case MRI_int:{
336            int *iar = MRI_INT_PTR(im) + (jj*nx) ;
337            for( ii=0 ; ii < nx ; ii++ )
338              fprintf(imfile," %6d",iar[ii]) ;
339          }
340          break ;
341 
342          case MRI_double:{
343            double *iar = MRI_DOUBLE_PTR(im) + (jj*nx) ;
344            for( ii=0 ; ii < nx ; ii++ )
345              fprintf(imfile," %16g",iar[ii]) ;
346          }
347          break ;
348 
349          case MRI_complex:{
350            complex *iar = MRI_COMPLEX_PTR(im) + (jj*nx) ;
351            for( ii=0 ; ii < nx ; ii++ )
352              fprintf(imfile," %-1.7g;%-1.7g",iar[ii].r,iar[ii].i) ;
353          }
354          break ;
355 
356          case MRI_rgb:{
357            byte *iar = MRI_RGB_PTR(im) + (3*jj*nx) ;
358            for( ii=0 ; ii < nx ; ii++ )
359              fprintf(imfile," %3d %3d %3d",iar[3*ii],iar[3*ii+1],iar[3*ii+2]) ;
360          }
361          break ;
362       }
363 
364       fprintf(imfile,"\n") ;
365    }
366 
367    fclose_maybe(imfile) ;
368    RETURN( 1 );
369 }
370 
371 /*------------------------------------------------------------
372    05 Jan 2000: write raw data from image
373 --------------------------------------------------------------*/
374 
mri_write_raw(char * fname,MRI_IMAGE * im)375 int mri_write_raw( char *fname , MRI_IMAGE *im )
376 {
377    FILE *imfile ;
378    void *data ;
379    int  dsize ;
380 
381 ENTRY("mri_write_raw") ;
382 
383    if( im == NULL || fname == NULL || fname[0] == '\0' ) RETURN( 0 );
384 
385    dsize = im->pixel_size * im->nvox ;
386    data  = mri_data_pointer( im ) ;
387 
388    if( dsize <= 0 || data == NULL ) RETURN( 0 );
389 
390    if( THD_is_file(fname) )
391      WARNING_message("Over-writing file %s",fname) ;
392 
393    imfile = fopen_maybe(fname) ;
394    if( imfile == NULL ) RETURN(0) ;
395 
396    fwrite( data , 1 , dsize , imfile ) ;
397    fclose_maybe( imfile ) ;
398    RETURN( 1 );
399 }
400 
401 /*---------------------------------------------------------------*/
402 
403 #include <signal.h>
404 
mri_write_jpg(char * fname,MRI_IMAGE * im)405 int mri_write_jpg( char *fname , MRI_IMAGE *im )  /* 15 Apr 2005 */
406 {
407    char *pg , *jpfilt, *eee ;
408    FILE *fp ;
409    int jpeg_compress;
410    MRI_IMAGE *qim ; int qq ;
411 
412 ENTRY("mri_write_jpg") ;
413 
414    if( fname == NULL || *fname == '\0' || im == NULL ) RETURN(0) ;
415    if( im->kind != MRI_rgb && im->kind != MRI_byte   ){
416      qim = mri_to_byte(im) ;
417    } else {
418      qim = im ;
419    }
420 
421    if( STRING_HAS_SUFFIX_CASE(fname,".png") ){  /* 07 Dec 2007 */
422      qq = mri_write_png(fname,qim) ;
423      if( qim != im ) mri_free(qim) ;
424      RETURN(qq) ;
425    }
426    if( STRING_HAS_SUFFIX_CASE(fname,".ppm") ||
427        STRING_HAS_SUFFIX_CASE(fname,".pgm") ||
428        STRING_HAS_SUFFIX_CASE(fname,".pnm")   ){
429      qq = mri_write_pnm(fname,im) ;
430      if( qim != im ) mri_free(qim) ;
431      RETURN(qq) ;
432    }
433 
434    pg = THD_find_executable( "cjpeg" ) ;
435    if( pg == NULL ){
436      if( qim != im ) mri_free(qim) ;
437      RETURN(0) ;
438    }
439 
440    /* user environment variable compression quality - mod 5/10/2006 drg */
441    eee = my_getenv("AFNI_JPEG_COMPRESS");
442    if(eee!=NULL){
443      jpeg_compress = strtod(eee, NULL);
444      if((jpeg_compress<=0) || (jpeg_compress>100)) jpeg_compress = 95;
445    }
446    else jpeg_compress = 95;
447 
448    jpfilt = (char *)malloc( sizeof(char)*(strlen(pg)+strlen(fname)+32) ) ;
449    sprintf( jpfilt , "%s -quality %d > %s" , pg , jpeg_compress, fname ) ;
450 #ifndef CYGWIN
451    signal( SIGPIPE , SIG_IGN ) ;
452 #endif
453    fp = popen( jpfilt , "w" ) ;
454    if( fp == NULL ){
455      free((void *)jpfilt);
456      if( qim != im ) mri_free(qim) ;
457      RETURN(0);
458    }
459 
460    if( qim->kind == MRI_rgb ){
461      fprintf(fp,"P6\n%d %d\n255\n" , qim->nx,qim->ny ) ;
462      fwrite( MRI_RGB_PTR(qim), sizeof(byte), 3*qim->nvox, fp ) ;
463    } else if( qim->kind == MRI_byte ){
464      fprintf(fp,"P5\n%d %d\n255\n" , qim->nx,qim->ny ) ;
465      fwrite( MRI_BYTE_PTR(qim), sizeof(byte), qim->nvox, fp ) ;
466    }
467    (void) pclose(fp) ; free((void *)jpfilt) ;
468    if( qim != im ) mri_free(qim) ;
469    RETURN(1) ;
470 }
471 
472 /*---------------------------------------------------------------*/
473 
mri_write_png(char * fname,MRI_IMAGE * im)474 int mri_write_png( char *fname , MRI_IMAGE *im )  /* 11 Dec 2006 */
475 {
476    char *pg , *pgfilt ;
477    FILE *fp ;
478 
479 ENTRY("mri_write_png") ;
480 
481    if( fname == NULL || *fname == '\0' || im == NULL ) RETURN(0) ;
482    if( im->kind != MRI_rgb && im->kind != MRI_byte   ) RETURN(0) ;
483 
484    if( STRING_HAS_SUFFIX_CASE(fname,".jpg") ){  /* 07 Dec 2007 */
485      RETURN( mri_write_jpg(fname,im) ) ;
486    }
487    if( STRING_HAS_SUFFIX_CASE(fname,".ppm") ||
488        STRING_HAS_SUFFIX_CASE(fname,".pgm") ||
489        STRING_HAS_SUFFIX_CASE(fname,".pnm")   ){
490      RETURN( mri_write_pnm(fname,im) ) ;
491    }
492 
493    pg = THD_find_executable( "pnmtopng" ) ; if( pg == NULL ) RETURN(0) ;
494    pgfilt = (char *)malloc( sizeof(char)*(strlen(pg)+strlen(fname)+32) ) ;
495    sprintf( pgfilt , "%s -compression 9 > %s" , pg , fname ) ;
496 #ifndef CYGWIN
497    signal( SIGPIPE , SIG_IGN ) ;
498 #endif
499    fp = popen( pgfilt , "w" ) ;
500    if( fp == NULL ){ free((void *)pgfilt); RETURN(0); }
501 
502    if( im->kind == MRI_rgb ){
503      fprintf(fp,"P6\n%d %d\n255\n" , im->nx,im->ny ) ;
504      fwrite( MRI_RGB_PTR(im), sizeof(byte), 3*im->nvox, fp ) ;
505    } else if( im->kind == MRI_byte ){
506      fprintf(fp,"P5\n%d %d\n255\n" , im->nx,im->ny ) ;
507      fwrite( MRI_BYTE_PTR(im), sizeof(byte), im->nvox, fp ) ;
508    }
509    (void) pclose(fp) ; free((void *)pgfilt) ; RETURN(1) ;
510 }
511 
512 /*---------------------------------------------------------------*/
513 
mri_write_filtered(char * fname,MRI_IMAGE * im)514 int mri_write_filtered( char *fname , MRI_IMAGE *im )  /* 15 Dec 2006 */
515 {
516    FILE *fp ;
517 
518    if( fname == NULL || im == NULL )                   return 0 ;
519    if( im->kind != MRI_rgb && im->kind != MRI_byte   ) return 0 ;
520    if( *fname == '|' ) fname++ ;   /* skip pipe character, if present */
521    if( *fname == '\0' )                                return 0 ;
522 
523 #ifndef CYGWIN
524    signal( SIGPIPE , SIG_IGN ) ;
525 #endif
526    fp = popen( fname , "w" ) ; if( fp == NULL ) return 0 ;
527 
528    if( im->kind == MRI_rgb ){
529      fprintf(fp,"P6\n%d %d\n255\n" , im->nx,im->ny ) ;
530      fwrite( MRI_RGB_PTR(im), sizeof(byte), 3*im->nvox, fp ) ;
531    } else if( im->kind == MRI_byte ){
532      fprintf(fp,"P5\n%d %d\n255\n" , im->nx,im->ny ) ;
533      fwrite( MRI_BYTE_PTR(im), sizeof(byte), im->nvox, fp ) ;
534    }
535    (void) pclose(fp) ;
536    return 1 ;
537 }
538 
539 /*---------------------------------------------------------------*/
540 
mri_write_floatvec(char * fname,floatvec * fv)541 void mri_write_floatvec( char *fname , floatvec *fv ) /* 21 Jan 2016 */
542 {
543    MRI_IMAGE *fim ;
544 
545    if( fname == NULL || fv == NULL ) return ;
546 
547    fim = mri_new_vol_empty( fv->nar,1,1, MRI_float ) ;
548    mri_set_data_pointer( fim , fv->ar ) ;
549    mri_write_1D( fname , fim ) ;
550    mri_clear_data_pointer( fim ) ;
551    mri_free( fim ) ;
552    return ;
553 }
554