#include "mrilib.h" int main( int argc , char * argv[] ) { THD_3dim_dataset *dset1,*dset2=NULL,*dset3=NULL , *mset=NULL , *oset ; MRI_IMAGE *dbr1,*dbr2,*dbr3 ; float fac1, fac2, fac3 ; char *prefix = "rgb" ; byte *mask=NULL , *rr,*gg,*bb , *rgb ; float fac=1.0 ; int iarg=1 , dofim=1 , ii,nvox ; if( argc < 2 || strcmp(argv[1],"-help") == 0 ){ printf("Usage #1: 3dThreetoRGB [options] dataset\n" "Usage #2: 3dThreetoRGB [options] dataset1 dataset2 dataset3\n" "\n" "Converts 3 sub-bricks of input to an RGB-valued dataset.\n" "* If you have 1 input dataset, then sub-bricks [0..2] are\n" " used to form the RGB components of the output.\n" "* If you have 3 input datasets, then the [0] sub-brick of\n" " each is used to form the RGB components, respectively.\n" "* RGB datasets have 3 bytes per voxel, with values ranging\n" " from 0..255.\n" "\n" "Options:\n" " -prefix ppp = Write output into dataset with prefix 'ppp'.\n" " [default='rgb']\n" " -scale fac = Multiply input values by 'fac' before using\n" " as RGB [default=1]. If you have floating\n" " point inputs in range 0..1, then using\n" " '-scale 255' would make a lot of sense.\n" " -mask mset = Only output nonzero values where the mask\n" " dataset 'mset' is nonzero.\n" " -fim = Write result as a 'fim' type dataset.\n" " [this is the default]\n" " -anat = Write result as a anatomical type dataset.\n" "Notes:\n" "* Input datasets must be byte-, short-, or float-valued.\n" "* You might calculate the component datasets using 3dcalc.\n" "* You can also create RGB-valued datasets in to3d, using\n" " 2D raw PPM image files as input, or the 3Dr: format.\n" "* RGB fim overlays are transparent in AFNI in voxels where all\n" " 3 bytes are zero - that is, it won't overlay solid black.\n" "* At present, there is limited support for RGB datasets.\n" " About the only thing you can do is display them in 2D\n" " slice windows in AFNI.\n" "\n" "-- RWCox - April 2002\n" ) ; PRINT_COMPILE_DATE ; exit(0) ; } mainENTRY("3dThreetoRGB main"); machdep(); AFNI_logger("3dThreetoRGB",argc,argv); /*-- options --*/ #define GOOD_TYPE(tt) ((tt)==MRI_short || (tt)==MRI_byte || (tt)==MRI_float) while( iarg < argc && argv[iarg][0] == '-' ){ if( strcmp(argv[iarg],"-prefix") == 0 ){ prefix = argv[++iarg] ; if( !THD_filename_ok(prefix) ){ fprintf(stderr,"** -prefix %s is illegal!\n",prefix) ; exit(1) ; } iarg++ ; continue ; } if( strcmp(argv[iarg],"-scale") == 0 ){ fac = strtod( argv[++iarg] , NULL ) ; if( fac <= 0.0 ){ fprintf(stderr,"** -scale %s is illegal!\n",argv[iarg]) ; exit(1) ; } iarg++ ; continue ; } if( strcmp(argv[iarg],"-fim") == 0 ){ dofim = 1 ; iarg++ ; continue ; } if( strcmp(argv[iarg],"-anat") == 0 ){ dofim = 0 ; iarg++ ; continue ; } if( strcmp(argv[iarg],"-mask") == 0 ){ if( mset != NULL ){ fprintf(stderr,"** can't have 2 -mask options!\n"); exit(1); } mset = THD_open_dataset( argv[++iarg] ) ; if( !ISVALID_DSET(mset) ){ fprintf(stderr,"** can't open -mset %s\n",argv[iarg]); exit(1); } if( !GOOD_TYPE( DSET_BRICK_TYPE(mset,0) ) ){ fprintf(stderr,"** -mset %s has invalid data type\n",argv[iarg]); exit(1) ; } DSET_load(mset) ; CHECK_LOAD_ERROR(mset) ; iarg++ ; continue ; } fprintf(stderr,"** ILLEGAL option: %s\n",argv[iarg]) ; exit(1) ; } if( iarg >= argc ){ fprintf(stderr,"** No datasets on command line!?\n"); exit(1); } /*-- read data --*/ #define OPENIT(ds,aa) \ do{ \ ds = THD_open_dataset(aa) ; \ if( !ISVALID_DSET(ds) ){ \ fprintf(stderr,"** Can't open dataset %s\n",aa); exit(1); \ } \ DSET_load(ds) ; CHECK_LOAD_ERROR(ds) ; \ } while(0) if( iarg == argc-1 ){ /* one dataset */ OPENIT(dset1,argv[iarg]) ; if( DSET_NVALS(dset1) < 3 ){ fprintf(stderr,"** Dataset %s needs at least 3 sub-bricks!\n",argv[iarg]); exit(1) ; } if( !GOOD_TYPE( DSET_BRICK_TYPE(dset1,0) ) || !GOOD_TYPE( DSET_BRICK_TYPE(dset1,1) ) || !GOOD_TYPE( DSET_BRICK_TYPE(dset1,2) ) ){ fprintf(stderr,"** ILLEGAL dataset type in %s\n",argv[iarg]); exit(1); } dbr1 = DSET_BRICK(dset1,0) ; fac1 = DSET_BRICK_FACTOR(dset1,0) ; dbr2 = DSET_BRICK(dset1,1) ; fac2 = DSET_BRICK_FACTOR(dset1,1) ; dbr3 = DSET_BRICK(dset1,2) ; fac3 = DSET_BRICK_FACTOR(dset1,2) ; } else if( iarg+2 < argc ){ /* three datasets */ OPENIT(dset1,argv[iarg]) ; if( !GOOD_TYPE( DSET_BRICK_TYPE(dset1,0) ) ){ fprintf(stderr,"** ILLEGAL dataset type in %s\n",argv[iarg]) ; exit(1); } OPENIT(dset2,argv[iarg+1]) ; if( !GOOD_TYPE( DSET_BRICK_TYPE(dset2,0) ) ){ fprintf(stderr,"** ILLEGAL dataset type in %s\n",argv[iarg+1]); exit(1); } OPENIT(dset3,argv[iarg+2]) ; if( !GOOD_TYPE( DSET_BRICK_TYPE(dset3,0) ) ){ fprintf(stderr,"** ILLEGAL dataset type in %s\n",argv[iarg+2]); exit(1); } dbr1 = DSET_BRICK(dset1,0) ; fac1 = DSET_BRICK_FACTOR(dset1,0) ; dbr2 = DSET_BRICK(dset2,0) ; fac2 = DSET_BRICK_FACTOR(dset2,0) ; dbr3 = DSET_BRICK(dset3,0) ; fac3 = DSET_BRICK_FACTOR(dset3,0) ; if( dbr1->nx != dbr2->nx || dbr1->nx != dbr3->nx ){ fprintf(stderr,"** Dataset x-axes don't match!\n") ; exit(1) ; } if( dbr1->ny != dbr2->ny || dbr1->ny != dbr3->ny ){ fprintf(stderr,"** Dataset y-axes don't match!\n") ; exit(1) ; } if( dbr1->nz != dbr2->nz || dbr1->nz != dbr3->nz ){ fprintf(stderr,"** Dataset z-axes don't match!\n") ; exit(1) ; } if( iarg+2 < argc-1 ){ fprintf(stderr,"++ Warning: extra arguments on command line: %s ...\n", argv[iarg+3] ) ; } } else { /* this is bad */ fprintf(stderr,"** Need either 1 or 3 datasets on command line!\n"); exit(1) ; } /* make a mask, if any */ if( mset != NULL ){ if( dbr1->nx != DSET_NX(mset) ){ fprintf(stderr,"** Mask and dataset x-axes don't match!\n"); exit(1); } if( dbr1->ny != DSET_NY(mset) ){ fprintf(stderr,"** Mask and dataset y-axes don't match!\n"); exit(1); } if( dbr1->nz != DSET_NZ(mset) ){ fprintf(stderr,"** Mask and dataset z-axes don't match!\n"); exit(1); } mask = THD_makemask( mset , 0 , 1.0,0.0 ) ; if( mask == NULL ){ fprintf(stderr,"** Can't make mask!\n"); exit(1); } DSET_unload(mset) ; } /* convert input sub-bricks to bytes */ nvox = dbr1->nvox ; rr = (byte *) calloc(1,nvox) ; if( fac1 == 0.0 ) fac1 = 1.0 ; EDIT_coerce_scale_type( nvox , fac*fac1 , dbr1->kind , mri_data_pointer(dbr1) , MRI_byte , rr ) ; gg = (byte *) calloc(1,nvox) ; if( fac2 == 0.0 ) fac2 = 1.0 ; EDIT_coerce_scale_type( nvox , fac*fac2 , dbr2->kind , mri_data_pointer(dbr2) , MRI_byte , gg ) ; bb = (byte *) calloc(1,nvox) ; if( fac3 == 0.0 ) fac3 = 1.0 ; EDIT_coerce_scale_type( nvox , fac*fac3 , dbr3->kind , mri_data_pointer(dbr3) , MRI_byte , bb ) ; DSET_unload(dset1) ; if( dset2 != NULL ) DSET_unload(dset2) ; if( dset3 != NULL ) DSET_unload(dset3) ; /* merge inputs to output */ rgb = (byte *) calloc(1,3*nvox) ; if( mask != NULL ){ for( ii=0 ; ii < nvox ; ii++ ){ if( mask[ii] ){ rgb[3*ii ] = rr[ii] ; rgb[3*ii+1] = gg[ii] ; rgb[3*ii+2] = bb[ii] ; } } } else { for( ii=0 ; ii < nvox ; ii++ ){ rgb[3*ii ] = rr[ii] ; rgb[3*ii+1] = gg[ii] ; rgb[3*ii+2] = bb[ii] ; } } free(mask) ; free(rr) ; free(gg) ; free(bb) ; /* make output dataset */ oset = EDIT_empty_copy( dset1 ) ; EDIT_dset_items( oset , ADN_prefix , prefix , ADN_datum_all, MRI_rgb , ADN_nvals , 1 , ADN_ntt , 0 , ADN_type , (dofim) ? HEAD_FUNC_TYPE : HEAD_ANAT_TYPE, ADN_func_type, (dofim) ? FUNC_FIM_TYPE : ANAT_SPGR_TYPE, ADN_none ) ; EDIT_substitute_brick( oset , 0 , MRI_rgb , rgb ) ; /* make history */ tross_Copy_History( oset , dset1 ) ; tross_Make_History( "3dThreetoRGB", argc,argv, oset ) ; if (DSET_write( oset ) != False) { fprintf(stderr,"++ output dataset: %s\n",DSET_BRIKNAME(oset)) ; exit(0) ; } else { fprintf(stderr, "** 3dThreetoRGB: Failed to write output!\n" ) ; exit(1) ; } }