revise buffered input
rad load works now
This commit is contained in:
parent
de94a725aa
commit
edca486f19
@ -17,7 +17,7 @@
|
|||||||
- nifti load/save uses double for all floating point metadata
|
- nifti load/save uses double for all floating point metadata
|
||||||
- add vips_error_buffer_copy()
|
- add vips_error_buffer_copy()
|
||||||
- add VipsStream: a universal IO class for loaders and savers
|
- add VipsStream: a universal IO class for loaders and savers
|
||||||
- jpeg, png, tiff and webp use the new IO class
|
- jpeg, png, tiff (though not tiffsave), rad and webp use the new IO class
|
||||||
- add @no_strip option to dzsave [kalozka1]
|
- add @no_strip option to dzsave [kalozka1]
|
||||||
|
|
||||||
31/8/19 started 8.8.3
|
31/8/19 started 8.8.3
|
||||||
|
@ -27,6 +27,8 @@
|
|||||||
* 23/7/18
|
* 23/7/18
|
||||||
* - fix a buffer overflow for incorrectly coded old-style RLE
|
* - fix a buffer overflow for incorrectly coded old-style RLE
|
||||||
* [HongxuChen]
|
* [HongxuChen]
|
||||||
|
* 6/11/19
|
||||||
|
* - revise for VipsStream
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -608,8 +610,6 @@ scanline_read( VipsStreamib *streamib, COLR *scanline, int width )
|
|||||||
run = code > 128;
|
run = code > 128;
|
||||||
len = run ? code & 127 : code;
|
len = run ? code & 127 : code;
|
||||||
|
|
||||||
printf( "len = %d\n", len );
|
|
||||||
|
|
||||||
if( j + len > width ) {
|
if( j + len > width ) {
|
||||||
vips_error( "rad2vips", "%s", _( "overrun" ) );
|
vips_error( "rad2vips", "%s", _( "overrun" ) );
|
||||||
return( -1 );
|
return( -1 );
|
||||||
@ -953,6 +953,9 @@ vips__rad_load( VipsStreami *streami, VipsImage *out )
|
|||||||
vips_image_write( t[1], out ) )
|
vips_image_write( t[1], out ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
|
if( vips_streami_decode( streami ) )
|
||||||
|
return( -1 );
|
||||||
|
|
||||||
return( 0 );
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -251,10 +251,13 @@ typedef struct _VipsStreamib {
|
|||||||
/* The +1 means there's always a \0 byte at the end.
|
/* The +1 means there's always a \0 byte at the end.
|
||||||
*
|
*
|
||||||
* Unsigned char, since we don't want >127 to be -ve.
|
* Unsigned char, since we don't want >127 to be -ve.
|
||||||
|
*
|
||||||
|
* chars_in_buffer is how many chars we have in input_buffer,
|
||||||
|
* read_point is the current read position in that buffer.
|
||||||
*/
|
*/
|
||||||
unsigned char input_buffer[VIPS_STREAMIB_BUFFER_SIZE + 1];
|
unsigned char input_buffer[VIPS_STREAMIB_BUFFER_SIZE + 1];
|
||||||
unsigned char *read_point;
|
int chars_in_buffer;
|
||||||
int chars_unread;
|
int read_point;
|
||||||
|
|
||||||
/* Build lines of text here.
|
/* Build lines of text here.
|
||||||
*/
|
*/
|
||||||
@ -275,20 +278,20 @@ void vips_streamib_unbuffer( VipsStreamib *streamib );
|
|||||||
|
|
||||||
int vips_streamib_getc( VipsStreamib *streamib );
|
int vips_streamib_getc( VipsStreamib *streamib );
|
||||||
#define VIPS_STREAMIB_GETC( S ) ( \
|
#define VIPS_STREAMIB_GETC( S ) ( \
|
||||||
(S)->chars_unread > 0 ? \
|
(S)->read_point < (S)->chars_in_buffer ? \
|
||||||
((S)->chars_unread--, ((S)->read_point++)[0]) : \
|
(S)->input_buffer[(S)->read_point++] : \
|
||||||
vips_streamib_getc( S ) \
|
vips_streamib_getc( S ) \
|
||||||
)
|
)
|
||||||
void vips_streamib_ungetc( VipsStreamib *streamib );
|
void vips_streamib_ungetc( VipsStreamib *streamib );
|
||||||
|
|
||||||
int vips_streamib_require( VipsStreamib *streamib, int require );
|
int vips_streamib_require( VipsStreamib *streamib, int require );
|
||||||
#define VIPS_STREAMIB_REQUIRE( S, R ) ( \
|
#define VIPS_STREAMIB_REQUIRE( S, R ) ( \
|
||||||
(R) > (S)->chars_unread ? \
|
(S)->read_point + (R) <= (S)->chars_in_buffer ? \
|
||||||
0 : \
|
0 : \
|
||||||
vips_streamib_require( (S), (R) ) \
|
vips_streamib_require( (S), (R) ) \
|
||||||
)
|
)
|
||||||
#define VIPS_STREAMIB_PEEK( S ) ((S)->read_point)
|
#define VIPS_STREAMIB_PEEK( S ) ((S)->input_buffer + (S)->read_point)
|
||||||
#define VIPS_STREAMIB_FETCH( S ) ((S)->chars_unread--, ((S)->read_point++)[0])
|
#define VIPS_STREAMIB_FETCH( S ) ((S)->input_buffer[(S)->read_point++])
|
||||||
|
|
||||||
const unsigned char *vips_streamib_get_line( VipsStreamib *streamib );
|
const unsigned char *vips_streamib_get_line( VipsStreamib *streamib );
|
||||||
unsigned char *vips_streamib_get_line_copy( VipsStreamib *streamib );
|
unsigned char *vips_streamib_get_line_copy( VipsStreamib *streamib );
|
||||||
|
@ -90,9 +90,9 @@ vips_streamib_class_init( VipsStreamibClass *class )
|
|||||||
static void
|
static void
|
||||||
vips_streamib_init( VipsStreamib *streamib )
|
vips_streamib_init( VipsStreamib *streamib )
|
||||||
{
|
{
|
||||||
streamib->read_point = streamib->input_buffer;
|
streamib->read_point = 0;
|
||||||
streamib->chars_unread = 0;
|
streamib->chars_in_buffer = 0;
|
||||||
streamib->read_point[streamib->chars_unread] = '\0';
|
streamib->input_buffer[0] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -130,12 +130,12 @@ vips_streamib_new( VipsStreami *streami )
|
|||||||
void
|
void
|
||||||
vips_streamib_unbuffer( VipsStreamib *streamib )
|
vips_streamib_unbuffer( VipsStreamib *streamib )
|
||||||
{
|
{
|
||||||
int bytes_in_buffer = streamib->read_point - streamib->input_buffer;
|
/* We'd read ahead a little way -- seek backwards by that amount.
|
||||||
|
*/
|
||||||
streamib->read_point = streamib->input_buffer;
|
|
||||||
streamib->chars_unread = 0;
|
|
||||||
vips_streami_seek( streamib->streami,
|
vips_streami_seek( streamib->streami,
|
||||||
-bytes_in_buffer, SEEK_SET );
|
streamib->read_point - streamib->chars_in_buffer, SEEK_SET );
|
||||||
|
streamib->read_point = 0;
|
||||||
|
streamib->chars_in_buffer = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Returns -1 on error, 0 on EOF, otherwise bytes read.
|
/* Returns -1 on error, 0 on EOF, otherwise bytes read.
|
||||||
@ -147,20 +147,20 @@ vips_streamib_refill( VipsStreamib *streamib )
|
|||||||
|
|
||||||
/* We should not discard any unread bytes.
|
/* We should not discard any unread bytes.
|
||||||
*/
|
*/
|
||||||
g_assert( streamib->chars_unread == 0 );
|
g_assert( streamib->read_point == streamib->chars_in_buffer );
|
||||||
|
|
||||||
bytes_read = vips_streami_read( streamib->streami,
|
bytes_read = vips_streami_read( streamib->streami,
|
||||||
streamib->input_buffer, VIPS_STREAMIB_BUFFER_SIZE );
|
streamib->input_buffer, VIPS_STREAMIB_BUFFER_SIZE );
|
||||||
if( bytes_read == -1 )
|
if( bytes_read == -1 )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
streamib->read_point = streamib->input_buffer;
|
streamib->read_point = 0;
|
||||||
streamib->chars_unread = bytes_read;
|
streamib->chars_in_buffer = bytes_read;
|
||||||
|
|
||||||
/* Always add a null byte so we can use strchr() etc. on lines. This is
|
/* Always add a null byte so we can use strchr() etc. on lines. This is
|
||||||
* safe because input_buffer is VIPS_STREAMIB_BUFFER_SIZE + 1 bytes.
|
* safe because input_buffer is VIPS_STREAMIB_BUFFER_SIZE + 1 bytes.
|
||||||
*/
|
*/
|
||||||
streamib->read_point[bytes_read] = '\0';
|
streamib->input_buffer[bytes_read] = '\0';
|
||||||
|
|
||||||
return( bytes_read );
|
return( bytes_read );
|
||||||
}
|
}
|
||||||
@ -178,18 +178,13 @@ vips_streamib_refill( VipsStreamib *streamib )
|
|||||||
int
|
int
|
||||||
vips_streamib_getc( VipsStreamib *streamib )
|
vips_streamib_getc( VipsStreamib *streamib )
|
||||||
{
|
{
|
||||||
int ch;
|
if( streamib->read_point == streamib->chars_in_buffer &&
|
||||||
|
|
||||||
if( streamib->chars_unread == 0 &&
|
|
||||||
vips_streamib_refill( streamib ) <= 0 )
|
vips_streamib_refill( streamib ) <= 0 )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
ch = streamib->read_point[0];
|
g_assert( streamib->read_point < streamib->chars_in_buffer );
|
||||||
|
|
||||||
streamib->read_point += 1;
|
return( streamib->input_buffer[streamib->read_point++] );
|
||||||
streamib->chars_unread -= 1;
|
|
||||||
|
|
||||||
return( ch );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -213,10 +208,8 @@ vips_streamib_getc( VipsStreamib *streamib )
|
|||||||
void
|
void
|
||||||
vips_streamib_ungetc( VipsStreamib *streamib )
|
vips_streamib_ungetc( VipsStreamib *streamib )
|
||||||
{
|
{
|
||||||
if( streamib->read_point > streamib->input_buffer ) {
|
if( streamib->read_point > 0 )
|
||||||
streamib->read_point -= 1;
|
streamib->read_point -= 1;
|
||||||
streamib->chars_unread += 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -232,31 +225,31 @@ int
|
|||||||
vips_streamib_require( VipsStreamib *streamib, int require )
|
vips_streamib_require( VipsStreamib *streamib, int require )
|
||||||
{
|
{
|
||||||
g_assert( require < VIPS_STREAMIB_BUFFER_SIZE );
|
g_assert( require < VIPS_STREAMIB_BUFFER_SIZE );
|
||||||
g_assert( streamib->chars_unread >= 0 );
|
g_assert( streamib->chars_in_buffer >= 0 );
|
||||||
g_assert( streamib->chars_unread <= VIPS_STREAMIB_BUFFER_SIZE );
|
g_assert( streamib->chars_in_buffer <= VIPS_STREAMIB_BUFFER_SIZE );
|
||||||
g_assert( streamib->read_point >= streamib->input_buffer );
|
g_assert( streamib->read_point >= 0 );
|
||||||
g_assert( streamib->read_point <
|
g_assert( streamib->read_point <= streamib->chars_in_buffer );
|
||||||
streamib->input_buffer + VIPS_STREAMIB_BUFFER_SIZE );
|
|
||||||
|
|
||||||
if( require > streamib->chars_unread ) {
|
if( streamib->read_point + require > streamib->chars_in_buffer ) {
|
||||||
/* Areas can overlap.
|
/* Areas can overlap, so we must memmove().
|
||||||
*/
|
*/
|
||||||
memmove( streamib->input_buffer,
|
memmove( streamib->input_buffer,
|
||||||
streamib->read_point, streamib->chars_unread );
|
streamib->input_buffer + streamib->read_point,
|
||||||
streamib->read_point = streamib->input_buffer;
|
streamib->chars_in_buffer - streamib->read_point );
|
||||||
|
streamib->chars_in_buffer -= streamib->read_point;
|
||||||
|
streamib->read_point = 0;
|
||||||
|
|
||||||
while( require > streamib->chars_unread ) {
|
while( require > streamib->chars_in_buffer ) {
|
||||||
unsigned char *q = streamib->input_buffer +
|
unsigned char *to = streamib->input_buffer +
|
||||||
streamib->chars_unread;
|
streamib->chars_in_buffer;
|
||||||
int space_available =
|
int space_available =
|
||||||
VIPS_STREAMIB_BUFFER_SIZE -
|
VIPS_STREAMIB_BUFFER_SIZE -
|
||||||
streamib->chars_unread;
|
streamib->chars_in_buffer;
|
||||||
size_t bytes_read;
|
size_t bytes_read;
|
||||||
|
|
||||||
if( (bytes_read = vips_streami_read( streamib->streami,
|
if( (bytes_read = vips_streami_read( streamib->streami,
|
||||||
q, space_available )) == -1 )
|
to, space_available )) == -1 )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
streamib->chars_unread += bytes_read;
|
|
||||||
if( bytes_read == 0 ) {
|
if( bytes_read == 0 ) {
|
||||||
vips_error(
|
vips_error(
|
||||||
vips_stream_nick( VIPS_STREAM(
|
vips_stream_nick( VIPS_STREAM(
|
||||||
@ -264,6 +257,9 @@ vips_streamib_require( VipsStreamib *streamib, int require )
|
|||||||
"%s", _( "end of file" ) );
|
"%s", _( "end of file" ) );
|
||||||
return( -1 );
|
return( -1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
to[bytes_read] = '\0';
|
||||||
|
streamib->chars_in_buffer += bytes_read;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -323,26 +319,26 @@ vips_streamib_require( VipsStreamib *streamib, int require )
|
|||||||
const unsigned char *
|
const unsigned char *
|
||||||
vips_streamib_get_line( VipsStreamib *streamib )
|
vips_streamib_get_line( VipsStreamib *streamib )
|
||||||
{
|
{
|
||||||
unsigned char *write_point;
|
int write_point;
|
||||||
int space_remaining;
|
int space_remaining;
|
||||||
int ch;
|
int ch;
|
||||||
|
|
||||||
write_point = streamib->line;
|
write_point = 0;
|
||||||
space_remaining = VIPS_STREAMIB_BUFFER_SIZE;
|
space_remaining = VIPS_STREAMIB_BUFFER_SIZE;
|
||||||
|
|
||||||
while( (ch = VIPS_STREAMIB_GETC( streamib )) != -1 &&
|
while( (ch = VIPS_STREAMIB_GETC( streamib )) != -1 &&
|
||||||
ch != '\n' &&
|
ch != '\n' &&
|
||||||
space_remaining > 0 ) {
|
space_remaining > 0 ) {
|
||||||
write_point[0] = ch;
|
streamib->line[write_point] = ch;
|
||||||
write_point += 1;
|
write_point += 1;
|
||||||
space_remaining -= 1;
|
space_remaining -= 1;
|
||||||
}
|
}
|
||||||
write_point[0] = '\0';
|
streamib->line[write_point] = '\0';
|
||||||
|
|
||||||
/* If we hit EOF immediately, return EOF.
|
/* If we hit EOF immediately, return EOF.
|
||||||
*/
|
*/
|
||||||
if( ch == -1 &&
|
if( ch == -1 &&
|
||||||
write_point == streamib->line )
|
write_point == 0 )
|
||||||
return( NULL );
|
return( NULL );
|
||||||
|
|
||||||
/* If the final char in the buffer is \r, this is probably a DOS file
|
/* If the final char in the buffer is \r, this is probably a DOS file
|
||||||
@ -351,9 +347,9 @@ vips_streamib_get_line( VipsStreamib *streamib )
|
|||||||
* There's a chance this could incorrectly remove \r in very long
|
* There's a chance this could incorrectly remove \r in very long
|
||||||
* lines, but ignore this.
|
* lines, but ignore this.
|
||||||
*/
|
*/
|
||||||
if( write_point - streamib->line > 0 &&
|
if( write_point > 0 &&
|
||||||
write_point[-1] == '\r' )
|
streamib->line[write_point - 1] == '\r' )
|
||||||
write_point[-1] = '\0';
|
streamib->line[write_point - 1] = '\0';
|
||||||
|
|
||||||
/* If we filled the output line without seeing \n, keep going to the
|
/* If we filled the output line without seeing \n, keep going to the
|
||||||
* next \n.
|
* next \n.
|
||||||
@ -400,6 +396,8 @@ vips_streamib_get_line_copy( VipsStreamib *streamib )
|
|||||||
g_byte_array_append( buffer, &c, 1 );
|
g_byte_array_append( buffer, &c, 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Immediate EOF.
|
||||||
|
*/
|
||||||
if( ch == -1 &&
|
if( ch == -1 &&
|
||||||
buffer->len == 0 ) {
|
buffer->len == 0 ) {
|
||||||
VIPS_FREEF( g_byte_array_unref, buffer );
|
VIPS_FREEF( g_byte_array_unref, buffer );
|
||||||
|
Loading…
Reference in New Issue
Block a user