fix pyr tiff write to buffer

now we have a test for it heh
This commit is contained in:
John Cupitt 2017-08-27 11:03:34 +01:00
parent 7cf7a6335e
commit c0bfa4e70b
3 changed files with 145 additions and 116 deletions

View File

@ -314,24 +314,11 @@ openout_buffer_read( thandle_t st, tdata_t data, tsize_t size )
{ {
VipsTiffOpenoutBuffer *buffer = (VipsTiffOpenoutBuffer *) st; VipsTiffOpenoutBuffer *buffer = (VipsTiffOpenoutBuffer *) st;
off_t write_point; #ifdef DEBUG
size_t available; printf( "openout_buffer_read: %zd bytes\n", size );
unsigned char *from; #endif /*DEBUG*/
write_point = vips_dbuf_tell( &buffer->dbuf ); return( vips_dbuf_read( &buffer->dbuf, data, size ) );
from = vips_dbuf_get_write( &buffer->dbuf, &available );
vips_dbuf_seek( &buffer->dbuf, write_point, SEEK_SET );
if( available < size ) {
vips_error( "openout_buffer_read",
"%s", _( "read beyond end of buffer" ) );
return( 0 );
}
memcpy( data, from, size );
vips_dbuf_seek( &buffer->dbuf, size, SEEK_CUR );
return( size );
} }
static tsize_t static tsize_t
@ -365,8 +352,26 @@ openout_buffer_seek( thandle_t st, toff_t position, int whence )
VipsTiffOpenoutBuffer *buffer = (VipsTiffOpenoutBuffer *) st; VipsTiffOpenoutBuffer *buffer = (VipsTiffOpenoutBuffer *) st;
#ifdef DEBUG #ifdef DEBUG
printf( "openout_buffer_seek: position %zd, whence %d\n", printf( "openout_buffer_seek: position %zd, whence %d ",
position, whence ); position, whence );
switch( whence ) {
case SEEK_SET:
printf( "set" );
break;
case SEEK_END:
printf( "end" );
break;
case SEEK_CUR:
printf( "cur" );
break;
default:
printf( "unknown" );
break;
}
printf( "\n" );
#endif /*DEBUG*/ #endif /*DEBUG*/
vips_dbuf_seek( &buffer->dbuf, position, whence ); vips_dbuf_seek( &buffer->dbuf, position, whence );

View File

@ -64,6 +64,7 @@ typedef struct _VipsDbuf {
void vips_dbuf_destroy( VipsDbuf *buf ); void vips_dbuf_destroy( VipsDbuf *buf );
void vips_dbuf_init( VipsDbuf *buf ); void vips_dbuf_init( VipsDbuf *buf );
gboolean vips_dbuf_allocate( VipsDbuf *dbuf, size_t size ); gboolean vips_dbuf_allocate( VipsDbuf *dbuf, size_t size );
size_t vips_dbuf_read( VipsDbuf *dbuf, unsigned char *data, size_t size );
unsigned char *vips_dbuf_get_write( VipsDbuf *dbuf, size_t *size ); unsigned char *vips_dbuf_get_write( VipsDbuf *dbuf, size_t *size );
gboolean vips_dbuf_write( VipsDbuf *dbuf, gboolean vips_dbuf_write( VipsDbuf *dbuf,
const unsigned char *data, size_t size ); const unsigned char *data, size_t size );

View File

@ -69,7 +69,7 @@ gboolean
vips_dbuf_minimum_size( VipsDbuf *dbuf, size_t size ) vips_dbuf_minimum_size( VipsDbuf *dbuf, size_t size )
{ {
if( size > dbuf->allocated_size ) { if( size > dbuf->allocated_size ) {
size_t new_allocated_size = 3 * (16 + size) / 2; const size_t new_allocated_size = 3 * (16 + size) / 2;
unsigned char *new_data; unsigned char *new_data;
@ -102,25 +102,26 @@ vips_dbuf_allocate( VipsDbuf *dbuf, size_t size )
} }
/** /**
* vips_dbuf_null_terminate: * vips_dbuf_read:
* @dbuf: the buffer * @dbuf: the buffer
* @data: read to this area
* @size: read up to this many bytes
* *
* Make sure the byte after the last data byte is `\0`. This extra byte is not * Up to @size bytes are read from the buffer and copied to @data. The number
* included in the data size and the write point is not moved. * of bytes transferred is returned.
* *
* This makes it safe to treat the dbuf contents as a C string. * Returns: the number of bytes transferred.
*
* Returns: %FALSE on out of memory, %TRUE otherwise.
*/ */
static gboolean size_t
vips_dbuf_null_terminate( VipsDbuf *dbuf ) vips_dbuf_read( VipsDbuf *dbuf, unsigned char *data, size_t size )
{ {
if( !vips_dbuf_minimum_size( dbuf, dbuf->data_size + 1 ) ) const size_t available = dbuf->data_size - dbuf->write_point;
return( FALSE ); const size_t copied = VIPS_MIN( size, available );
dbuf->data[dbuf->data_size] = 0; memcpy( data, dbuf->data + dbuf->write_point, copied );
dbuf->write_point += copied;
return( TRUE ); return( copied );
} }
/** /**
@ -141,14 +142,14 @@ unsigned char *
vips_dbuf_get_write( VipsDbuf *dbuf, size_t *size ) vips_dbuf_get_write( VipsDbuf *dbuf, size_t *size )
{ {
unsigned char *write = dbuf->data + dbuf->write_point; unsigned char *write = dbuf->data + dbuf->write_point;
size_t length = dbuf->data + dbuf->allocated_size - write; const size_t available = dbuf->allocated_size - dbuf->write_point;
memset( write, 0, length ); memset( write, 0, available );
dbuf->write_point = dbuf->allocated_size; dbuf->write_point = dbuf->allocated_size;
dbuf->data_size = dbuf->allocated_size; dbuf->data_size = dbuf->allocated_size;
if( size ) if( size )
*size = length; *size = available;
return( write ); return( write );
} }
@ -310,6 +311,28 @@ vips_dbuf_tell( VipsDbuf *dbuf )
return( dbuf->write_point ); return( dbuf->write_point );
} }
/**
* vips_dbuf_null_terminate:
* @dbuf: the buffer
*
* Make sure the byte after the last data byte is `\0`. This extra byte is not
* included in the data size and the write point is not moved.
*
* This makes it safe to treat the dbuf contents as a C string.
*
* Returns: %FALSE on out of memory, %TRUE otherwise.
*/
static gboolean
vips_dbuf_null_terminate( VipsDbuf *dbuf )
{
if( !vips_dbuf_minimum_size( dbuf, dbuf->data_size + 1 ) )
return( FALSE );
dbuf->data[dbuf->data_size] = 0;
return( TRUE );
}
/** /**
* vips_dbuf_steal: * vips_dbuf_steal:
* @dbuf: the buffer * @dbuf: the buffer