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