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 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; }
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; }
/* Writes the given inrimage header in an already opened file.*/ int _writeInrimageHeader(const _image *im, ENDIANNESS end) { unsigned int pos, i; char type[30], endianness[5], buf[257], scale[20]; Set_numeric_locale num_locale("C"); if(im->openMode != OM_CLOSE) { /* fix word kind */ switch(im->wordKind) { case WK_FLOAT: sprintf(type, "float"); scale[0] = '\0'; break; case WK_FIXED: switch(im->sign) { case SGN_SIGNED: sprintf(type, "signed fixed"); break; case SGN_UNSIGNED: sprintf(type, "unsigned fixed"); break; default: return -1; } sprintf(scale, "SCALE=2**0\n"); break; default: return -1; } switch(end) { case END_LITTLE: sprintf(endianness, "decm"); break; case END_BIG: sprintf(endianness, "sun"); break; default: /* fix architecture endianness */ if( _getEndianness() == END_LITTLE) sprintf(endianness, "decm"); else sprintf(endianness, "sun"); break; } /* write header information */ sprintf(buf, "%s\nXDIM=%i\nYDIM=%i\nZDIM=%i\nVDIM=%d\nTYPE=%s\nPIXSIZE=%i bits\n%sCPU=%s\nVX=%f\nVY=%f\nVZ=%f\n", INR4_MAGIC, im->xdim, im->ydim, im->zdim, im->vdim, type, im->wdim*8, scale, endianness, im->vx, im->vy, im->vz); if ( im->cx != 0 ) sprintf(buf+strlen(buf), "XO=%d\n", im->cx ); if ( im->cy != 0 ) sprintf(buf+strlen(buf), "YO=%d\n", im->cy ); if ( im->cz != 0 ) sprintf(buf+strlen(buf), "ZO=%d\n", im->cz ); if ( im->tx != 0.0 ) sprintf(buf+strlen(buf), "TX=%f\n", im->tx ); if ( im->ty != 0.0 ) sprintf(buf+strlen(buf), "TY=%f\n", im->ty ); if ( im->tz != 0.0 ) sprintf(buf+strlen(buf), "TZ=%f\n", im->tz ); if ( im->rx != 0.0 ) sprintf(buf+strlen(buf), "RX=%f\n", im->rx ); if ( im->ry != 0.0 ) sprintf(buf+strlen(buf), "RY=%f\n", im->ry ); if ( im->rz != 0.0 ) sprintf(buf+strlen(buf), "RZ=%f\n", im->rz ); pos = strlen(buf); if(ImageIO_write(im, buf, strlen(buf)) == 0) return -1; /* write user strings */ if ( im->user != NULL ) { for(i = 0; i < im->nuser; i++) { if ( im->user[i] == NULL ) continue; pos += strlen(im->user[i]) + 2; if(ImageIO_write(im, "#", 1) == 0) return -1; if(ImageIO_write(im, im->user[i], strlen(im->user[i])) == 0) return -1; if(ImageIO_write(im, "\n", 1) == 0) return -1; } } /* write end of header */ pos = pos % 256; if(pos > 252) { for(i = pos; i < 256; i++) if(ImageIO_write(im, "\n", 1) != 1) return -1; pos = 0; } buf[0] = '\0'; for(i = pos; i < 252; i++) strcat(buf, "\n"); strcat(buf, "##}\n"); if(ImageIO_write(im, buf, strlen(buf)) == 0) return -1; else return 1; } else return -1; }