/* Writes the given image body in an already opened file.*/ int _writeInrimageData(const _image *im) { unsigned long size, nbv, nwrt, i; unsigned int v; unsigned char **vp; if(im->openMode != OM_CLOSE) { /* scalar or interlaced vectors */ if(im->vectMode != VM_NON_INTERLACED) { size = im->xdim * im->ydim * im->zdim * im->vdim * im->wdim; nwrt = ImageIO_write(im, im->data, size); if(nwrt != size) return -1; else return 1; } /* non interlaced vectors: interlace for saving */ else { nbv = im->xdim * im->ydim * im->zdim; size = im->xdim * im->ydim * im->zdim * im->wdim; vp = (unsigned char **) ImageIO_alloc(im->vdim * sizeof(unsigned char *)); for(v = 0; v < im->vdim; v++) vp[v] = (unsigned char *) im->data + v * size; for(i = 0; i < nbv; i++) for(v = 0; v < im->vdim; v++) { if(ImageIO_write(im, (const void *) vp[v], im->wdim) != im->wdim) return -1; vp[v] += im->wdim; } ImageIO_free(vp); return 1; } } else return -1; }
PTRIMAGE_FORMAT createBMPFormat() { PTRIMAGE_FORMAT f=(PTRIMAGE_FORMAT) ImageIO_alloc(sizeof(IMAGE_FORMAT)); f->testImageFormat=&testBmpHeader; f->readImageHeader=&readBmpImage; f->writeImage=0; strcpy(f->fileExtension,".bmp"); strcpy(f->realName,"BMP"); return f; }
PTRIMAGE_FORMAT createPpmFormat() { PTRIMAGE_FORMAT f=(PTRIMAGE_FORMAT) ImageIO_alloc(sizeof(IMAGE_FORMAT)); f->testImageFormat=&testPpmHeader; f->readImageHeader=&readPpmImage; f->writeImage=&writePpmImage; strcpy(f->fileExtension,".ppm,.ppm.gz"); strcpy(f->realName,"Ppm"); return f; }
PTRIMAGE_FORMAT createPgmAscIIFormat() { PTRIMAGE_FORMAT f=(PTRIMAGE_FORMAT) ImageIO_alloc(sizeof(IMAGE_FORMAT)); f->testImageFormat=&testPgmAsciiHeader; f->readImageHeader=&readPgmAsciiImage; f->writeImage=&writePgmImage; strcpy(f->fileExtension,".pgm,.pgm.gz"); strcpy(f->realName,"Pgm-ASCII"); return f; }
PTRIMAGE_FORMAT createAnalyzeFormat() { PTRIMAGE_FORMAT f=(PTRIMAGE_FORMAT) ImageIO_alloc(sizeof(IMAGE_FORMAT)); f->testImageFormat=&testAnalyzeHeader; f->readImageHeader=&readAnalyzeHeader; f->writeImage=&writeAnalyze; strcpy(f->fileExtension,".hdr,.hdr.gz,.img,.img.gz"); strcpy(f->realName,"Analyze"); return f; }
PTRIMAGE_FORMAT createGifFormat() { PTRIMAGE_FORMAT f=(PTRIMAGE_FORMAT) ImageIO_alloc(sizeof(IMAGE_FORMAT)); f->testImageFormat=&testGifHeader; f->readImageHeader=&readGifImage; f->writeImage=0; strcpy(f->fileExtension,".gif"); strcpy(f->realName,"Gif"); return f; }
PTRIMAGE_FORMAT createGisFormat() { PTRIMAGE_FORMAT f=(PTRIMAGE_FORMAT) ImageIO_alloc(sizeof(IMAGE_FORMAT)); f->testImageFormat=&testGisHeader; f->readImageHeader=&readGisHeader; f->writeImage=&writeGis; strcpy(f->fileExtension,".dim,.dim.gz,.ima,.ima.gz"); strcpy(f->realName,"Gis"); return f; }
/* 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 writePgmImage(char *name,_image *im ) { char string[256]; int max; unsigned int i; if ( im->xdim <= 0 || im->ydim <= 0 || im->zdim != 1 || im->vdim != 1 ) { fprintf( stderr, "writePgmImage: bad dimensions, unable to write '%s'\n", name ); return -1; } if ( im->wordKind != WK_FIXED || im->sign != SGN_UNSIGNED || ( im->wdim != 1 && im->wdim != 2 ) ) { fprintf( stderr, "writePgmImage: bad type, unable to write '%s'\n", name ); return -1; } if ( 0 ) im->dataMode = DM_ASCII; _openWriteImage( im, name ); if(!im->fd) { fprintf(stderr, "writePgmImage: error: unable to open file \'%s\'\n", name ); return ImageIO_OPENING; } if ( im->dataMode == DM_ASCII ) sprintf( string, "%s\n", PGM_ASCII_MAGIC ); else sprintf( string, "%s\n", PGM_MAGIC ); ImageIO_write( im, string, strlen( string ) ); sprintf( string, "# CREATOR: pnm.c $Revision$ $Date$\n" ); ImageIO_write( im, string, strlen( string ) ); sprintf( string, "%d %d\n", im->xdim, im->ydim ); ImageIO_write( im, string, strlen( string ) ); max = 0; switch ( im->wdim ) { case 1 : { unsigned char *buf = (unsigned char *)im->data; for ( i=0; i<im->xdim*im->ydim; i++, buf++ ) if ( max < *buf ) max = *buf; } break; case 2 : { unsigned short *buf = (unsigned short *)im->data; for ( i=0; i<im->xdim*im->ydim; i++, buf++ ) if ( max < *buf ) max = *buf; } break; } /* max == 0 causes problems for xv */ if ( max == 0 ) max = 1; sprintf( string, "%d\n", max ); ImageIO_write( im, string, strlen( string ) ); if ( im->dataMode == DM_ASCII ) { int i, j, n, size; char *str = (char*)ImageIO_alloc( _LGTH_STRING_+1 ); size = im->xdim * im->ydim * im->zdim * im->vdim; n = ( im->xdim < 16 ) ? im->xdim : 16; i = 0; switch( im->wdim ) { default : /* can not occur */ fprintf( stderr, "writePgmImage: bad type, unable to write '%s'\n", name ); ImageIO_close( im ); im->openMode = OM_CLOSE; return -1; case 1 : { unsigned char *theBuf = ( unsigned char * )im->data; do { memset( str, 0, _LGTH_STRING_ ); for ( j=0; j<n && i<size; j++, i++ ) { sprintf( str+strlen(str), "%d", theBuf[i] ); if ( j<n && i<size ) sprintf( str+strlen(str), " " ); } sprintf( str+strlen(str), "\n" ); if ( ImageIO_write( im, str, strlen( str ) ) <= 0 ) { fprintf(stderr, "writePgmImage: error when writing data in \'%s\'\n", name ); return( -3 ); } } while ( i < size ); } break; case 2 : { unsigned short int *theBuf = ( unsigned short int * )im->data; do { memset( str, 0, _LGTH_STRING_ ); for ( j=0; j<n && i<size; j++, i++ ) { sprintf( str+strlen(str), "%d", theBuf[i] ); if ( j<n && i<size ) sprintf( str+strlen(str), " " ); } sprintf( str+strlen(str), "\n" ); if ( ImageIO_write( im, str, strlen( str ) ) <= 0 ) { fprintf(stderr, "writePgmImage: error when writing data in \'%s\'\n", name ); return( -3 ); } } while ( i < size ); } break; } } else { if ( im->wdim == 1 || ( im->wdim == 2 && max > 255 ) ) { ImageIO_write( im, im->data, im->xdim*im->ydim*im->wdim ); } else { /* 2 octets, but max <= 255 has to be converted on one octet */ unsigned short *buf = (unsigned short *)im->data; unsigned char *tmp = (unsigned char *)ImageIO_alloc( im->xdim*im->ydim ); if ( tmp == NULL ) { fprintf( stderr, "writePgmImage: unable to allocate auxiliary buffer\n" ); return -1; } for ( i=0; i<im->xdim*im->ydim; i++, buf++ ) tmp[i] = (unsigned char)*buf; ImageIO_write( im, tmp, im->xdim*im->ydim ); ImageIO_free( tmp ); } } ImageIO_close( im ); im->openMode = OM_CLOSE; return 1; }
/* 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 "P2". - 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 readPgmAsciiImage(const char *name,_image *im) { char string[256]; int x=0, y=0; int max=0; int n; char *tmp; int iv; fgetns( string, 255, im ); if ( strncmp(string, PGM_ASCII_MAGIC, strlen(PGM_ASCII_MAGIC) ) ) { fprintf( stderr, "readAsciiPgmImage: 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; } else { fprintf( stderr, "readAsciiPgmImage: max value too large (%d) in \'%s\'\n", max, name ); return( -1 ); } im->data = ImageIO_alloc( x*y ); n=0; while( fgetns( string, 255, im ) != 0 && n < x*y ) { tmp = string; while ( *tmp != '\n' && *tmp != '\0' && *tmp != EOF && n < x*y ) { /* skip trailing whitespace */ while ( *tmp == ' ' || *tmp == '\t' ) tmp++; if ( *tmp == '\0' || *tmp == '\n' || *tmp == EOF ) continue; /* read a number */ switch ( im->wordKind ) { case WK_FIXED : if ( sscanf( tmp, "%d", &iv ) != 1 ) { fprintf( stderr, "readAsciiPgmImage: error in reading ascii data\n" ); ImageIO_free( im->data ); im->data = NULL; return 0; } break; default : ImageIO_free( im->data ); im->data = NULL; return 0; } if ( im->wdim == 1 ) { unsigned char *buf = (unsigned char *)im->data; buf += n; if ( iv < 0 ) *buf = (unsigned char)0; else if ( iv > 255 ) *buf = (unsigned char)255; else *buf = (unsigned char)iv; n ++; } else if ( im->wdim == 2 ) { unsigned short int *buf = (unsigned short int *)im->data; buf += n; if ( iv < 0 ) *buf = (unsigned short int)0; else if ( iv > 65535 ) *buf = (unsigned short int)65535; else *buf = (unsigned short int)iv; n ++; } else { fprintf( stderr, "readAsciiPgmImage: word im not handled\n" ); ImageIO_free( im->data ); im->data = NULL; return 0; } /* skip a number */ while ( (*tmp >= '0' && *tmp <= '9') || *tmp == '.' || *tmp == '-' ) tmp++; } } return 1; }
int writePpmImage( char *name,_image *im ) { char string[256]; int max; unsigned int i; if ( im->xdim <= 0 || im->ydim <= 0 || im->zdim != 1 || im->vdim != 3 ) { fprintf( stderr, "writePpmImage: bad dimensions, unable to write '%s'\n", name ); return -1; } if ( im->wordKind != WK_FIXED || im->sign != SGN_UNSIGNED || ( im->wdim != 1 && im->wdim != 2 ) ) { fprintf( stderr, "writePpmImage: bad type, unable to write '%s'\n", name ); return -1; } _openWriteImage( im, name ); if(!im->fd) { fprintf(stderr, "writeInrimage: error: unable to open file \'%s\'\n", name ); return ImageIO_OPENING; } sprintf( string, "%s\n", PPM_MAGIC ); ImageIO_write( im, string, strlen( string ) ); sprintf( string, "# CREATOR: pnm.c $Revision$ $Date$\n" ); ImageIO_write( im, string, strlen( string ) ); sprintf( string, "%d %d\n", im->xdim, im->ydim ); ImageIO_write( im, string, strlen( string ) ); max = 0; switch ( im->wdim ) { case 1 : { unsigned char *buf = (unsigned char *)im->data; for ( i=0; i<im->xdim*im->ydim*3; i++, buf++ ) if ( max < *buf ) max = *buf; } break; case 2 : { unsigned short *buf = (unsigned short *)im->data; for ( i=0; i<im->xdim*im->ydim*3; i++, buf++ ) if ( max < *buf ) max = *buf; } break; } if ( max == 0 ) max = 1; sprintf( string, "%d\n", max ); ImageIO_write( im, string, strlen( string ) ); if ( im->wdim == 1 || ( im->wdim == 2 && max > 255 ) ) { ImageIO_write( im, im->data, im->xdim*im->ydim*3*im->wdim ); } else { /* 2 octets, but max <= 255 has to be converted on one octet */ unsigned short *buf = (unsigned short *)im->data; unsigned char *tmp = (unsigned char *)ImageIO_alloc( im->xdim*im->ydim*3 ); if ( tmp == NULL ) { fprintf( stderr, "writePpmImage: unable to allocate auxiliary buffer\n" ); return -1; } for ( i=0; i<im->xdim*im->ydim*3; i++, buf++ ) tmp[i] = (unsigned char)*buf; ImageIO_write( im, tmp, im->xdim*im->ydim*3 ); ImageIO_free( tmp ); } ImageIO_close( im ); im->openMode = OM_CLOSE; 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; }
int writeAnalyze( char *name, _image* im) { char *outputName; int length, extLength=0, res; length=strlen(name); outputName= (char *)ImageIO_alloc(length+8); if ( strncmp( name+length-4, ".hdr", 4 ) == 0 ) { extLength = 4; } else if ( strncmp( name+length-4, ".img", 4 ) == 0 ) { extLength = 4; } else if ( strncmp( name+length-7, ".img.gz", 7 ) == 0 ) { extLength = 7; } else if ( strncmp( name+length-7, ".hdr.gz", 7 ) == 0 ) { extLength = 7; } strncpy( outputName, name, length-extLength ); if ( strncmp( name+length-7, ".hdr.gz", 7 ) == 0 ) strcpy( outputName+length-extLength, ".hdr.gz" ); else strcpy( outputName+length-extLength, ".hdr" ); _openWriteImage(im, outputName); if( !im->fd ) { fprintf(stderr, "writeAnalyze: error: unable to open file \'%s\'\n", outputName); if ( outputName != NULL ) ImageIO_free( outputName ); return ImageIO_OPENING; } res = writeAnalyzeHeader(im); if ( res < 0 ) { fprintf(stderr, "writeAnalyze: error: unable to write header of \'%s\'\n", outputName); if ( outputName != NULL ) ImageIO_free( outputName ); ImageIO_close( im ); im->fd = NULL; im->openMode = OM_CLOSE; return( res ); } ImageIO_close(im); strncpy( outputName, name, length-extLength ); if ( strncmp( name+length-3, ".gz", 3 ) == 0 ) { strcpy( outputName+length-extLength, ".img.gz" ); } else { strcpy( outputName+length-extLength, ".img" ); } _openWriteImage(im, outputName); if( !im->fd ) { fprintf(stderr, "writeAnalyze: error: unable to open file \'%s\'\n", outputName); if ( outputName != NULL ) ImageIO_free( outputName ); return ImageIO_OPENING; } res = writeAnalyzeData(im); if (res < 0) { fprintf(stderr, "writeAnalyze: error: unable to write data in \'%s\'\n", outputName ); ImageIO_close( im ); im->fd = NULL; im->openMode = OM_CLOSE; return( res ); } if ( outputName != NULL ) ImageIO_free( outputName ); ImageIO_close( im ); im->fd = NULL; im->openMode = OM_CLOSE; return ( res ); }
/* read header of an opened inrimage */ int readInrimageHeader(const char *,_image *im) { char str[257]; int n, nusr; stringListHead strl = { NULL, NULL }; stringListElement *oel, *el; Set_numeric_locale num_locale("C"); if(im->openMode != OM_CLOSE) { /* read image magic number */ if(!fgetns(str, 257, im )) return -1; if(strcmp(str, INR4_MAGIC)) return -1; /* while read line does not begin with '#' or '\n', read line and decode field */ if(!fgetns(str, 257, im)) return -1; while(str[0] != '#' && str[0] != '\0') { if(!strncmp(str, "XDIM=", 5)) { if(sscanf(str+5, "%u", &im->xdim) != 1) return -1; } else if(!strncmp(str, "YDIM=", 5)) { if(sscanf(str+5, "%u", &im->ydim) != 1) return -1; } else if(!strncmp(str, "ZDIM=", 5)) { if(sscanf(str+5, "%u", &im->zdim) != 1) return -1; } else if(!strncmp(str, "VDIM=", 5)) { if(sscanf(str+5, "%u", &im->vdim) != 1) return -1; if(im->vdim == 1) im->vectMode = VM_SCALAR; else im->vectMode = VM_INTERLACED; } else if(!strncmp(str, "VX=", 3)) { if(sscanf(str+3, "%lf", &im->vx) != 1) return -1; } else if(!strncmp(str, "VY=", 3)) { if(sscanf(str+3, "%lf", &im->vy) != 1) return -1; } else if(!strncmp(str, "VZ=", 3)) { if(sscanf(str+3, "%lf", &im->vz) != 1) return -1; } else if(!strncmp(str, "TYPE=", 5)) { if(!strncmp(str+5, "float", 5)) im->wordKind = WK_FLOAT; else { if(!strncmp(str+5, "signed fixed", 12)) { im->wordKind = WK_FIXED; im->sign = SGN_SIGNED; } else if(!strncmp(str+5, "unsigned fixed", 14)) { im->wordKind = WK_FIXED; im->sign = SGN_UNSIGNED; } else return -1; } } /* before "sscanf(str+8, "%i %n", &im->wdim, &n) != 1" was used. However the man said ... n Nothing is expected; instead, the number of charac ters consumed thus far from the input is stored through the next pointer, which must be a pointer to int. This is not a conversion, although it can be suppressed with the * flag. The C standard says: `Execution of a %n directive does not incre ment the assignment count returned at the comple tion of execution' but the Corrigendum seems to contradict this. Probably it is wise not to make any assumptions on the effect of %n conversions on the return value. ... Thus I change it. It was yielding a RETURN_FAILURE with insight (GM). */ else if(!strncmp(str, "PIXSIZE=", 8)) { if(sscanf(str+8, "%u", &im->wdim) != 1) return -1; if(im->wdim != 8 && im->wdim != 16 && im->wdim != 32 && im->wdim != 64) return -1; if ( im->wdim <= 9 ) { if(strncmp(str+8+1, " bits", 5)) return -1; } else if ( im->wdim <= 99 ) { if(strncmp(str+8+2, " bits", 5)) return -1; } else { return -1; } im->wdim >>= 3; } else if(!strncmp(str, "SCALE=", 6)) ; else if(!strncmp(str, "CPU=", 4)) { if(!strncmp(str+4, "decm", 4)) im->endianness = END_LITTLE; else if(!strncmp(str+4, "alpha", 5)) im->endianness = END_LITTLE; else if(!strncmp(str+4, "pc", 2)) im->endianness = END_LITTLE; else if(!strncmp(str+4, "sun", 3)) im->endianness = END_BIG; else if(!strncmp(str+4, "sgi", 3)) im->endianness = END_BIG; else return -1; } else if(!strncmp(str, "XO=", 3)) { if(sscanf(str+3, "%d", &im->cx) != 1) return -1; } else if(!strncmp(str, "YO=", 3)) { if(sscanf(str+3, "%d", &im->cy) != 1) return -1; } else if(!strncmp(str, "ZO=", 3)) { if(sscanf(str+3, "%d", &im->cz) != 1) return -1; } else if(!strncmp(str, "TX=", 3)) { if(sscanf(str+3, "%f", &im->tx) != 1) return -1; } else if(!strncmp(str, "TY=", 3)) { if(sscanf(str+3, "%f", &im->ty) != 1) return -1; } else if(!strncmp(str, "TZ=", 3)) { if(sscanf(str+3, "%f", &im->tz) != 1) return -1; } else if(!strncmp(str, "RX=", 3)) { if(sscanf(str+3, "%f", &im->rx) != 1) return -1; } else if(!strncmp(str, "RY=", 3)) { if(sscanf(str+3, "%f", &im->ry) != 1) return -1; } else if(!strncmp(str, "RZ=", 3)) { if(sscanf(str+3, "%f", &im->rz) != 1) return -1; } if(!fgetns(str, 257, im)) return -1; } /* parse user strings */ im->nuser = nusr = 0; while(str[0] == '#' && strncmp(str, "##}", 3)) { addStringElement(&strl, str + 1); while(strlen(str) == 256) { if(!fgetns(str, 257, im)) return -1; concatStringElement(&strl, str); } nusr++; if(!fgetns(str, 257, im)) return -1; } /* go to end of header */ while(strncmp(str, "##}", 3)) { if(!fgetns(str, 257, im)) return -1; } /* 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) { if(nusr > 0) { im->nuser = nusr; im->user = (char **) ImageIO_alloc(im->nuser * sizeof(char *)); oel = NULL; for(el = strl.begin, n = 0; el != NULL; el = oel, n++) { im->user[n] = el->string; oel = el->next; ImageIO_free(el); } } return 0; } else return -1; }
int readGifImage(const char *name,_image *im) { register byte ch, ch1; register byte *ptr, *ptr1; register int i, block; int npixels, maxpixels, aspect, filesize; float normaspect; int OutCount = 0, /* Decompressor output 'stack count' */ RWidth, RHeight, /* screen dimensions */ /*LeftOfs, TopOfs, image offset */ BitsPerPixel, /* Bits per pixel, read from GIF header */ ColorMapSize, /* number of colors */ Background, /* background color */ InitCodeSize, /* Starting code size, used during Clear */ Code, /* Value returned by ReadCode */ MaxCode, /* limiting value for current code size */ ClearCode, /* GIF clear code */ EOFCode, /* GIF end-of-information code */ CurCode, OldCode=0, InCode, /* Decompressor variables */ FirstFree, /* First free code, generated per GIF spec */ FreeCode, /* Decompressor,next free slot in hash table */ FinChar=0, /* Decompressor variable */ BitMask, /* AND mask for data size */ Misc; /* miscellaneous bits (interlace, local cmap)*/ int Interlace, HasColormap; /* not used */ /* char header[10]; */ /* The hash table used by the decompressor */ int Prefix[4096]; int Suffix[4096]; /* An output array used by the decompressor */ int OutCode[4097]; /* initialize variables */ BitOffset = XC = YC = Pass = OutCount = npixels = maxpixels = 0; RawGIF = Raster = NULL; gif89 = 0; #ifdef WIN32 fp = fopen(name,"rb"); #else fp = fopen(name,"r"); #endif fp = fopen(name,"rb"); if (!fp) { return(GifError("could not open a GIF file")); } /* find the size of the file */ fseek(fp, 0L, 2); filesize = ftell(fp); fseek(fp, 0L, 0); /* the +256's are so we can read truncated GIF files without fear of segmentation violation */ if (!(ptr = RawGIF = (byte *) ImageIO_alloc(filesize+256))) return( GifError("not enough memory to read gif file") ); if (!(Raster = (byte *) ImageIO_alloc(filesize+256))) return( GifError("not enough memory to read gif file") ); if (fread(ptr, filesize, 1, fp) != 1) return( GifError("GIF data read failed") ); if (strncmp((char *) ptr, id87, 6)==0) gif89 = 0; else if (strncmp((char *) ptr, id89, 6)==0) gif89 = 1; else return( GifError("not a GIF file")); ptr += 6; /* Get variables from the GIF screen descriptor */ ch = NEXTBYTE; RWidth = ch + 0x100 * NEXTBYTE; /* screen dimensions... not used. */ ch = NEXTBYTE; RHeight = ch + 0x100 * NEXTBYTE; use(RWidth); use(RHeight); ch = NEXTBYTE; HasColormap = ((ch & COLORMAPMASK) ? TRUE : FALSE); BitsPerPixel = (ch & 7) + 1; ColorMapSize = 1 << BitsPerPixel; BitMask = ColorMapSize - 1; Background = NEXTBYTE; /* background color... not used. */ use(Background); aspect = NEXTBYTE; if (aspect) { if (!gif89) return(GifError("corrupt GIF file (screen descriptor)")); else normaspect = (float) (aspect + 15) / 64.0f; /* gif89 aspect ratio */ if (DEBUG) fprintf(stderr,"GIF89 aspect = %f\n", normaspect); } /* Read in global colormap. */ if (HasColormap) { r = (byte *) ImageIO_alloc(ColorMapSize * sizeof(byte)); g = (byte *) ImageIO_alloc(ColorMapSize * sizeof(byte)); b = (byte *) ImageIO_alloc(ColorMapSize * sizeof(byte)); for (i = 0; i < ColorMapSize; i++) { r[i] = NEXTBYTE; g[i] = NEXTBYTE; b[i] = NEXTBYTE; } } else { /* no colormap in GIF file */ /* put std EGA palette (repeated 16 times) into colormap, for lack of anything better to do */ ColorMapSize = 256; r = (byte *) ImageIO_alloc(256 * sizeof(byte)); g = (byte *) ImageIO_alloc(256 * sizeof(byte)); b = (byte *) ImageIO_alloc(256 * sizeof(byte)); for (i = 0; i < 256; i++) { r[i] = EGApalette[i&15][0]; g[i] = EGApalette[i&15][1]; b[i] = EGApalette[i&15][2]; } } /* possible things at this point are: * an application extension block * a comment extension block * an (optional) graphic control extension block * followed by either an image * or a plaintext extension */ while (1) { block = NEXTBYTE; if (block == EXTENSION) { /* parse extension blocks */ int i, fn, blocksize, aspnum, aspden; /* read extension block */ fn = NEXTBYTE; if (DEBUG) fprintf(stderr,"GIF extension type 0x%02x\n", fn); if (fn == 'R') { /* GIF87 aspect extension */ blocksize = NEXTBYTE; if (blocksize == 2) { aspnum = NEXTBYTE; aspden = NEXTBYTE; if (aspden>0 && aspnum>0) normaspect = (float) aspnum / (float) aspden; else { normaspect = 1.0; aspnum = aspden = 1; } if (DEBUG) fprintf(stderr,"GIF87 aspect extension: %d:%d = %f\n\n", aspnum, aspden,normaspect); } else { for (i=0; i<blocksize; i++) (void)NEXTBYTE; } } else if (fn == 0xFE) { /* Comment Extension. just eat it */ int ch, j, sbsize; if (DEBUG) fprintf(stderr,"Comment extension: "); /* read (and ignore) data sub-blocks */ do { j = 0; sbsize = NEXTBYTE; while (j<sbsize) { ch = NEXTBYTE; j++; if (DEBUG) fprintf(stderr,"%c", ch); } } while (sbsize); if (DEBUG) fprintf(stderr,"\n\n"); } else if (fn == 0x01) { /* PlainText Extension */ int j,sbsize,ch; int tgLeft, tgTop, tgWidth, tgHeight, cWidth, cHeight, fg, bg; /* SetISTR(ISTR_WARNING, "PlainText extension found in GIF file. Ignored.");*/ sbsize = NEXTBYTE; tgLeft = NEXTBYTE; tgLeft += (NEXTBYTE)<<8; tgTop = NEXTBYTE; tgTop += (NEXTBYTE)<<8; tgWidth = NEXTBYTE; tgWidth += (NEXTBYTE)<<8; tgHeight = NEXTBYTE; tgHeight += (NEXTBYTE)<<8; cWidth = NEXTBYTE; cHeight = NEXTBYTE; fg = NEXTBYTE; bg = NEXTBYTE; i=12; for ( ; i<sbsize; i++) (void)NEXTBYTE; /* read rest of first subblock */ if (DEBUG) fprintf(stderr, "PlainText: tgrid=%d,%d %dx%d cell=%dx%d col=%d,%d\n", tgLeft, tgTop, tgWidth, tgHeight, cWidth, cHeight, fg, bg); /* read (and ignore) data sub-blocks */ do { j = 0; sbsize = NEXTBYTE; while (j<sbsize) { ch = NEXTBYTE; j++; if (DEBUG) fprintf(stderr,"%c", ch); } } while (sbsize); if (DEBUG) fprintf(stderr,"\n\n"); } else if (fn == 0xF9) { /* Graphic Control Extension */ int j, sbsize; if (DEBUG) fprintf(stderr,"Graphic Control extension\n\n"); /* SetISTR(ISTR_WARNING, "Graphic Control Extension in GIF file. Ignored.");*/ /* read (and ignore) data sub-blocks */ do { j = 0; sbsize = NEXTBYTE; while (j<sbsize) { (void)NEXTBYTE; j++; } } while (sbsize); } else { /* unknown extension */ int j, sbsize; if (DEBUG) fprintf(stderr,"unknown GIF extension 0x%02x\n\n", fn); /* SetISTR(ISTR_WARNING, "Unknown extension 0x%02x in GIF file. Ignored.",fn);*/ /* read (and ignore) data sub-blocks */ do { j = 0; sbsize = NEXTBYTE; while (j<sbsize) { (void)NEXTBYTE; j++; } } while (sbsize); } } else if (block == IMAGESEP) break; /* read an image */ else if (block == TRAILER) { return( GifError("no image data found in GIF file") ); } else return (GifError("Unknown block type found in file.")); } /* read in values from the image descriptor */ ch = NEXTBYTE; /* LeftOfs = ch + 0x100 * NEXTBYTE;*/ ch = NEXTBYTE; /* TopOfs = ch + 0x100 * NEXTBYTE; */ ch = NEXTBYTE; ch = NEXTBYTE; ch = NEXTBYTE; Width = ch + 0x100 * NEXTBYTE; ch = NEXTBYTE; Height = ch + 0x100 * NEXTBYTE; Misc = NEXTBYTE; Interlace = ((Misc & INTERLACEMASK) ? TRUE : FALSE); if (Misc & 0x80) { for (i=0; i< 1 << ((Misc&7)+1); i++) { r[i] = NEXTBYTE; g[i] = NEXTBYTE; b[i] = NEXTBYTE; } } if (!HasColormap && !(Misc&0x80)) { /* no global or local colormap */ /* SetISTR(ISTR_WARNING, "No colormap in this GIF file. Assuming EGA colors.");*/ } /* Start reading the raster data. First we get the intial code size * and compute decompressor constant values, based on this code size. */ /* SetISTR(ISTR_FORMAT, "GIF%s, %d bits per pixel, %sinterlaced. (%d bytes)", (gif89) ? "89" : "87", BitsPerPixel, Interlace ? "" : "non-", filesize);*/ CodeSize = NEXTBYTE; ClearCode = (1 << CodeSize); EOFCode = ClearCode + 1; FreeCode = FirstFree = ClearCode + 2; /* The GIF spec has it that the code size is the code size used to * compute the above values is the code size given in the file, but the * code size used in compression/decompression is the code size given in * the file plus one. (thus the ++). */ CodeSize++; InitCodeSize = CodeSize; MaxCode = (1 << CodeSize); ReadMask = MaxCode - 1; /* UNBLOCK: * Read the raster data. Here we just transpose it from the GIF array * to the Raster array, turning it from a series of blocks into one long * data stream, which makes life much easier for ReadCode(). */ ptr1 = Raster; do { ch = ch1 = NEXTBYTE; while (ch--) { *ptr1 = NEXTBYTE; ptr1++; } if ((ptr - RawGIF) > filesize) { /* SetISTR(ISTR_WARNING, "This GIF file seems to be truncated. Winging it.");*/ break; } } while(ch1); ImageIO_free(RawGIF); RawGIF = NULL; if (DEBUG) { fprintf(stderr,"xv: LoadGIF() - picture is %dx%d, %d bits, %sinterlaced\n", Width, Height, BitsPerPixel, Interlace ? "" : "non-"); } /* Allocate the 'pic' */ maxpixels = Width*Height; im->xdim = Width; im->ydim = Height; im->zdim = 1; im->vdim = 3; im->wdim = 1; im->wordKind = WK_FIXED; im->sign = SGN_UNSIGNED; im->data = ImageIO_alloc(Width * Height * 3); org = buf = (unsigned char *) im->data; if (!org) return( GifError("not enough memory for image buffer") ); /* Decompress the file, continuing until you see the GIF EOF code. * One obvious enhancement is to add checking for corrupt files here. */ Code = ReadCode(); while (Code != EOFCode) { /* Clear code sets everything back to its initial value, then reads the * immediately subsequent code as uncompressed data. */ if (Code == ClearCode) { CodeSize = InitCodeSize; MaxCode = (1 << CodeSize); ReadMask = MaxCode - 1; FreeCode = FirstFree; Code = ReadCode(); CurCode = OldCode = Code; FinChar = CurCode & BitMask; if (!Interlace) { *buf++ = r[FinChar]; *buf++ = g[FinChar]; *buf++ = b[FinChar]; } else DoInterlace((byte)FinChar); npixels++; } else { /* If not a clear code, must be data: save same as CurCode and InCode */ /* if we're at maxcode and didn't get a clear, stop loading */ if (FreeCode>=4096) { printf("freecode blew up\n"); break; } CurCode = InCode = Code; /* If greater or equal to FreeCode, not in the hash table yet; * repeat the last character decoded */ if (CurCode >= FreeCode) { CurCode = OldCode; if (OutCount > 4096) { printf("outcount1 blew up\n"); break; } OutCode[OutCount++] = FinChar; } /* Unless this code is raw data, pursue the chain pointed to by CurCode * through the hash table to its end; each code in the chain puts its * associated output code on the output queue. */ while (CurCode > BitMask) { if (OutCount > 4096) { fprintf(stderr,"outcount2 blew up\n"); break;} /* corrupt file */ OutCode[OutCount++] = Suffix[CurCode]; CurCode = Prefix[CurCode]; } if (OutCount > 4096) { printf("outcount blew up\n"); break; } /* The last code in the chain is treated as raw data. */ FinChar = CurCode & BitMask; OutCode[OutCount++] = FinChar; /* Now we put the data out to the Output routine. * It's been stacked LIFO, so deal with it that way... */ /* safety thing: prevent exceeding range of 'pic' */ if (npixels + OutCount > maxpixels) OutCount = maxpixels-npixels; npixels += OutCount; if (!Interlace) for (i=OutCount-1; i>=0; i--) { *buf++ = r[OutCode[i]]; *buf++ = g[OutCode[i]]; *buf++ = b[OutCode[i]]; } else for (i=OutCount-1; i>=0; i--) DoInterlace((byte)OutCode[i]); OutCount = 0; /* Build the hash table on-the-fly. No table is stored in the file. */ Prefix[FreeCode] = OldCode; Suffix[FreeCode] = FinChar; OldCode = InCode; /* Point to the next slot in the table. If we exceed the current * MaxCode value, increment the code size unless it's already 12. If it * is, do nothing: the next code decompressed better be CLEAR */ FreeCode++; if (FreeCode >= MaxCode) { if (CodeSize < 12) { CodeSize++; MaxCode *= 2; ReadMask = (1 << CodeSize) - 1; } } } Code = ReadCode(); if (npixels >= maxpixels) break; } ImageIO_free(Raster); Raster = NULL; if (npixels != maxpixels) { /* SetISTR(ISTR_WARNING,"This GIF file seems to be truncated. Winging it.");*/ if (!Interlace) memset(buf, 0, 3*(maxpixels-npixels)); /* clear to EOBuffer */ } /* SetDirRButt(F_FORMAT, F_GIF); SetDirRButt(F_COLORS, F_FULLCOLOR);*/ return 1; }
int writeGisHeader( const _image* inr ) { const char *proc = "writeGisHeader"; char *str = NULL; if ( inr->vectMode == VM_NON_INTERLACED ) { fprintf( stderr, "%s: can not write non interlaced data\n", proc ); return -1; } str = (char*)ImageIO_alloc( _LGTH_STRING_ ); /* dimensions */ sprintf( str, "%d %d", inr->xdim, inr->ydim ); if ( inr->vdim > 1 ) { sprintf( str+strlen(str), " %d %d", inr->zdim, inr->vdim ); } else if ( inr->zdim > 1 ) { sprintf( str+strlen(str), " %d", inr->zdim ); } sprintf( str+strlen(str), "\n" ); /* type */ sprintf( str+strlen(str), "-type " ); switch ( inr->wordKind ) { case WK_FIXED : switch( inr->sign ) { case SGN_UNSIGNED : sprintf( str+strlen(str), "U" ); sprintf( str+strlen(str), "%d", 8*inr->wdim ); break; case SGN_SIGNED : sprintf( str+strlen(str), "S" ); sprintf( str+strlen(str), "%d", 8*inr->wdim ); break; default : fprintf( stderr, "%s: unknown wordSign\n", proc ); ImageIO_free( str ); return -1; } break; case WK_FLOAT : if ( inr->wdim == sizeof( float ) ) { sprintf( str+strlen(str), "FLOAT" ); } else if ( inr->wdim == sizeof( double ) ) { sprintf( str+strlen(str), "DOUBLE" ); } else { fprintf( stderr, "%s: unknown WK_FLOAT word dim\n", proc ); ImageIO_free( str ); return -1; } break; default : fprintf( stderr, "%s: unknown wordKind for image\n", proc ); ImageIO_free( str ); return -1; } sprintf( str+strlen(str), "\n" ); sprintf( str+strlen(str), "-dx %f\n", inr->vx ); sprintf( str+strlen(str), "-dy %f\n", inr->vy ); if ( inr->zdim > 1 ) sprintf( str+strlen(str), "-dz %f\n", inr->vz ); if ( inr->wdim > 1 ) { sprintf( str+strlen(str), "-bo " ); switch ( _getEndianness() ) { default : case END_LITTLE : sprintf( str+strlen(str), "DCBA" ); break; case END_BIG : sprintf( str+strlen(str), "ABCD" ); break; } sprintf( str+strlen(str), "\n" ); } switch ( inr->dataMode ) { default : case DM_BINARY : sprintf( str+strlen(str), "-om binar\n" ); break; case DM_ASCII : sprintf( str+strlen(str), "-om ascii\n" ); } if( ImageIO_write( inr, str, strlen(str)) == 0) { ImageIO_free( str ); return -1; } ImageIO_free( str ); return 1; }
int writeGis( char *name, _image* im) { char *outputName; int length, extLength=0, res; length=strlen(name); outputName= (char *)ImageIO_alloc(length+8); if ( strncmp( name+length-4, ".dim", 4 ) == 0 ) { extLength = 4; } else if ( strncmp( name+length-4, ".ima", 4 ) == 0 ) { extLength = 4; } else if ( strncmp( name+length-7, ".ima.gz", 7 ) == 0 ) { extLength = 7; } else if ( strncmp( name+length-7, ".dim.gz", 7 ) == 0 ) { extLength = 7; } strncpy( outputName, name, length-extLength ); if ( strncmp( name+length-7, ".dim.gz", 7 ) == 0 ) strcpy( outputName+length-extLength, ".dim.gz" ); else strcpy( outputName+length-extLength, ".dim" ); _openWriteImage(im, outputName); if( !im->fd ) { fprintf(stderr, "writeGis: error: unable to open file \'%s\'\n", outputName); if ( outputName != NULL ) ImageIO_free( outputName ); return ImageIO_OPENING; } res = writeGisHeader(im); if (res < 0 ) { fprintf(stderr, "writeGis: error: unable to write header of \'%s\'\n", outputName); if ( outputName != NULL ) ImageIO_free( outputName ); ImageIO_close( im ); im->fd = NULL; im->openMode = OM_CLOSE; return( res ); } ImageIO_close(im); strncpy( outputName, name, length-extLength ); if ( strncmp( name+length-3, ".gz", 3 ) == 0 ) { strcpy( outputName+length-extLength, ".ima.gz" ); } else { strcpy( outputName+length-extLength, ".ima" ); } _openWriteImage(im, outputName); if( !im->fd ) { fprintf(stderr, "writeGis: error: unable to open file \'%s\'\n", outputName); if ( outputName != NULL ) ImageIO_free( outputName ); return ImageIO_OPENING; } if ( im->dataMode == DM_ASCII ) { int i, j, n, size; char *str = (char*)ImageIO_alloc( _LGTH_STRING_+1 ); size = im->xdim * im->ydim * im->zdim * im->vdim; n = ( im->xdim < 16 ) ? im->xdim : 16; i = 0; switch( im->wordKind ) { default : fprintf(stderr, "writeGis: such word kind not handled in ascii mode for file \'%s\'\n", outputName); if ( outputName != NULL ) ImageIO_free( outputName ); return( -3 ); case WK_FIXED : switch ( im->wdim ) { default : fprintf(stderr, "writeGis: such word dim not handled in ascii mode for file \'%s\'\n", outputName); if ( outputName != NULL ) ImageIO_free( outputName ); return( -3 ); case 1 : switch ( im->sign ) { default : fprintf(stderr, "writeGis: such sign not handled in ascii mode for file \'%s\'\n", outputName); if ( outputName != NULL ) ImageIO_free( outputName ); return( -3 ); case SGN_UNSIGNED : { unsigned char *theBuf = ( unsigned char * )im->data; do { memset( str, 0, _LGTH_STRING_ ); for ( j=0; j<n && i<size; j++, i++ ) { sprintf( str+strlen(str), "%d", theBuf[i] ); if ( j<n && i<size ) sprintf( str+strlen(str), " " ); } sprintf( str+strlen(str), "\n" ); res = ImageIO_write( im, str, strlen( str ) ); if ( res <= 0 ) { fprintf(stderr, "writeGis: error when writing data in \'%s\'\n", outputName); if ( outputName != NULL ) ImageIO_free( outputName ); return( -3 ); } } while ( i < size ); } break; case SGN_SIGNED : { char *theBuf = ( char * )im->data; do { memset( str, 0, _LGTH_STRING_ ); for ( j=0; j<n && i<size; j++, i++ ) { sprintf( str+strlen(str), "%d", theBuf[i] ); if ( j<n && i<size ) sprintf( str+strlen(str), " " ); } sprintf( str+strlen(str), "\n" ); res = ImageIO_write( im, str, strlen( str ) ); if ( res <= 0 ) { fprintf(stderr, "writeGis: error when writing data in \'%s\'\n", outputName); if ( outputName != NULL ) ImageIO_free( outputName ); return( -3 ); } } while ( i < size ); } break; } /* end of switch ( im->sign ) */ break; case 2 : switch ( im->sign ) { default : fprintf(stderr, "writeGis: such sign not handled in ascii mode for file \'%s\'\n", outputName); if ( outputName != NULL ) ImageIO_free( outputName ); return( -3 ); case SGN_UNSIGNED : { unsigned short int *theBuf = ( unsigned short int * )im->data; do { memset( str, 0, _LGTH_STRING_ ); for ( j=0; j<n && i<size; j++, i++ ) { sprintf( str+strlen(str), "%d", theBuf[i] ); if ( j<n && i<size ) sprintf( str+strlen(str), " " ); } sprintf( str+strlen(str), "\n" ); res = ImageIO_write( im, str, strlen( str ) ); if ( res <= 0 ) { fprintf(stderr, "writeGis: error when writing data in \'%s\'\n", outputName); if ( outputName != NULL ) ImageIO_free( outputName ); return( -3 ); } } while ( i < size ); } break; case SGN_SIGNED : { short int *theBuf = ( short int * )im->data; do { memset( str, 0, _LGTH_STRING_ ); for ( j=0; j<n && i<size; j++, i++ ) { sprintf( str+strlen(str), "%d", theBuf[i] ); if ( j<n && i<size ) sprintf( str+strlen(str), " " ); } sprintf( str+strlen(str), "\n" ); res = ImageIO_write( im, str, strlen( str ) ); if ( res <= 0 ) { fprintf(stderr, "writeGis: error when writing data in \'%s\'\n", outputName); if ( outputName != NULL ) ImageIO_free( outputName ); return( -3 ); } } while ( i < size ); } break; } /* end of switch ( im->sign ) */ break; } /* end of switch ( im->wdim ) */ } /* end of switch( im->wordKind ) */ ImageIO_free( str ); } else { res = _writeInrimageData(im); } if ( outputName != NULL ) ImageIO_free( outputName ); return res; }
int readGisHeader( const char* name,_image* im) { char *s, *str = NULL; int status; int n=0, nusermax = 20; str = (char*)ImageIO_alloc( _LGTH_STRING_+1 ); if ( !fgetns(str, _LGTH_STRING_, im) ) { ImageIO_free( str ); return -1; } status = sscanf( str,"%d %d %d %d", &(im->xdim), &(im->ydim), &(im->zdim), &(im->vdim) ); switch ( status ) { case 2 : im->zdim = 1; case 3 : im->vdim = 1; case 4 : break; default : fprintf( stderr, "readGisHeader: unable to read dimensions in '%s'\n", name ); ImageIO_free( str ); return -1; } if ( im->vdim > 1 ) { im->vectMode = VM_INTERLACED; } else { im->vectMode = VM_SCALAR; } #define ADD_USER_STRING { \ if ( n == 0 ) { \ im->user = (char**)ImageIO_alloc( nusermax * sizeof( char*) ); \ for ( n=0; n<nusermax; n++ ) im->user[n] = NULL; \ n = 0; \ } \ im->user[n] = (char*)ImageIO_alloc( 1+strlen( s ) ); \ strcpy( im->user[n++], s ); \ } while( fgetns( str, _LGTH_STRING_, im ) != 0 ) { s = str; do { while ( *s == ' ' || *s == '\t' ) s++; if ( !strncmp( s, "-dx ", 4 ) ) { s += 4; status = sscanf( s, "%lf", &(im->vx) ); if ( status != 1 ) { fprintf( stderr, "readGisHeader: error while reading -dx in '%s'\n", s-4 ); *s = '\0'; } else { while ( *s == '.' || (*s >= '0' && *s <= '9') ) s++; } } else if ( !strncmp( s, "-dy ", 4 ) ) { s += 4; status = sscanf( s, "%lf", &(im->vy) ); if ( status != 1 ) { fprintf( stderr, "readGisHeader: error while reading -dy in '%s'\n", s-4 ); *s = '\0'; } else { while ( *s == '.' || (*s >= '0' && *s <= '9') ) s++; } } else if ( !strncmp( s, "-dz ", 4 ) ) { s += 4; status = sscanf( s, "%lf", &(im->vz) ); if ( status != 1 ) { fprintf( stderr, "readGisHeader: error while reading -dz in '%s'\n", s-4 ); *s = '\0'; } else { while ( *s == '.' || (*s >= '0' && *s <= '9') ) s++; } } else if ( !strncmp( s, "-dt ", 4 ) ) { ADD_USER_STRING s += 4; while ( *s == '.' || (*s >= '0' && *s <= '9') ) s++; } else if ( !strncmp( s, "-type ", 6 ) ) { s += 6; if ( !strncmp( s, "U8", 2 ) ) { im->wdim = 1; im->wordKind = WK_FIXED; im->sign = SGN_UNSIGNED; s += 2; } else if ( !strncmp( s, "S8", 2 ) ) { im->wdim = 1; im->wordKind = WK_FIXED; im->sign = SGN_SIGNED; s += 2; } else if ( !strncmp( s, "U16", 3 ) ) { im->wdim = 2; im->wordKind = WK_FIXED; im->sign = SGN_UNSIGNED; s += 3; } else if ( !strncmp( s, "S16", 3 ) ) { im->wdim = 2; im->wordKind = WK_FIXED; im->sign = SGN_SIGNED; s += 3; } else if ( !strncmp( s, "U32", 3 ) ) { im->wdim = 4; im->wordKind = WK_FIXED; im->sign = SGN_UNSIGNED; s += 3; } else if ( !strncmp( s, "S32", 3 ) ) { im->wdim = 4; im->wordKind = WK_FIXED; im->sign = SGN_SIGNED; s += 3; } else if ( !strncmp( s, "FLOAT", 5 ) ) { im->wdim = sizeof( float ); im->wordKind = WK_FLOAT; im->sign = SGN_UNKNOWN; s += 5; } else if ( !strncmp( s, "DOUBLE", 6 ) ) { im->wdim = sizeof( double ); im->wordKind = WK_FLOAT; im->sign = SGN_UNKNOWN; s += 6; } else { fprintf( stderr, "readGisHeader: unknown type '%s'\n", s-6 ); *s = '\0'; } } else if ( !strncmp( s, "-bo ", 4 ) ) { s += 4; if ( !strncmp( s, "ABCD", 4 ) ) { im->endianness = END_BIG; s += 4; } else if ( !strncmp( s, "SUN", 3 ) ) { im->endianness = END_BIG; s += 3; } else if ( !strncmp( s, "DCBA", 4 ) ) { im->endianness = END_LITTLE; s += 4; } else if ( !strncmp( s, "ALPHA", 5 ) ) { im->endianness = END_LITTLE; s += 5; } else { fprintf( stderr, "readGisHeader: unknown byte order '%s'\n", s-4 ); *s = '\0'; } } else if ( !strncmp( s, "-ar ", 4 ) ) { s += 4; if ( !strncmp( s, "SUN", 3 ) ) { im->endianness = END_BIG; s += 3; } else if ( !strncmp( s, "ALPHA", 5 ) ) { im->endianness = END_LITTLE; s += 5; } else { fprintf( stderr, "readGisHeader: unknown architecture '%s'\n", s-4 ); *s = '\0'; } } else if ( !strncmp( s, "-om ", 4 ) ) { s += 4; if ( !strncmp( s, "binar", 5 ) ) { im->dataMode = DM_BINARY; s += 5; } else if ( !strncmp( s, "ascii", 5 ) ) { im->dataMode = DM_ASCII; s += 5; } else { fprintf( stderr, "readGisHeader: unknown data type '%s'\n", s-4 ); ImageIO_free( str ); return -1; } } else { fprintf( stderr, "readGisHeader: unknown indentifier '%s'\n", s ); ADD_USER_STRING *s = '\0'; } } while( *s != '\0' && *s != '\n' ); } ImageIO_free( str ); if ( im->endianness == END_UNKNOWN ) { im->endianness = _getEndianness(); } /* 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, ".dim" ) ) { fprintf (stderr, "readGisHeader: error: file header extension must be .dim\n"); ImageIO_free( data_filename ); return -1; } ImageIO_close(im); /* open data file */ strcpy(data_filename,name); strcpy(data_filename+length-3, "ima.gz"); _openReadImage(im,data_filename); if(!im->fd) { strcpy(data_filename,name); strcpy(data_filename+length-3, "ima"); _openReadImage(im,data_filename); if(!im->fd) { fprintf(stderr, "readGisHeader: error: unable to open data file \'%s\'\n", data_filename); ImageIO_free( data_filename ); return -1; } } ImageIO_free( data_filename ); /* read data if ascii only U8 and S8 */ if ( im->dataMode == DM_ASCII ) { int size = im->xdim * im->ydim * im->zdim * im->vdim * im->wdim; unsigned int n; char *tmp; int ret, iv=0; if ( im->wdim != 1 || im->wordKind != WK_FIXED ) { fprintf(stderr, "readGisHeader: error: unable to read such ascii type\n" ); return -1; } n = 0 ; if ( size <= 0 ) return -1; if(!im->data) { im->data = ( void*) ImageIO_alloc(size); if(!im->data) return -1; } n = 0; str = (char*)ImageIO_alloc( _LGTH_STRING_+1 ); while( fgetns( str, _LGTH_STRING_, im ) != 0 && n < im->xdim * im->ydim * im->zdim * im->vdim ) { tmp = str; while ( *tmp != '\n' && *tmp != '\0' && *tmp != EOF && n < im->xdim * im->ydim * im->zdim * im->vdim ) { /* skip trailing whitespace */ while ( *tmp == ' ' || *tmp == '\t' ) tmp++; if ( *tmp == '\0' || *tmp == '\n' || *tmp == EOF ) continue; /* read a number */ switch ( im->wordKind ) { case WK_FIXED : ret = sscanf( tmp, "%d", &iv ); break; default : ImageIO_free( im->data ); im->data = NULL; ImageIO_free( str ); return -1; } if ( ret != 1 ) { fprintf( stderr, "readGisHeader: error in reading ascii data\n" ); ImageIO_free( im->data ); im->data = NULL; ImageIO_free( str ); return -1; } if ( im->wordKind == WK_FIXED && im->sign == SGN_UNSIGNED && im->wdim == 1 ) { unsigned char *buf = (unsigned char *)im->data; buf += n; if ( iv < 0 ) *buf = (unsigned char)0; else if ( iv > 255 ) *buf = (unsigned char)255; else *buf = (unsigned char)iv; n ++; } else if ( im->wordKind == WK_FIXED && im->sign == SGN_SIGNED && im->wdim == 1 ) { char *buf = (char *)im->data; buf += n; if ( iv < -128 ) *buf = (char)-128; else if ( iv > 127 ) *buf = (char)127; else *buf = (char)iv; n ++; } else if ( im->wordKind == WK_FIXED && im->sign == SGN_UNSIGNED && im->wdim == 2 ) { unsigned short int *buf = (unsigned short int *)im->data; buf += n; if ( iv < 0 ) *buf = (unsigned short int)0; else if ( iv > 65535 ) *buf = (unsigned short int)65535; else *buf = (unsigned short int)iv; n ++; } else if ( im->wordKind == WK_FIXED && im->sign == SGN_SIGNED && im->wdim == 2 ) { short int *buf = (short int *)im->data; buf += n; if ( iv < -32768 ) *buf = (short int)-32768; else if ( iv > 32767 ) *buf = (short int)32767; else *buf = (short int)iv; n ++; } else { ImageIO_free( im->data ); im->data = NULL; ImageIO_free( str ); return -1; } /* skip a number */ while ( (*tmp >= '0' && *tmp <= '9') || *tmp == '.' || *tmp == '-' ) tmp++; } } ImageIO_free( str ); ImageIO_close(im); } } /* 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; } return -1; }