fix up streamib a bit more
radiance load is almost working
This commit is contained in:
parent
6d3b53174d
commit
de94a725aa
@ -475,9 +475,6 @@ char *buf;
|
||||
static const char FMTSTR[] = "FORMAT="; /* format identifier */
|
||||
|
||||
|
||||
static gethfunc mycheck;
|
||||
|
||||
|
||||
static int
|
||||
formatval( /* get format value (return true if format) */
|
||||
char fmt[MAXFMTLEN],
|
||||
@ -507,16 +504,12 @@ getheader( /* get header from file */
|
||||
)
|
||||
{
|
||||
for(;;) {
|
||||
const char *line;
|
||||
const unsigned char *line;
|
||||
|
||||
if( vips_streamib_get_line( streamib, &line ) )
|
||||
if( !(line = vips_streamib_get_line( streamib )) )
|
||||
return( -1 );
|
||||
if( !line )
|
||||
/* EOF.
|
||||
*/
|
||||
return( -1 );
|
||||
if( strcmp( line, "" ) == 0 )
|
||||
/* Blank line.
|
||||
if( strcmp( (char *) line, "" ) == 0 )
|
||||
/* Blank line. We've parsed the header successfully.
|
||||
*/
|
||||
break;
|
||||
|
||||
@ -528,117 +521,6 @@ getheader( /* get header from file */
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
struct check {
|
||||
char fs[MAXFMTLEN];
|
||||
};
|
||||
|
||||
|
||||
static int
|
||||
mycheck( /* check a header line for format info. */
|
||||
char *s,
|
||||
void *cp
|
||||
)
|
||||
{
|
||||
struct check *p = (struct check *) cp;
|
||||
|
||||
if (!formatval(p->fs, s) && p->fp != NULL) {
|
||||
fputs(s, p->fp);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
globmatch( /* check for match of s against pattern p */
|
||||
const char *p,
|
||||
const char *s
|
||||
)
|
||||
{
|
||||
int setmatch;
|
||||
|
||||
do {
|
||||
switch (*p) {
|
||||
case '?': /* match any character */
|
||||
if (!*s++)
|
||||
return(0);
|
||||
break;
|
||||
case '*': /* match any string */
|
||||
while (p[1] == '*') p++;
|
||||
do
|
||||
if ( (p[1]=='?') | (p[1]==*s) &&
|
||||
globmatch(p+1,s) )
|
||||
return(1);
|
||||
while (*s++);
|
||||
return(0);
|
||||
case '[': /* character set */
|
||||
setmatch = *s == *++p;
|
||||
if (!*p)
|
||||
return(0);
|
||||
while (*++p != ']') {
|
||||
if (!*p)
|
||||
return(0);
|
||||
if (*p == '-') {
|
||||
setmatch += (p[-1] <= *s && *s <= p[1]);
|
||||
if (!*++p)
|
||||
break;
|
||||
} else
|
||||
setmatch += (*p == *s);
|
||||
}
|
||||
if (!setmatch)
|
||||
return(0);
|
||||
s++;
|
||||
break;
|
||||
case '\\': /* literal next */
|
||||
p++;
|
||||
/* fall through */
|
||||
default: /* normal character */
|
||||
if (*p != *s)
|
||||
return(0);
|
||||
s++;
|
||||
break;
|
||||
}
|
||||
} while (*p++);
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Checkheader(fin,fmt,fout) returns a value of 1 if the input format
|
||||
* matches the specification in fmt, 0 if no input format was found,
|
||||
* and -1 if the input format does not match or there is an
|
||||
* error reading the header. If fmt is empty, then -1 is returned
|
||||
* if any input format is found (or there is an error), and 0 otherwise.
|
||||
* If fmt contains any '*' or '?' characters, then checkheader
|
||||
* does wildcard expansion and copies a matching result into fmt.
|
||||
* Be sure that fmt is big enough to hold the match in such cases,
|
||||
* and that it is not a static, read-only string!
|
||||
*/
|
||||
|
||||
static int
|
||||
checkheader(
|
||||
VipsStreamib *streamib,
|
||||
char fmt[MAXFMTLEN]
|
||||
)
|
||||
{
|
||||
struct check cdat;
|
||||
char *cp;
|
||||
|
||||
cdat.fs[0] = '\0';
|
||||
if (getheader(streamib, mycheck, &cdat) < 0)
|
||||
return(-1);
|
||||
if (!cdat.fs[0])
|
||||
return(0);
|
||||
for (cp = fmt; *cp; cp++) /* check for globbing */
|
||||
if ((*cp == '?') | (*cp == '*')) {
|
||||
if (globmatch(fmt, cdat.fs)) {
|
||||
strcpy(fmt, cdat.fs);
|
||||
return(1);
|
||||
} else
|
||||
return(-1);
|
||||
}
|
||||
return(strcmp(fmt, cdat.fs) ? -1 : 1); /* literal match */
|
||||
}
|
||||
|
||||
/* Read a single scanline, encoded in the old style.
|
||||
*/
|
||||
static int
|
||||
@ -726,6 +608,8 @@ scanline_read( VipsStreamib *streamib, COLR *scanline, int width )
|
||||
run = code > 128;
|
||||
len = run ? code & 127 : code;
|
||||
|
||||
printf( "len = %d\n", len );
|
||||
|
||||
if( j + len > width ) {
|
||||
vips_error( "rad2vips", "%s", _( "overrun" ) );
|
||||
return( -1 );
|
||||
@ -841,15 +725,17 @@ int
|
||||
vips__rad_israd( VipsStreami *streami )
|
||||
{
|
||||
VipsStreamib *streamib;
|
||||
char format[256];
|
||||
const unsigned char *line;
|
||||
int result;
|
||||
|
||||
strcpy( format, PICFMT );
|
||||
/* Just test that the first line is the magic string.
|
||||
*/
|
||||
streamib = vips_streamib_new( streami );
|
||||
result = checkheader( streamib, format );
|
||||
result = (line = vips_streamib_get_line( streamib )) &&
|
||||
strcmp( (char *) line, "#?RADIANCE" ) == 0;
|
||||
VIPS_UNREF( streamib );
|
||||
|
||||
return( result == 1 );
|
||||
return( result );
|
||||
}
|
||||
|
||||
static void
|
||||
@ -934,14 +820,14 @@ static int
|
||||
rad2vips_get_header( Read *read, VipsImage *out )
|
||||
{
|
||||
VipsInterpretation interpretation;
|
||||
const char *line;
|
||||
const unsigned char *line;
|
||||
int width;
|
||||
int height;
|
||||
int i, j;
|
||||
|
||||
if( getheader( read->streamib,
|
||||
(gethfunc *) rad2vips_process_line, read ) ||
|
||||
vips_streamib_get_line( read->streamib, &line ) ||
|
||||
!(line = vips_streamib_get_line( read->streamib )) ||
|
||||
!str2resolu( &read->rs, line ) ) {
|
||||
vips_error( "rad2vips", "%s",
|
||||
_( "error reading radiance header" ) );
|
||||
|
@ -249,14 +249,16 @@ typedef struct _VipsStreamib {
|
||||
VipsStreami *streami;
|
||||
|
||||
/* The +1 means there's always a \0 byte at the end.
|
||||
*
|
||||
* Unsigned char, since we don't want >127 to be -ve.
|
||||
*/
|
||||
char input_buffer[VIPS_STREAMIB_BUFFER_SIZE + 1];
|
||||
char *read_point;
|
||||
unsigned char input_buffer[VIPS_STREAMIB_BUFFER_SIZE + 1];
|
||||
unsigned char *read_point;
|
||||
int chars_unread;
|
||||
|
||||
/* Build lines of text here.
|
||||
*/
|
||||
char line[VIPS_STREAMIB_BUFFER_SIZE + 1];
|
||||
unsigned char line[VIPS_STREAMIB_BUFFER_SIZE + 1];
|
||||
|
||||
} VipsStreamib;
|
||||
|
||||
@ -285,11 +287,11 @@ int vips_streamib_require( VipsStreamib *streamib, int require );
|
||||
0 : \
|
||||
vips_streamib_require( (S), (R) ) \
|
||||
)
|
||||
#define VIPS_STREAMIB_PEEK( S ) (( S )->read_point)
|
||||
#define VIPS_STREAMIB_PEEK( S ) ((S)->read_point)
|
||||
#define VIPS_STREAMIB_FETCH( S ) ((S)->chars_unread--, ((S)->read_point++)[0])
|
||||
|
||||
int vips_streamib_get_line( VipsStreamib *streamib, const char **line );
|
||||
int vips_streamib_get_line_copy( VipsStreamib *streamib, char **line );
|
||||
const unsigned char *vips_streamib_get_line( VipsStreamib *streamib );
|
||||
unsigned char *vips_streamib_get_line_copy( VipsStreamib *streamib );
|
||||
|
||||
#define VIPS_TYPE_STREAMO (vips_streamo_get_type())
|
||||
#define VIPS_STREAMO( obj ) \
|
||||
|
@ -246,7 +246,7 @@ vips_streamib_require( VipsStreamib *streamib, int require )
|
||||
streamib->read_point = streamib->input_buffer;
|
||||
|
||||
while( require > streamib->chars_unread ) {
|
||||
char *q = streamib->input_buffer +
|
||||
unsigned char *q = streamib->input_buffer +
|
||||
streamib->chars_unread;
|
||||
int space_available =
|
||||
VIPS_STREAMIB_BUFFER_SIZE -
|
||||
@ -304,27 +304,26 @@ vips_streamib_require( VipsStreamib *streamib, int require )
|
||||
/**
|
||||
* vips_streamib_get_line:
|
||||
* @streamib: stream to operate on
|
||||
* @line: return the next line of text here
|
||||
*
|
||||
* Fetch the next line of text from @streamib and return in @line. The end of
|
||||
* line character (or characters, for DOS files) are removed, and @line
|
||||
* Fetch the next line of text from @streamib and return it. The end of
|
||||
* line character (or characters, for DOS files) are removed, and the string
|
||||
* is terminated with a null (`\0` character).
|
||||
*
|
||||
* @line is set to NULL on end of file.
|
||||
* Returns NULL on end of file or read error.
|
||||
*
|
||||
* If the line is longer than some arbitrary (but large) limit, is is
|
||||
* truncated. If you need to be able to read very long lines, use the
|
||||
* slower vips_streamib_get_line_copy().
|
||||
*
|
||||
* The return value of @line is owned by @streamib and must not be freed. It
|
||||
* The return value is owned by @streamib and must not be freed. It
|
||||
* is valid until the next call to vips_streamib_get_line().
|
||||
*
|
||||
* Returns: 0 on success, -1 on error.
|
||||
* Returns: the next line from the file, or NULL on EOF or read error.
|
||||
*/
|
||||
int
|
||||
vips_streamib_get_line( VipsStreamib *streamib, const char **line )
|
||||
const unsigned char *
|
||||
vips_streamib_get_line( VipsStreamib *streamib )
|
||||
{
|
||||
char *write_point;
|
||||
unsigned char *write_point;
|
||||
int space_remaining;
|
||||
int ch;
|
||||
|
||||
@ -342,10 +341,19 @@ vips_streamib_get_line( VipsStreamib *streamib, const char **line )
|
||||
|
||||
/* If we hit EOF immediately, return EOF.
|
||||
*/
|
||||
if( write_point == streamib->line ) {
|
||||
*line = NULL;
|
||||
return( 0 );
|
||||
}
|
||||
if( ch == -1 &&
|
||||
write_point == streamib->line )
|
||||
return( NULL );
|
||||
|
||||
/* If the final char in the buffer is \r, this is probably a DOS file
|
||||
* and we should remove that too.
|
||||
*
|
||||
* There's a chance this could incorrectly remove \r in very long
|
||||
* lines, but ignore this.
|
||||
*/
|
||||
if( write_point - streamib->line > 0 &&
|
||||
write_point[-1] == '\r' )
|
||||
write_point[-1] = '\0';
|
||||
|
||||
/* If we filled the output line without seeing \n, keep going to the
|
||||
* next \n.
|
||||
@ -357,16 +365,7 @@ vips_streamib_get_line( VipsStreamib *streamib, const char **line )
|
||||
;
|
||||
}
|
||||
|
||||
/* If we stopped on \n, try to skip any \r too.
|
||||
*/
|
||||
if( ch == '\n' ) {
|
||||
if( VIPS_STREAMIB_GETC( streamib ) != '\r' )
|
||||
vips_streamib_ungetc( streamib );
|
||||
}
|
||||
|
||||
*line = streamib->line;
|
||||
|
||||
return( 0 );
|
||||
return( streamib->line );
|
||||
}
|
||||
|
||||
/**
|
||||
@ -382,13 +381,13 @@ vips_streamib_get_line( VipsStreamib *streamib, const char **line )
|
||||
* This is slower than vips_streamib_get_line(), but can work with lines of
|
||||
* any length.
|
||||
*
|
||||
* Returns: the next line from the file, or NULL on EOF.
|
||||
*
|
||||
* Returns: the next line from the file, or NULL on EOF or read error.
|
||||
*/
|
||||
int
|
||||
vips_streamib_get_line_copy( VipsStreamib *streamib, char **line )
|
||||
unsigned char *
|
||||
vips_streamib_get_line_copy( VipsStreamib *streamib )
|
||||
{
|
||||
const unsigned char null = '\0';
|
||||
static const unsigned char null = '\0';
|
||||
|
||||
GByteArray *buffer;
|
||||
int ch;
|
||||
|
||||
@ -401,21 +400,21 @@ vips_streamib_get_line_copy( VipsStreamib *streamib, char **line )
|
||||
g_byte_array_append( buffer, &c, 1 );
|
||||
}
|
||||
|
||||
if( ch == -1 ) {
|
||||
if( ch == -1 &&
|
||||
buffer->len == 0 ) {
|
||||
VIPS_FREEF( g_byte_array_unref, buffer );
|
||||
return( -1 );
|
||||
return( NULL );
|
||||
}
|
||||
|
||||
/* If the character before the \n was \r, this is probably a DOS file
|
||||
* and we should remove the \r.
|
||||
*/
|
||||
if( ch == '\n' &&
|
||||
buffer->len > 0 &&
|
||||
buffer->data[buffer->len - 1] == '\r' )
|
||||
g_byte_array_set_size( buffer, buffer->len - 1 );
|
||||
|
||||
g_byte_array_append( buffer, &null, 1 );
|
||||
|
||||
/* If we stopped on \n, try to skip any \r too.
|
||||
*/
|
||||
if( ch == '\n' ) {
|
||||
if( VIPS_STREAMIB_GETC( streamib ) != '\r' )
|
||||
vips_streamib_ungetc( streamib );
|
||||
}
|
||||
|
||||
*line = (char *) g_byte_array_free( buffer, FALSE );
|
||||
|
||||
return( 0 );
|
||||
return( (unsigned char *) g_byte_array_free( buffer, FALSE ) );
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user