fix pyr tiff write to buffer
now we have a test for it heh
This commit is contained in:
parent
7cf7a6335e
commit
c0bfa4e70b
|
@ -1,4 +1,4 @@
|
||||||
/* Some shared TIFF utilities.
|
/* Some shared TIFF utilities.
|
||||||
*
|
*
|
||||||
* 14/10/16
|
* 14/10/16
|
||||||
* - from vips2tiff.c
|
* - from vips2tiff.c
|
||||||
|
@ -10,7 +10,7 @@
|
||||||
/*
|
/*
|
||||||
|
|
||||||
This file is part of VIPS.
|
This file is part of VIPS.
|
||||||
|
|
||||||
VIPS is free software; you can redistribute it and/or modify
|
VIPS is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU Lesser General Public License as published by
|
it under the terms of the GNU Lesser General Public License as published by
|
||||||
the Free Software Foundation; either version 2 of the License, or
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
@ -34,7 +34,7 @@
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
#define DEBUG
|
#define DEBUG
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -62,7 +62,7 @@
|
||||||
/* Handle TIFF errors here. Shared with vips2tiff.c. These can be called from
|
/* Handle TIFF errors here. Shared with vips2tiff.c. These can be called from
|
||||||
* more than one thread.
|
* more than one thread.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
vips__thandler_error( const char *module, const char *fmt, va_list ap )
|
vips__thandler_error( const char *module, const char *fmt, va_list ap )
|
||||||
{
|
{
|
||||||
vips_verror( module, fmt, ap );
|
vips_verror( module, fmt, ap );
|
||||||
|
@ -71,7 +71,7 @@ vips__thandler_error( const char *module, const char *fmt, va_list ap )
|
||||||
/* It'd be nice to be able to support the @fail option for the tiff loader, but
|
/* It'd be nice to be able to support the @fail option for the tiff loader, but
|
||||||
* there's no easy way to do this, since libtiff has a global warning handler.
|
* there's no easy way to do this, since libtiff has a global warning handler.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
vips__thandler_warning( const char *module, const char *fmt, va_list ap )
|
vips__thandler_warning( const char *module, const char *fmt, va_list ap )
|
||||||
{
|
{
|
||||||
g_logv( G_LOG_DOMAIN, G_LOG_LEVEL_WARNING, fmt, ap );
|
g_logv( G_LOG_DOMAIN, G_LOG_LEVEL_WARNING, fmt, ap );
|
||||||
|
@ -106,22 +106,22 @@ vips__tiff_openout( const char *path, gboolean bigtiff )
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
wchar_t *path16;
|
wchar_t *path16;
|
||||||
|
|
||||||
if( !(path16 = (wchar_t *)
|
if( !(path16 = (wchar_t *)
|
||||||
g_utf8_to_utf16( path, -1, NULL, NULL, &error )) ) {
|
g_utf8_to_utf16( path, -1, NULL, NULL, &error )) ) {
|
||||||
vips_g_error( &error );
|
vips_g_error( &error );
|
||||||
return( NULL );
|
return( NULL );
|
||||||
}
|
}
|
||||||
|
|
||||||
tif = TIFFOpenW( path16, mode );
|
tif = TIFFOpenW( path16, mode );
|
||||||
|
|
||||||
g_free( path16 );
|
g_free( path16 );
|
||||||
}
|
}
|
||||||
#else /*!OS_WIN32*/
|
#else /*!OS_WIN32*/
|
||||||
tif = TIFFOpen( path, mode );
|
tif = TIFFOpen( path, mode );
|
||||||
#endif /*OS_WIN32*/
|
#endif /*OS_WIN32*/
|
||||||
|
|
||||||
if( !tif ) {
|
if( !tif ) {
|
||||||
vips_error( "tiff",
|
vips_error( "tiff",
|
||||||
_( "unable to open \"%s\" for output" ), path );
|
_( "unable to open \"%s\" for output" ), path );
|
||||||
return( NULL );
|
return( NULL );
|
||||||
}
|
}
|
||||||
|
@ -129,7 +129,7 @@ vips__tiff_openout( const char *path, gboolean bigtiff )
|
||||||
return( tif );
|
return( tif );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Open TIFF for input from a file.
|
/* Open TIFF for input from a file.
|
||||||
*/
|
*/
|
||||||
TIFF *
|
TIFF *
|
||||||
vips__tiff_openin( const char *path )
|
vips__tiff_openin( const char *path )
|
||||||
|
@ -142,7 +142,7 @@ vips__tiff_openin( const char *path )
|
||||||
TIFF *tif;
|
TIFF *tif;
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printf( "vips__tiff_openin( \"%s\" )\n", path );
|
printf( "vips__tiff_openin( \"%s\" )\n", path );
|
||||||
#endif /*DEBUG*/
|
#endif /*DEBUG*/
|
||||||
|
|
||||||
/* Need the utf-16 version on Windows.
|
/* Need the utf-16 version on Windows.
|
||||||
|
@ -152,22 +152,22 @@ vips__tiff_openin( const char *path )
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
wchar_t *path16;
|
wchar_t *path16;
|
||||||
|
|
||||||
if( !(path16 = (wchar_t *)
|
if( !(path16 = (wchar_t *)
|
||||||
g_utf8_to_utf16( path, -1, NULL, NULL, &error )) ) {
|
g_utf8_to_utf16( path, -1, NULL, NULL, &error )) ) {
|
||||||
vips_g_error( &error );
|
vips_g_error( &error );
|
||||||
return( NULL );
|
return( NULL );
|
||||||
}
|
}
|
||||||
|
|
||||||
tif = TIFFOpenW( path16, mode );
|
tif = TIFFOpenW( path16, mode );
|
||||||
|
|
||||||
g_free( path16 );
|
g_free( path16 );
|
||||||
}
|
}
|
||||||
#else /*!OS_WIN32*/
|
#else /*!OS_WIN32*/
|
||||||
tif = TIFFOpen( path, mode );
|
tif = TIFFOpen( path, mode );
|
||||||
#endif /*OS_WIN32*/
|
#endif /*OS_WIN32*/
|
||||||
|
|
||||||
if( !tif ) {
|
if( !tif ) {
|
||||||
vips_error( "tiff",
|
vips_error( "tiff",
|
||||||
_( "unable to open \"%s\" for input" ), path );
|
_( "unable to open \"%s\" for input" ), path );
|
||||||
return( NULL );
|
return( NULL );
|
||||||
}
|
}
|
||||||
|
@ -175,7 +175,7 @@ vips__tiff_openin( const char *path )
|
||||||
return( tif );
|
return( tif );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TIFF input from a memory buffer.
|
/* TIFF input from a memory buffer.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef struct _VipsTiffOpeninBuffer {
|
typedef struct _VipsTiffOpeninBuffer {
|
||||||
|
@ -184,7 +184,7 @@ typedef struct _VipsTiffOpeninBuffer {
|
||||||
size_t length;
|
size_t length;
|
||||||
} VipsTiffOpeninBuffer;
|
} VipsTiffOpeninBuffer;
|
||||||
|
|
||||||
static tsize_t
|
static tsize_t
|
||||||
openin_buffer_read( thandle_t st, tdata_t data, tsize_t size )
|
openin_buffer_read( thandle_t st, tdata_t data, tsize_t size )
|
||||||
{
|
{
|
||||||
VipsTiffOpeninBuffer *buffer = (VipsTiffOpeninBuffer *) st;
|
VipsTiffOpeninBuffer *buffer = (VipsTiffOpeninBuffer *) st;
|
||||||
|
@ -193,38 +193,38 @@ openin_buffer_read( thandle_t st, tdata_t data, tsize_t size )
|
||||||
size_t copied;
|
size_t copied;
|
||||||
|
|
||||||
if( buffer->position > buffer->length ) {
|
if( buffer->position > buffer->length ) {
|
||||||
vips_error( "openin_buffer_read",
|
vips_error( "openin_buffer_read",
|
||||||
"%s", _( "read beyond end of buffer" ) );
|
"%s", _( "read beyond end of buffer" ) );
|
||||||
return( 0 );
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
available = buffer->length - buffer->position;
|
available = buffer->length - buffer->position;
|
||||||
copied = VIPS_MIN( size, available );
|
copied = VIPS_MIN( size, available );
|
||||||
memcpy( data,
|
memcpy( data,
|
||||||
(unsigned char *) buffer->data + buffer->position, copied );
|
(unsigned char *) buffer->data + buffer->position, copied );
|
||||||
buffer->position += copied;
|
buffer->position += copied;
|
||||||
|
|
||||||
return( copied );
|
return( copied );
|
||||||
}
|
}
|
||||||
|
|
||||||
static tsize_t
|
static tsize_t
|
||||||
openin_buffer_write( thandle_t st, tdata_t buffer, tsize_t size )
|
openin_buffer_write( thandle_t st, tdata_t buffer, tsize_t size )
|
||||||
{
|
{
|
||||||
g_assert_not_reached();
|
g_assert_not_reached();
|
||||||
|
|
||||||
return( 0 );
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
openin_buffer_close( thandle_t st )
|
openin_buffer_close( thandle_t st )
|
||||||
{
|
{
|
||||||
return( 0 );
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* After calling this, ->pos is not bound by the size of the buffer, it can
|
/* After calling this, ->pos is not bound by the size of the buffer, it can
|
||||||
* have any positive value.
|
* have any positive value.
|
||||||
*/
|
*/
|
||||||
static toff_t
|
static toff_t
|
||||||
openin_buffer_seek( thandle_t st, toff_t position, int whence )
|
openin_buffer_seek( thandle_t st, toff_t position, int whence )
|
||||||
{
|
{
|
||||||
VipsTiffOpeninBuffer *buffer = (VipsTiffOpeninBuffer *) st;
|
VipsTiffOpeninBuffer *buffer = (VipsTiffOpeninBuffer *) st;
|
||||||
|
@ -236,31 +236,31 @@ openin_buffer_seek( thandle_t st, toff_t position, int whence )
|
||||||
else if( whence == SEEK_END )
|
else if( whence == SEEK_END )
|
||||||
buffer->position = buffer->length + position;
|
buffer->position = buffer->length + position;
|
||||||
else
|
else
|
||||||
g_assert_not_reached();
|
g_assert_not_reached();
|
||||||
|
|
||||||
return( buffer->position );
|
return( buffer->position );
|
||||||
}
|
}
|
||||||
|
|
||||||
static toff_t
|
static toff_t
|
||||||
openin_buffer_size( thandle_t st )
|
openin_buffer_size( thandle_t st )
|
||||||
{
|
{
|
||||||
VipsTiffOpeninBuffer *buffer = (VipsTiffOpeninBuffer *) st;
|
VipsTiffOpeninBuffer *buffer = (VipsTiffOpeninBuffer *) st;
|
||||||
|
|
||||||
return( buffer->length );
|
return( buffer->length );
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
openin_buffer_map( thandle_t st, tdata_t *start, toff_t *len )
|
openin_buffer_map( thandle_t st, tdata_t *start, toff_t *len )
|
||||||
{
|
{
|
||||||
g_assert_not_reached();
|
g_assert_not_reached();
|
||||||
|
|
||||||
return( 0 );
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
openin_buffer_unmap( thandle_t st, tdata_t start, toff_t len )
|
openin_buffer_unmap( thandle_t st, tdata_t start, toff_t len )
|
||||||
{
|
{
|
||||||
g_assert_not_reached();
|
g_assert_not_reached();
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -272,7 +272,7 @@ vips__tiff_openin_buffer( VipsImage *image, const void *data, size_t length )
|
||||||
TIFF *tiff;
|
TIFF *tiff;
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printf( "vips__tiff_openin_buffer:\n" );
|
printf( "vips__tiff_openin_buffer:\n" );
|
||||||
#endif /*DEBUG*/
|
#endif /*DEBUG*/
|
||||||
|
|
||||||
buffer = VIPS_NEW( image, VipsTiffOpeninBuffer );
|
buffer = VIPS_NEW( image, VipsTiffOpeninBuffer );
|
||||||
|
@ -282,26 +282,26 @@ vips__tiff_openin_buffer( VipsImage *image, const void *data, size_t length )
|
||||||
|
|
||||||
if( !(tiff = TIFFClientOpen( "memory input", "rm",
|
if( !(tiff = TIFFClientOpen( "memory input", "rm",
|
||||||
(thandle_t) buffer,
|
(thandle_t) buffer,
|
||||||
openin_buffer_read,
|
openin_buffer_read,
|
||||||
openin_buffer_write,
|
openin_buffer_write,
|
||||||
openin_buffer_seek,
|
openin_buffer_seek,
|
||||||
openin_buffer_close,
|
openin_buffer_close,
|
||||||
openin_buffer_size,
|
openin_buffer_size,
|
||||||
openin_buffer_map,
|
openin_buffer_map,
|
||||||
openin_buffer_unmap )) ) {
|
openin_buffer_unmap )) ) {
|
||||||
vips_error( "vips__tiff_openin_buffer", "%s",
|
vips_error( "vips__tiff_openin_buffer", "%s",
|
||||||
_( "unable to open memory buffer for input" ) );
|
_( "unable to open memory buffer for input" ) );
|
||||||
return( NULL );
|
return( NULL );
|
||||||
}
|
}
|
||||||
|
|
||||||
return( tiff );
|
return( tiff );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TIFF output to a memory buffer.
|
/* TIFF output to a memory buffer.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef struct _VipsTiffOpenoutBuffer {
|
typedef struct _VipsTiffOpenoutBuffer {
|
||||||
VipsDbuf dbuf;
|
VipsDbuf dbuf;
|
||||||
|
|
||||||
/* On close, consolidate and write the output here.
|
/* On close, consolidate and write the output here.
|
||||||
*/
|
*/
|
||||||
|
@ -309,91 +309,96 @@ typedef struct _VipsTiffOpenoutBuffer {
|
||||||
size_t *out_length;
|
size_t *out_length;
|
||||||
} VipsTiffOpenoutBuffer;
|
} VipsTiffOpenoutBuffer;
|
||||||
|
|
||||||
static tsize_t
|
static tsize_t
|
||||||
openout_buffer_read( thandle_t st, tdata_t data, tsize_t size )
|
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
|
||||||
openout_buffer_write( thandle_t st, tdata_t data, tsize_t size )
|
openout_buffer_write( thandle_t st, tdata_t data, tsize_t size )
|
||||||
{
|
{
|
||||||
VipsTiffOpenoutBuffer *buffer = (VipsTiffOpenoutBuffer *) st;
|
VipsTiffOpenoutBuffer *buffer = (VipsTiffOpenoutBuffer *) st;
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printf( "openout_buffer_write: %zd bytes\n", size );
|
printf( "openout_buffer_write: %zd bytes\n", size );
|
||||||
#endif /*DEBUG*/
|
#endif /*DEBUG*/
|
||||||
|
|
||||||
vips_dbuf_write( &buffer->dbuf, data, size );
|
vips_dbuf_write( &buffer->dbuf, data, size );
|
||||||
|
|
||||||
return( size );
|
return( size );
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
openout_buffer_close( thandle_t st )
|
openout_buffer_close( thandle_t st )
|
||||||
{
|
{
|
||||||
VipsTiffOpenoutBuffer *buffer = (VipsTiffOpenoutBuffer *) st;
|
VipsTiffOpenoutBuffer *buffer = (VipsTiffOpenoutBuffer *) st;
|
||||||
|
|
||||||
*(buffer->out_data) = vips_dbuf_steal( &buffer->dbuf,
|
*(buffer->out_data) = vips_dbuf_steal( &buffer->dbuf,
|
||||||
buffer->out_length);
|
buffer->out_length);
|
||||||
|
|
||||||
return( 0 );
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
static toff_t
|
static toff_t
|
||||||
openout_buffer_seek( thandle_t st, toff_t position, int whence )
|
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 );
|
||||||
|
|
||||||
return( vips_dbuf_tell( &buffer->dbuf ) );
|
return( vips_dbuf_tell( &buffer->dbuf ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
static toff_t
|
static toff_t
|
||||||
openout_buffer_size( thandle_t st )
|
openout_buffer_size( thandle_t st )
|
||||||
{
|
{
|
||||||
g_assert_not_reached();
|
g_assert_not_reached();
|
||||||
|
|
||||||
return( 0 );
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
openout_buffer_map( thandle_t st, tdata_t *start, toff_t *len )
|
|
||||||
{
|
|
||||||
g_assert_not_reached();
|
|
||||||
|
|
||||||
return( 0 );
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static int
|
||||||
|
openout_buffer_map( thandle_t st, tdata_t *start, toff_t *len )
|
||||||
|
{
|
||||||
|
g_assert_not_reached();
|
||||||
|
|
||||||
|
return( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
openout_buffer_unmap( thandle_t st, tdata_t start, toff_t len )
|
openout_buffer_unmap( thandle_t st, tdata_t start, toff_t len )
|
||||||
{
|
{
|
||||||
g_assert_not_reached();
|
g_assert_not_reached();
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -401,7 +406,7 @@ openout_buffer_unmap( thandle_t st, tdata_t start, toff_t len )
|
||||||
/* On TIFFClose(), @data and @length are set to point to the output buffer.
|
/* On TIFFClose(), @data and @length are set to point to the output buffer.
|
||||||
*/
|
*/
|
||||||
TIFF *
|
TIFF *
|
||||||
vips__tiff_openout_buffer( VipsImage *image,
|
vips__tiff_openout_buffer( VipsImage *image,
|
||||||
gboolean bigtiff, void **out_data, size_t *out_length )
|
gboolean bigtiff, void **out_data, size_t *out_length )
|
||||||
{
|
{
|
||||||
const char *mode = bigtiff ? "w8" : "w";
|
const char *mode = bigtiff ? "w8" : "w";
|
||||||
|
@ -410,29 +415,29 @@ vips__tiff_openout_buffer( VipsImage *image,
|
||||||
TIFF *tiff;
|
TIFF *tiff;
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printf( "vips__tiff_openout_buffer:\n" );
|
printf( "vips__tiff_openout_buffer:\n" );
|
||||||
#endif /*DEBUG*/
|
#endif /*DEBUG*/
|
||||||
|
|
||||||
buffer = VIPS_NEW( image, VipsTiffOpenoutBuffer );
|
buffer = VIPS_NEW( image, VipsTiffOpenoutBuffer );
|
||||||
vips_dbuf_init( &buffer->dbuf );
|
vips_dbuf_init( &buffer->dbuf );
|
||||||
buffer->out_data = out_data;
|
buffer->out_data = out_data;
|
||||||
buffer->out_length = out_length;
|
buffer->out_length = out_length;
|
||||||
|
|
||||||
if( !(tiff = TIFFClientOpen( "memory output", mode,
|
if( !(tiff = TIFFClientOpen( "memory output", mode,
|
||||||
(thandle_t) buffer,
|
(thandle_t) buffer,
|
||||||
openout_buffer_read,
|
openout_buffer_read,
|
||||||
openout_buffer_write,
|
openout_buffer_write,
|
||||||
openout_buffer_seek,
|
openout_buffer_seek,
|
||||||
openout_buffer_close,
|
openout_buffer_close,
|
||||||
openout_buffer_size,
|
openout_buffer_size,
|
||||||
openout_buffer_map,
|
openout_buffer_map,
|
||||||
openout_buffer_unmap )) ) {
|
openout_buffer_unmap )) ) {
|
||||||
vips_error( "vips__tiff_openout_buffer", "%s",
|
vips_error( "vips__tiff_openout_buffer", "%s",
|
||||||
_( "unable to open memory buffer for output" ) );
|
_( "unable to open memory buffer for output" ) );
|
||||||
return( NULL );
|
return( NULL );
|
||||||
}
|
}
|
||||||
|
|
||||||
return( tiff );
|
return( tiff );
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /*HAVE_TIFF*/
|
#endif /*HAVE_TIFF*/
|
||||||
|
|
|
@ -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 );
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue