#include "mrilib.h" #include #undef QBUF #define QBUF 4096 MRI_IMAGE * mri_read_stuff( char *fname ) { static int first=1 ; static char *jpeg_filter = NULL ; /* djpeg */ static char *gif_filter = NULL ; /* giftopnm */ static char *tiff_filter = NULL ; /* tifftopnm */ static char *bmp_filter = NULL ; /* bmptoppm */ static char *png_filter = NULL ; /* pngtopnm */ static char *pnm_filter = NULL ; /* cat */ char *pg , *pg2 , *filt=NULL ; int nf , nbuf , ipos , nx,ny,maxval=255 , bper,nbim, pbm=0 ; FILE *fp ; MRI_IMAGE *im ; byte *imar , *buf ; char *qs , *qd , *qname , *qq ; ENTRY("mri_read_stuff") ; /*--- check input for OK-ness ---*/ if( fname == NULL || *fname == '\0' ) RETURN(NULL) ; /*--- first time in, setup up filters to PNM format ---*/ if( first ){ first = 0 ; pg = THD_find_executable( "cat" ) ; /* cheap, but works */ if( pg != NULL ){ pnm_filter = AFMALL(char, strlen(pg)+32) ; sprintf( pnm_filter , "%s %%s" , pg ) ; } pg = THD_find_executable( "djpeg" ) ; if( pg != NULL ){ jpeg_filter = AFMALL(char, strlen(pg)+32) ; sprintf( jpeg_filter , "%s %%s" , pg ) ; } pg = THD_find_executable( "giftopnm" ) ; if( pg != NULL ){ gif_filter = AFMALL(char, strlen(pg)+32) ; sprintf( gif_filter , "%s %%s" , pg ) ; } pg = THD_find_executable( "tifftopnm" ) ; if( pg != NULL ){ tiff_filter = AFMALL(char, strlen(pg)+32) ; sprintf( tiff_filter , "%s %%s" , pg ) ; } pg = THD_find_executable( "bmptoppm" ) ; if( pg != NULL ){ bmp_filter = AFMALL(char, strlen(pg)+32) ; sprintf( bmp_filter , "%s %%s" , pg ) ; } pg = THD_find_executable( "pngtopnm" ) ; if( pg != NULL ){ png_filter = AFMALL(char, strlen(pg)+32) ; sprintf( png_filter , "%s %%s" , pg ) ; } } /*--- determine filter based on file suffix ---*/ nf = strlen(fname) ; if( nf < 5 ) RETURN(NULL); /* filename too short! */ pg = fname + (nf-4); /* points to last 4 chars */ pg2 = pg - 1; /* points to last 5 chars */ if( strcmp(pg ,".jpg" ) == 0 || strcmp(pg ,".JPG" ) == 0 || strcmp(pg2,".jpeg") == 0 || strcmp(pg2,".JPEG") == 0 ) filt = jpeg_filter ; else if( strcmp(pg ,".gif" ) == 0 || strcmp(pg ,".GIF" ) == 0 ) filt = gif_filter ; else if( strcmp(pg ,".pbm" ) == 0 || strcmp(pg ,".PBM" ) == 0 || strcmp(pg ,".pgm" ) == 0 || strcmp(pg ,".PGM" ) == 0 || strcmp(pg ,".ppm" ) == 0 || strcmp(pg ,".PPM" ) == 0 ) filt = pnm_filter ; else if( strcmp(pg ,".tif" ) == 0 || strcmp(pg ,".TIF" ) == 0 || strcmp(pg2,".tiff") == 0 || strcmp(pg2,".TIFF") == 0 ) filt = tiff_filter ; else if( strcmp(pg ,".bmp" ) == 0 || strcmp(pg ,".BMP" ) == 0 ) filt = bmp_filter ; else if( strcmp(pg ,".png" ) == 0 || strcmp(pg ,".PNG" ) == 0 ) filt = png_filter ; if( filt == NULL ) RETURN(NULL); /* didn't match, or no filter */ /*--- create the filter for this file and open the pipe ---*/ pg = AFMALL(char, nf+strlen(filt)+32) ; /* string to hold filter */ qs = strchr(fname,'\'') ; qd = strchr(fname,'\"') ; if( qs == NULL || qd == NULL ){ /* 22 Dec 2005: quotize name */ qq = (qs==NULL) ? "'" : "\"" ; qname = (char *)malloc(sizeof(char)*(nf+8)) ; strcpy(qname,qq); strcat(qname,fname); strcat(qname,qq); sprintf( pg , filt , qname ) ; free((void *)qname) ; } else { sprintf( pg , filt , fname ) ; } #ifndef CYGWIN signal( SIGPIPE , SIG_IGN ) ; /* ignore this signal */ #endif fp = popen( pg , "r" ) ; if( fp == NULL ){ free(pg); RETURN(NULL); } /* bad pipe */ buf = AFMALL(byte, QBUF) ; /* read buffer for initial data from pipe */ /*--- read 1st block from pipe ---*/ nbuf = fread( buf , 1 , QBUF , fp ) ; if( nbuf < 16 ){ /* bad read */ free(buf); free(pg); pclose(fp); RETURN(NULL); } if( buf[0] != 'P' ){ /* not a P?M file */ free(buf); free(pg); pclose(fp); RETURN(NULL); } if( buf[1] == '6' ) bper = 3 ; /* PPM from pipe */ else if( buf[1] == '5' ) bper = 1 ; /* PGM from pipe */ else if( buf[1] == '4' ){bper = 1 ; pbm=1; } /* PBM from pipe */ else { free(buf); free(pg); pclose(fp); RETURN(NULL); /* bad bad bad!! */ } ipos = 2 ; /* start scanning for PNM header stuff at position 2 in buf */ /* skip comment lines in the buffer */ #undef SKIPCOM #define SKIPCOM \ { if(buf[ipos]=='#') \ do{ ipos++; } while( ipos= nbuf ){ var = -1; } \ else { \ int nch; char chb[32]; \ for( nch=0 ; ipos= nbuf ){ /* bad */ free(buf); free(pg); pclose(fp); RETURN(NULL); } /* scan for the ny variable */ NUMSCAN(ny) ; if( ny < 2 || ipos >= nbuf ){ /* bad */ free(buf); free(pg); pclose(fp); RETURN(NULL); } /* scan for the maxval variable */ if( !pbm ){ NUMSCAN(maxval) ; if( maxval <= 0 || maxval > 255 || ipos >= nbuf ){ /* bad */ free(buf); free(pg); pclose(fp); RETURN(NULL); } } ipos++ ; /* skip byte after maxval; */ /* ipos now points at 1st byte of image data */ /*--- create output image struct ---*/ if( bper == 3 ){ /* PPM */ im = mri_new( nx , ny , MRI_rgb ) ; imar = MRI_RGB_PTR(im) ; } else { /* PGM or PBM */ im = mri_new( nx , ny , MRI_byte ) ; imar = MRI_BYTE_PTR(im) ; } mri_add_name( fname , im ) ; nbim = bper * nx * ny ; /* num bytes in image array imar */ /*--- copy remaining data in buf (if any) to image array ---*/ nbuf = nbuf - ipos ; /* num bytes left in buf */ if( nbuf > nbim ) nbuf = nbim ; /* but don't want too much */ if( nbuf > 0 ) memcpy( imar , buf+ipos , nbuf ) ; free(buf) ; /* have used this up now */ /*--- read rest of image array directly from pipe ---*/ if( nbuf < nbim ) fread( imar+nbuf , 1 , nbim-nbuf , fp ) ; free(pg) ; pclose(fp) ; /* toss out the trash */ /*--- if was really a PBM image, inflate to PGM now ---*/ if( pbm ) mri_inflate_pbm( im ) ; /* 02 Jan 2003 */ /*--- if maxval < 255, scale byte data up to that level ---*/ if( maxval < 255 ){ int ii ; float fac = 255.4/maxval ; for( ii=0 ; ii < nbim ; ii++ ) imar[ii] = (byte)( imar[ii]*fac ) ; } /*--- vamoose the ranch ---*/ RETURN(im); } /*--------------------------------------------------------------------------*/ /*! Inflate data from PBM to PGM, in place. ----------------------------------------------------------------------------*/ void mri_inflate_pbm( MRI_IMAGE *im ) /* 02 Jan 2002 */ { MRI_IMAGE *qim ; byte *qimar , *imar ; int ii,jj , nx,ny , nbrow , i8 ; byte bmask[8] = { 1<<7 , 1<<6 , 1<<5 , 1<<4 , 1<<3 , 1<<2 , 1<<1 , 1 } ; ENTRY("mri_inflate_pbm") ; if( im == NULL || im->kind != MRI_byte ) EXRETURN ; nx = im->nx ; ny = im->ny ; qim = mri_new( nx , ny , MRI_byte ) ; qimar = MRI_BYTE_PTR(qim) ; imar = MRI_BYTE_PTR(im) ; nbrow = nx/8 ; if( 8*nbrow < nx ) nbrow++ ; for( jj=0 ; jj < ny ; jj++ ) for( ii=0 ; ii < nx ; ii++ ){ i8 = ii >> 3 ; qimar[ii+jj*nx] = ( imar[(i8)+jj*nbrow] & bmask[ii&7] ) != 0 ; } memcpy( imar , qimar , nx*ny ) ; mri_free( qim ) ; EXRETURN ; }