/* The portable graymap format is a lowest common denominator grayscale file format. The definition is as follows: - A "magic number" for identifying the file type. A pgm file's magic number is the two characters "P5". - Whitespace (blanks, TABs, CRs, LFs). - A width, formatted as ASCII characters in decimal. - Whitespace. - A height, again in ASCII decimal. - Whitespace. - The maximum gray value (Maxval), again in ASCII decimal. Must be less than 65536. - Newline or other single whitespace character. - A raster of Width * Height gray values, proceeding through the image in normal English reading order. Each gray value is a number from 0 through Maxval, with 0 being black and Maxval being white. Each gray value is represented in pure binary by either 1 or 2 bytes. If the Maxval is less than 256, it is 1 byte. Otherwise, it is 2 bytes. The most significant byte is first. - Characters from a "#" to the next end-of-line, before the maxval line, are comments and are ignored. */ int readPgmImage(const char *name,_image *im) { char string[256]; int x=0, y=0; int max=0; fgetns( string, 255, im ); if ( strncmp(string, PGM_MAGIC, strlen(PGM_MAGIC) ) ) { fprintf( stderr, "readPgmImage: bad magic string in \'%s\'\n", name ); return( -1 ); } do { fgetns( string, 255, im ); if ( string[0] != '#' ) { if ( x == 0 && y == 0 ) { sscanf( string, "%d %d", &x, &y ); } else if ( max == 0 ) { sscanf( string, "%d", &max ); } } } while ( max == 0 ); im->xdim = x; im->ydim = y; im->zdim = 1; im->vdim = 1; im->wordKind = WK_FIXED; im->sign = SGN_UNSIGNED; if ( max < 256 ) im->wdim = 1; else if ( max < 65536 ) { im->wdim = 2; fprintf( stderr, "readPgmImage: Warning, data of \'%s\' may have to be swapped\n", name ); } else { fprintf( stderr, "readPgmImage: max value too large (%d) in \'%s\'\n", max, name ); return( -1 ); } im->data = ImageIO_alloc( x*y ); ImageIO_read( im, im->data, x*y ); return 1; }
int _readAnalyzeHeader( _image* im, const char* name, struct dsr *analyzeHeader ) { unsigned int i ; /* compile time endianness */ ENDIANNESS ARCHITECTURE_ENDIANNESS = _getEndianness(); if(im->openMode != OM_CLOSE) { ImageIO_read( im, analyzeHeader, sizeof(struct dsr) ); if( analyzeHeader->hk.sizeof_hdr == sizeof(struct dsr) ) { im->endianness = ARCHITECTURE_ENDIANNESS ; } else { _swapAnalyzeHdr( analyzeHeader ); if( analyzeHeader->hk.sizeof_hdr != sizeof(struct dsr) ) { fprintf (stderr, "_readAnalyzeHeader: error: unknown magic (%d)...\n", analyzeHeader->hk.sizeof_hdr ); return -1; } if( ARCHITECTURE_ENDIANNESS == END_LITTLE ) { im->endianness = END_BIG; } else { im->endianness = END_LITTLE; } } if ( analyzeHeader->dime.dim[0] > 4 ) { fprintf (stderr, "_readAnalyzeHeader: error: dimensionality not supported (%d)...\n", analyzeHeader->dime.dim[0] ); return -1; } im->xdim = analyzeHeader->dime.dim[1]; im->ydim = analyzeHeader->dime.dim[2]; im->zdim = analyzeHeader->dime.dim[3]; /* 0 time-points is a convention for one volume only at MNI */ /* Corrected by X. Pennec following a bug report by Irina Kezele at MNI */ if( analyzeHeader->dime.dim[4] == 0 ){ fprintf (stderr, "_readAnalyzeHeader: warning: time dimension / number if volume (dim[4]) is 0. Assuming this means 1 (otherwise there would be no image...). \n"); analyzeHeader->dime.dim[4] = 1; } /* Analyze doesn't support vector images. The forth dimension relates to time. */ if( analyzeHeader->dime.dim[4] != 1 ) { fprintf (stderr, "_readAnalyzeHeader: error: time dimension not supported (%d)...\n", analyzeHeader->dime.dim[4] ); return -1; } im->vectMode = VM_SCALAR; im->vx = analyzeHeader->dime.pixdim[1]; im->vy = analyzeHeader->dime.pixdim[2]; im->vz = analyzeHeader->dime.pixdim[3]; if( im->vx == 0.0 ) im->vx = 1.0 ; if( im->vy == 0.0 ) im->vy = im->vx ; if( im->vz == 0.0 ) im->vz = im->vy ; switch(analyzeHeader->dime.datatype) { case DT_BINARY: case DT_UNSIGNED_CHAR: case DT_SIGNED_SHORT: case DT_SIGNED_INT: case DT_FLOAT: case DT_COMPLEX: case DT_DOUBLE: im->vdim = 1; break ; case DT_RGB: im->vdim = 3; break ; default: fprintf (stderr, "_readAnalyzeHeader: error: data type not supported (%d)...\n", analyzeHeader->dime.datatype ); return -1; } switch(analyzeHeader->dime.datatype) { case DT_BINARY: case DT_UNSIGNED_CHAR: case DT_SIGNED_SHORT: case DT_SIGNED_INT: case DT_RGB: im->wordKind = WK_FIXED; break ; case DT_FLOAT: case DT_COMPLEX: case DT_DOUBLE: im->wordKind = WK_FLOAT; break ; default: fprintf (stderr, "_readAnalyzeHeader: error: data type not supported (%d)...\n", analyzeHeader->dime.datatype ); return -1; } switch(analyzeHeader->dime.datatype) { case DT_BINARY: case DT_UNSIGNED_CHAR: case DT_RGB: im->sign = SGN_UNSIGNED; break ; case DT_SIGNED_SHORT: case DT_SIGNED_INT: case DT_FLOAT: case DT_COMPLEX: case DT_DOUBLE: im->sign = SGN_SIGNED; break ; default: fprintf (stderr, "_readAnalyzeHeader: error: data type not supported (%d)...\n", analyzeHeader->dime.datatype ); return -1; } im->wdim = analyzeHeader->dime.bitpix; if( analyzeHeader->dime.datatype == DT_RGB ) { im->wdim /= 3 ; } if(im->wdim != 8 && im->wdim != 16 && im->wdim != 32 && im->wdim != 64) { fprintf (stderr, "_readAnalyzeHeader: error: pixel size not supported (%d)...\n", analyzeHeader->dime.bitpix ); return -1; } im->wdim >>= 3 ; /* There are 17 optional data fields be careful in the allocation */ im->nuser = 1 + 17 ; im->user = (char **) ImageIO_alloc(im->nuser * sizeof(char *)); for ( i=0; i<im->nuser; i++ ) im->user[i] = NULL; i = 0 ; im->user[i] = (char *) ImageIO_alloc((strlen("Data lost in the Analyze -> ImageIO conversion:") + 1)); sprintf( im->user[i++], "Data lost in the Analyze -> ImageIO conversion:" ); im->user[i] = (char *) ImageIO_alloc((strlen(" descrip: ") + 1 + strlen(analyzeHeader->hist.descrip) )); sprintf( im->user[i++], " descrip: %s", analyzeHeader->hist.descrip ); im->user[i] = (char *) ImageIO_alloc((strlen(" aux_file: ") + 1 + strlen(analyzeHeader->hist.descrip) )); sprintf( im->user[i++], " aux_file: %s", analyzeHeader->hist.descrip ); im->user[i] = (char *) ImageIO_alloc((strlen(" orient: ") + 1+ 2)); sprintf( im->user[i++], " orient: %d", analyzeHeader->hist.orient ); im->user[i] = (char *) ImageIO_alloc((strlen(" originator: ") + 1 + strlen(analyzeHeader->hist.originator) )); sprintf( im->user[i++], " originator: %s", analyzeHeader->hist.originator ); im->user[i] = (char *) ImageIO_alloc((strlen(" generated: ") + 1 + strlen(analyzeHeader->hist.generated) )); sprintf( im->user[i++], " generated: %s", analyzeHeader->hist.generated ); im->user[i] = (char *) ImageIO_alloc((strlen(" scannum: ") + 1 + strlen(analyzeHeader->hist.scannum) )); sprintf( im->user[i++], " scannum: %s", analyzeHeader->hist.scannum ); im->user[i] = (char *) ImageIO_alloc((strlen(" patient_id: ") + 1 + strlen(analyzeHeader->hist.patient_id) )); sprintf( im->user[i++], " patient_id: %s", analyzeHeader->hist.patient_id ); im->user[i] = (char *) ImageIO_alloc((strlen(" exp_date: ") + 1 + strlen(analyzeHeader->hist.exp_date) )); sprintf( im->user[i++], " exp_date: %s", analyzeHeader->hist.exp_date ); im->user[i] = (char *) ImageIO_alloc((strlen(" exp_time: ") + 1 + strlen(analyzeHeader->hist.exp_time) )); sprintf( im->user[i++], " exp_time: %s", analyzeHeader->hist.exp_time ); /* A 32 bit int doesn't print on more than 11 chars */ im->user[i] = (char *) ImageIO_alloc((strlen(" views: ") + 11 + 1)); sprintf( im->user[i++], " views: %d", analyzeHeader->hist.views ); im->user[i] = (char *) ImageIO_alloc((strlen(" vols_added: ") + 11 + 1)); sprintf( im->user[i++], " vols_added: %d", analyzeHeader->hist.vols_added ); im->user[i] = (char *) ImageIO_alloc((strlen(" start_field: ") + 11 + 1)); sprintf( im->user[i++], " start_field: %d", analyzeHeader->hist.start_field ); im->user[i] = (char *) ImageIO_alloc((strlen(" field_skip: ") + 11 + 1)); sprintf( im->user[i++], " field_skip: %d", analyzeHeader->hist.field_skip ); im->user[i] = (char *) ImageIO_alloc((strlen(" omax: ") + 11 + 1)); sprintf( im->user[i++], " omax: %d", analyzeHeader->hist.omax ); im->user[i] = (char *) ImageIO_alloc((strlen(" omin: ") + 11 + 1)); sprintf( im->user[i++], " omin: %d", analyzeHeader->hist.omin ); im->user[i] = (char *) ImageIO_alloc((strlen(" smax: ") + 11 + 1)); sprintf( im->user[i++], " smax: %d", analyzeHeader->hist.smax ); im->user[i] = (char *) ImageIO_alloc((strlen(" smin: ") + 11 + 1)); sprintf( im->user[i++], " smin: %d", analyzeHeader->hist.smin ); /* header is read. close header file and open data file. */ if( name != NULL ) { int length = strlen(name) ; char* data_filename = (char *) ImageIO_alloc(length+4) ; if( strcmp( name+length-4, ".hdr" ) ) { fprintf (stderr, "_readAnalyzeHeader: error: file header extension must be .hdr\n"); ImageIO_free( data_filename ); return -1; } ImageIO_close(im); strcpy(data_filename,name); strcpy(data_filename+length-3, "img.gz"); _openReadImage(im,data_filename); if(!im->fd) { strcpy(data_filename,name); strcpy(data_filename+length-3, "img"); _openReadImage(im,data_filename); if(!im->fd) { fprintf(stderr, "_readAnalyzeHeader: error: unable to open data file \'%s\'\n", data_filename); ImageIO_free( data_filename ); return -1; } } ImageIO_free( data_filename ); } /* check header validity */ if(im->xdim > 0 && im->ydim > 0 && im->zdim > 0 && im->vdim > 0 && im->vx > 0.0 && im->vy > 0.0 && im->vz > 0.0 && (im->wordKind == WK_FLOAT || (im->wordKind == WK_FIXED && im->sign != SGN_UNKNOWN)) && im->endianness != END_UNKNOWN) { return 0; } else return -1; }