/* 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 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; }
/* 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; }
/* 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; }