tiff uses vipdbuf

This commit is contained in:
John Cupitt 2017-02-28 16:44:12 +00:00
parent f2a178e98f
commit 8f47c75a85
7 changed files with 85 additions and 105 deletions

5
TODO
View File

@ -1,5 +1,10 @@
- verify xml data against master for vips save and dzsave
- curious
$ vips tiffload_buffer images/sample.tif
(vips:18224): GLib-GObject-WARNING **: unable to set property 'buffer' of type 'VipsBlob' from value of type 'gchararray'
Trace/breakpoint trap (core dumped)

View File

@ -1349,24 +1349,24 @@ vips2rad_put_header_buf( Write *write )
{
vips2rad_make_header( write );
vips_dbuf_appendf( &write->dbuf, "#?RADIANCE\n" );
vips_dbuf_appendf( &write->dbuf, "%s%s\n", FMTSTR, write->format );
vips_dbuf_appendf( &write->dbuf, "%s%e\n", EXPOSSTR, write->expos );
vips_dbuf_appendf( &write->dbuf, "%s %f %f %f\n",
vips_dbuf_writef( &write->dbuf, "#?RADIANCE\n" );
vips_dbuf_writef( &write->dbuf, "%s%s\n", FMTSTR, write->format );
vips_dbuf_writef( &write->dbuf, "%s%e\n", EXPOSSTR, write->expos );
vips_dbuf_writef( &write->dbuf, "%s %f %f %f\n",
COLCORSTR,
write->colcor[RED], write->colcor[GRN], write->colcor[BLU] );
vips_dbuf_appendf( &write->dbuf, "SOFTWARE=vips %s\n",
vips_dbuf_writef( &write->dbuf, "SOFTWARE=vips %s\n",
vips_version_string() );
vips_dbuf_appendf( &write->dbuf, "%s%f\n", ASPECTSTR, write->aspect );
vips_dbuf_appendf( &write->dbuf,
vips_dbuf_writef( &write->dbuf, "%s%f\n", ASPECTSTR, write->aspect );
vips_dbuf_writef( &write->dbuf,
"%s %.4f %.4f %.4f %.4f %.4f %.4f %.4f %.4f\n",
PRIMARYSTR,
write->prims[RED][CIEX], write->prims[RED][CIEY],
write->prims[GRN][CIEX], write->prims[GRN][CIEY],
write->prims[BLU][CIEX], write->prims[BLU][CIEY],
write->prims[WHT][CIEX], write->prims[WHT][CIEY] );
vips_dbuf_appendf( &write->dbuf, "\n" );
vips_dbuf_appendf( &write->dbuf, "%s",
vips_dbuf_writef( &write->dbuf, "\n" );
vips_dbuf_writef( &write->dbuf, "%s",
resolu2str( resolu_buf, &write->rs ) );
return( 0 );

View File

@ -298,10 +298,7 @@ vips__tiff_openin_buffer( VipsImage *image, const void *data, size_t length )
*/
typedef struct _VipsTiffOpenoutBuffer {
size_t position;
void *data;
size_t allocated;
size_t length;
VipsDbuf dbuf;
/* On close, consolidate and write the output here.
*/
@ -321,37 +318,12 @@ static tsize_t
openout_buffer_write( thandle_t st, tdata_t data, tsize_t size )
{
VipsTiffOpenoutBuffer *buffer = (VipsTiffOpenoutBuffer *) st;
size_t new_length = VIPS_MAX( buffer->position + size, buffer->length );
#ifdef DEBUG
printf( "openout_buffer_write: %zd bytes\n", size );
#endif /*DEBUG*/
/* We could make a chain of blocks, but libtiff does a lot of seeking
* during writes, so we'd have to handle writes being
* split over blocks, which would be annoying.
*
* Instead, go for exponential realloc: the number of reallocs grows as
* log(final size), and we never over allocate by more than 30%.
*
* realloc can be very, very slow on Windows, but maybe g_realloc() is
* smarter.
*/
if( new_length > buffer->allocated ) {
buffer->allocated = VIPS_MAX( (16 + buffer->allocated) * 3 / 2,
new_length );
buffer->data = g_try_realloc( buffer->data, buffer->allocated );
if( buffer->data == NULL ) {
vips_error( "tiff memory write",
"%s", _( "Out of memory." ) );
return( 0 );
}
}
memcpy( buffer->data + buffer->position, data, size );
buffer->position += size;
buffer->length = new_length;
vips_dbuf_write( &buffer->dbuf, data, size );
return( size );
}
@ -361,8 +333,8 @@ openout_buffer_close( thandle_t st )
{
VipsTiffOpenoutBuffer *buffer = (VipsTiffOpenoutBuffer *) st;
*(buffer->out_data) = buffer->data;
*(buffer->out_length) = buffer->length;
*(buffer->out_data) = vips_dbuf_steal( &buffer->dbuf,
buffer->out_length);
return( 0 );
}
@ -377,16 +349,9 @@ openout_buffer_seek( thandle_t st, toff_t position, int whence )
position, whence );
#endif /*DEBUG*/
if( whence == SEEK_SET )
buffer->position = position;
else if( whence == SEEK_CUR )
buffer->position += position;
else if( whence == SEEK_END )
buffer->position = buffer->length + position;
else
g_assert_not_reached();
vips_dbuf_seek( &buffer->dbuf, position, whence );
return( buffer->position );
return( vips_dbuf_tell( &buffer->dbuf ) );
}
static toff_t
@ -429,10 +394,7 @@ vips__tiff_openout_buffer( VipsImage *image,
#endif /*DEBUG*/
buffer = VIPS_NEW( image, VipsTiffOpenoutBuffer );
buffer->position = 0;
buffer->data = NULL;
buffer->allocated = 0;
buffer->length = 0;
vips_dbuf_init( &buffer->dbuf );
buffer->out_data = out_data;
buffer->out_length = out_length;

View File

@ -1016,7 +1016,7 @@ user_write_data( png_structp png_ptr, png_bytep data, png_size_t length )
{
Write *write = (Write *) png_get_io_ptr( png_ptr );
vips_dbuf_append( &write->dbuf, data, length );
vips_dbuf_write( &write->dbuf, data, length );
}
int

View File

@ -37,8 +37,7 @@ extern "C" {
#include <vips/vips.h>
/* A buffer in the process of being written to ... multiple calls to
* vips_dbuf_append add to it.
/* A buffer in the process of being written to.
*/
typedef struct _VipsDbuf {
@ -66,13 +65,14 @@ void vips_dbuf_destroy( VipsDbuf *buf );
void vips_dbuf_init( VipsDbuf *buf );
gboolean vips_dbuf_allocate( VipsDbuf *dbuf, size_t size );
unsigned char *vips_dbuf_get_write( VipsDbuf *dbuf, size_t *size );
gboolean vips_dbuf_append( VipsDbuf *dbuf,
gboolean vips_dbuf_write( VipsDbuf *dbuf,
const unsigned char *data, size_t size );
gboolean vips_dbuf_appendf( VipsDbuf *dbuf, const char *fmt, ... );
gboolean vips_dbuf_writef( VipsDbuf *dbuf, const char *fmt, ... );
void vips_dbuf_reset( VipsDbuf *dbuf );
void vips_dbuf_destroy( VipsDbuf *dbuf );
gboolean vips_dbuf_seek( VipsDbuf *dbuf, off_t offset, int whence );
void vips_dbuf_truncate( VipsDbuf *dbuf );
off_t vips_dbuf_tell( VipsDbuf *dbuf );
unsigned char *vips_dbuf_string( VipsDbuf *dbuf, size_t *size );
unsigned char *vips_dbuf_steal( VipsDbuf *dbuf, size_t *size );

View File

@ -154,17 +154,17 @@ vips_dbuf_get_write( VipsDbuf *dbuf, size_t *size )
}
/**
* vips_dbuf_append:
* vips_dbuf_write:
* @dbuf: the buffer
* @data: the data to append to the buffer
* @size: the size of the len to append
* @data: the data to write to the buffer
* @size: the size of the len to write
*
* Append @size bytes from @data. @dbuf expands if necessary.
*
* Returns: %FALSE on out of memory, %TRUE otherwise.
*/
gboolean
vips_dbuf_append( VipsDbuf *dbuf, const unsigned char *data, size_t size )
vips_dbuf_write( VipsDbuf *dbuf, const unsigned char *data, size_t size )
{
if( !vips_dbuf_allocate( dbuf, size ) )
return( FALSE );
@ -177,17 +177,17 @@ vips_dbuf_append( VipsDbuf *dbuf, const unsigned char *data, size_t size )
}
/**
* vips_dbuf_appendf:
* vips_dbuf_writef:
* @dbuf: the buffer
* @fmt: <function>printf()</function>-style format string
* @...: arguments to format string
*
* Format the string and append to @dbuf.
* Format the string and write to @dbuf.
*
* Returns: %FALSE on out of memory, %TRUE otherwise.
*/
gboolean
vips_dbuf_appendf( VipsDbuf *dbuf, const char *fmt, ... )
vips_dbuf_writef( VipsDbuf *dbuf, const char *fmt, ... )
{
va_list ap;
char *line;
@ -196,7 +196,7 @@ vips_dbuf_appendf( VipsDbuf *dbuf, const char *fmt, ... )
line = g_strdup_vprintf( fmt, ap );
va_end( ap );
if( vips_dbuf_append( dbuf, (unsigned char *) line, strlen( line ) ) ) {
if( vips_dbuf_write( dbuf, (unsigned char *) line, strlen( line ) ) ) {
g_free( line );
return( FALSE );
}
@ -278,7 +278,8 @@ vips_dbuf_seek( VipsDbuf *dbuf, off_t offset, int whence )
return( FALSE );
dbuf->write_point = new_write_point;
if( dbuf->data_size < dbuf->write_point ) {
memset( dbuf->data, 0, dbuf->write_point - dbuf->data_size );
memset( dbuf->data + dbuf->data_size, 0,
dbuf->write_point - dbuf->data_size );
dbuf->data_size = dbuf->write_point;
}
@ -297,6 +298,18 @@ vips_dbuf_truncate( VipsDbuf *dbuf )
dbuf->data_size = dbuf->write_point;
}
/**
* vips_dbuf_truncate:
* @dbuf: the buffer
*
* Truncate the data so that it ends at the write point. No memory is freed.
*/
off_t
vips_dbuf_tell( VipsDbuf *dbuf )
{
return( dbuf->write_point );
}
/**
* vips_dbuf_steal:
* @dbuf: the buffer

View File

@ -648,7 +648,7 @@ parser_data_handler( void *user_data, const XML_Char *data, int len )
printf( "parser_data_handler: %d bytes\n", len );
#endif /*DEBUG*/
vips_dbuf_append( &vep->dbuf, (unsigned char *) data, len );
vips_dbuf_write( &vep->dbuf, (unsigned char *) data, len );
}
/* Called at the end of vips open ... get any XML after the pixel data
@ -718,7 +718,7 @@ vips__write_extension_block( VipsImage *im, void *buf, int size )
/* Append a string to a buffer, but escape " as \".
*/
static void
dbuf_append_quotes( VipsDbuf *dbuf, const char *str )
dbuf_write_quotes( VipsDbuf *dbuf, const char *str )
{
const char *p;
size_t len;
@ -726,16 +726,16 @@ dbuf_append_quotes( VipsDbuf *dbuf, const char *str )
for( p = str; *p; p += len ) {
len = strcspn( p, "\"" );
vips_dbuf_append( dbuf, (unsigned char *) p, len );
vips_dbuf_write( dbuf, (unsigned char *) p, len );
if( p[len] == '"' )
vips_dbuf_appendf( dbuf, "\\" );
vips_dbuf_writef( dbuf, "\\" );
}
}
/* Append a string to a buffer, but escape &<>.
*/
static void
dbuf_append_amp( VipsDbuf *dbuf, const char *str )
dbuf_write_amp( VipsDbuf *dbuf, const char *str )
{
const char *p;
size_t len;
@ -743,20 +743,20 @@ dbuf_append_amp( VipsDbuf *dbuf, const char *str )
for( p = str; *p; p += len ) {
len = strcspn( p, "&<>" );
vips_dbuf_append( dbuf, (unsigned char *) p, len );
vips_dbuf_write( dbuf, (unsigned char *) p, len );
switch( p[len] ) {
case '&':
vips_dbuf_appendf( dbuf, "&amp;" );
vips_dbuf_writef( dbuf, "&amp;" );
len += 1;
break;
case '<':
vips_dbuf_appendf( dbuf, "&lt;" );
vips_dbuf_writef( dbuf, "&lt;" );
len += 1;
break;
case '>':
vips_dbuf_appendf( dbuf, "&gt;" );
vips_dbuf_writef( dbuf, "&gt;" );
len += 1;
break;
@ -788,12 +788,12 @@ build_xml_meta( VipsMeta *meta, VipsDbuf *dbuf )
}
str = vips_value_get_save_string( &save_value );
vips_dbuf_appendf( dbuf, " <field type=\"%s\" name=\"",
vips_dbuf_writef( dbuf, " <field type=\"%s\" name=\"",
g_type_name( type ) );
dbuf_append_quotes( dbuf, meta->name );
vips_dbuf_appendf( dbuf, "\">" );
dbuf_append_amp( dbuf, str );
vips_dbuf_appendf( dbuf, "</field>\n" );
dbuf_write_quotes( dbuf, meta->name );
vips_dbuf_writef( dbuf, "\">" );
dbuf_write_amp( dbuf, str );
vips_dbuf_writef( dbuf, "</field>\n" );
g_value_unset( &save_value );
}
@ -811,20 +811,20 @@ build_xml( VipsImage *image )
vips_dbuf_init( &dbuf );
vips_dbuf_appendf( &dbuf, "<?xml version=\"1.0\"?>\n" );
vips_dbuf_appendf( &dbuf, "<root xmlns=\"%svips/%d.%d.%d\">\n",
vips_dbuf_writef( &dbuf, "<?xml version=\"1.0\"?>\n" );
vips_dbuf_writef( &dbuf, "<root xmlns=\"%svips/%d.%d.%d\">\n",
NAMESPACE_URI,
VIPS_MAJOR_VERSION, VIPS_MINOR_VERSION, VIPS_MICRO_VERSION );
vips_dbuf_appendf( &dbuf, " <header>\n" );
vips_dbuf_writef( &dbuf, " <header>\n" );
str = vips_image_get_history( image );
vips_dbuf_appendf( &dbuf, " <field type=\"%s\" name=\"Hist\">",
vips_dbuf_writef( &dbuf, " <field type=\"%s\" name=\"Hist\">",
g_type_name( VIPS_TYPE_REF_STRING ) );
dbuf_append_amp( &dbuf, str );
vips_dbuf_appendf( &dbuf, "</field>\n" );
dbuf_write_amp( &dbuf, str );
vips_dbuf_writef( &dbuf, "</field>\n" );
vips_dbuf_appendf( &dbuf, " </header>\n" );
vips_dbuf_appendf( &dbuf, " <meta>\n" );
vips_dbuf_writef( &dbuf, " </header>\n" );
vips_dbuf_writef( &dbuf, " <meta>\n" );
if( vips_slist_map2( image->meta_traverse,
(VipsSListMap2Fn) build_xml_meta, &dbuf, NULL ) ) {
@ -832,8 +832,8 @@ build_xml( VipsImage *image )
return( NULL );
}
vips_dbuf_appendf( &dbuf, " </meta>\n" );
vips_dbuf_appendf( &dbuf, "</root>\n" );
vips_dbuf_writef( &dbuf, " </meta>\n" );
vips_dbuf_writef( &dbuf, "</root>\n" );
return( (char *) vips_dbuf_steal( &dbuf, NULL ) );
}
@ -863,15 +863,15 @@ vips__xml_properties_meta( VipsImage *image,
str = vips_value_get_save_string( &save_value );
g_value_unset( &save_value );
vips_dbuf_appendf( dbuf, " <property>\n" );
vips_dbuf_appendf( dbuf, " <name>" );
dbuf_append_amp( dbuf, field );
vips_dbuf_appendf( dbuf, "</name>\n" );
vips_dbuf_appendf( dbuf, " <value type=\"%s\">",
vips_dbuf_writef( dbuf, " <property>\n" );
vips_dbuf_writef( dbuf, " <name>" );
dbuf_write_amp( dbuf, field );
vips_dbuf_writef( dbuf, "</name>\n" );
vips_dbuf_writef( dbuf, " <value type=\"%s\">",
g_type_name( type ) );
dbuf_append_amp( dbuf, str );
vips_dbuf_appendf( dbuf, "</value>\n" );
vips_dbuf_appendf( dbuf, " </property>\n" );
dbuf_write_amp( dbuf, str );
vips_dbuf_writef( dbuf, "</value>\n" );
vips_dbuf_writef( dbuf, " </property>\n" );
}
return( NULL );
@ -891,22 +891,22 @@ vips__xml_properties( VipsImage *image )
g_get_current_time( &now );
date = g_time_val_to_iso8601( &now );
vips_dbuf_appendf( &dbuf, "<?xml version=\"1.0\"?>\n" );
vips_dbuf_appendf( &dbuf, "<image xmlns=\"%s/dzsave\" "
vips_dbuf_writef( &dbuf, "<?xml version=\"1.0\"?>\n" );
vips_dbuf_writef( &dbuf, "<image xmlns=\"%s/dzsave\" "
"date=\"%s\" version=\"%d.%d.%d\">\n",
NAMESPACE_URI,
date,
VIPS_MAJOR_VERSION, VIPS_MINOR_VERSION, VIPS_MICRO_VERSION );
g_free( date );
vips_dbuf_appendf( &dbuf, " <properties>\n" );
vips_dbuf_writef( &dbuf, " <properties>\n" );
if( vips_image_map( image, vips__xml_properties_meta, &dbuf ) ) {
vips_dbuf_destroy( &dbuf );
return( NULL );
}
vips_dbuf_appendf( &dbuf, " </properties>\n" );
vips_dbuf_appendf( &dbuf, "</image>\n" );
vips_dbuf_writef( &dbuf, " </properties>\n" );
vips_dbuf_writef( &dbuf, "</image>\n" );
return( (char *) vips_dbuf_steal( &dbuf, NULL ) );
}