Merge remote-tracking branch 'origin/tiffload-buffer'

Conflicts:
	ChangeLog
This commit is contained in:
John Cupitt 2014-04-22 13:25:25 +01:00
commit aeb3cf3fa3
7 changed files with 412 additions and 116 deletions

View File

@ -22,6 +22,7 @@
argument order argument order
- support 16-bit palette TIFFs, plus palette TIFFs can have an alpha - support 16-bit palette TIFFs, plus palette TIFFs can have an alpha
- add ".vips" as an alternative suffix for vips files - add ".vips" as an alternative suffix for vips files
- add vips_tiffload_buffer()
6/3/14 started 7.38.6 6/3/14 started 7.38.6
- grey ramp minimum was wrong - grey ramp minimum was wrong

View File

@ -1651,7 +1651,8 @@ vips_foreign_operation_init( void )
extern GType vips_foreign_save_jpeg_file_get_type( void ); extern GType vips_foreign_save_jpeg_file_get_type( void );
extern GType vips_foreign_save_jpeg_buffer_get_type( void ); extern GType vips_foreign_save_jpeg_buffer_get_type( void );
extern GType vips_foreign_save_jpeg_mime_get_type( void ); extern GType vips_foreign_save_jpeg_mime_get_type( void );
extern GType vips_foreign_load_tiff_get_type( void ); extern GType vips_foreign_load_tiff_file_get_type( void );
extern GType vips_foreign_load_tiff_buffer_get_type( void );
extern GType vips_foreign_save_tiff_get_type( void ); extern GType vips_foreign_save_tiff_get_type( void );
extern GType vips_foreign_load_vips_get_type( void ); extern GType vips_foreign_load_vips_get_type( void );
extern GType vips_foreign_save_vips_get_type( void ); extern GType vips_foreign_save_vips_get_type( void );
@ -1709,7 +1710,8 @@ vips_foreign_operation_init( void )
#endif /*HAVE_LIBWEBP*/ #endif /*HAVE_LIBWEBP*/
#ifdef HAVE_TIFF #ifdef HAVE_TIFF
vips_foreign_load_tiff_get_type(); vips_foreign_load_tiff_file_get_type();
vips_foreign_load_tiff_buffer_get_type();
vips_foreign_save_tiff_get_type(); vips_foreign_save_tiff_get_type();
#endif /*HAVE_TIFF*/ #endif /*HAVE_TIFF*/
@ -1807,6 +1809,44 @@ vips_tiffload( const char *filename, VipsImage **out, ... )
return( result ); return( result );
} }
/**
* vips_tiffload_buffer:
* @buf: memory area to load
* @len: size of memory area
* @out: image to write
* @...: %NULL-terminated list of optional named arguments
*
* Optional arguments:
*
* @page: load this page
*
* Read a TIFF-formatted memory block into a VIPS image. Exactly as
* vips_tiffload(), but read from a memory source.
*
* See also: vips_tiffload().
*
* Returns: 0 on success, -1 on error.
*/
int
vips_tiffload_buffer( void *buf, size_t len, VipsImage **out, ... )
{
va_list ap;
VipsArea *area;
int result;
/* We don't take a copy of the data or free it.
*/
area = vips_area_new_blob( NULL, buf, len );
va_start( ap, out );
result = vips_call_split( "tiffload_buffer", ap, area, out );
va_end( ap );
vips_area_unref( area );
return( result );
}
/** /**
* vips_tiffsave: * vips_tiffsave:
* @in: image to save * @in: image to save
@ -1899,46 +1939,6 @@ vips_tiffsave( VipsImage *in, const char *filename, ... )
return( result ); return( result );
} }
/**
* vips_jpegload_buffer:
* @buf: memory area to load
* @len: size of memory area
* @out: image to write
* @...: %NULL-terminated list of optional named arguments
*
* Read a JPEG-formatted memory block into a VIPS image. It can read most
* 8-bit JPEG images, including CMYK and YCbCr.
*
* This function is handy for processing JPEG image thumbnails.
*
* Caution: on return only the header will have been read, the pixel data is
* not decompressed until the first pixel is read. Therefore you must not free
* @buf until you have read pixel data from @out.
*
* See also: vips_jpegload().
*
* Returns: 0 on success, -1 on error.
*/
int
vips_jpegload_buffer( void *buf, size_t len, VipsImage **out, ... )
{
va_list ap;
VipsArea *area;
int result;
/* We don't take a copy of the data or free it.
*/
area = vips_area_new_blob( NULL, buf, len );
va_start( ap, out );
result = vips_call_split( "jpegload_buffer", ap, area, out );
va_end( ap );
vips_area_unref( area );
return( result );
}
/** /**
* vips_jpegload: * vips_jpegload:
* @filename: file to load * @filename: file to load
@ -2008,6 +2008,45 @@ vips_jpegload( const char *filename, VipsImage **out, ... )
return( result ); return( result );
} }
/**
* vips_jpegload_buffer:
* @buf: memory area to load
* @len: size of memory area
* @out: image to write
* @...: %NULL-terminated list of optional named arguments
*
* Optional arguments:
*
* @shrink: shrink by this much on load
* @fail: fail on warnings
*
* Read a JPEG-formatted memory block into a VIPS image. Exactly as
* vips_jpegload(), but read from a memory buffer.
*
* See also: vips_jpegload().
*
* Returns: 0 on success, -1 on error.
*/
int
vips_jpegload_buffer( void *buf, size_t len, VipsImage **out, ... )
{
va_list ap;
VipsArea *area;
int result;
/* We don't take a copy of the data or free it.
*/
area = vips_area_new_blob( NULL, buf, len );
va_start( ap, out );
result = vips_call_split( "jpegload_buffer", ap, area, out );
va_end( ap );
vips_area_unref( area );
return( result );
}
/** /**
* vips_jpegsave: * vips_jpegsave:
* @in: image to save * @in: image to save

View File

@ -50,12 +50,17 @@ int vips__tiff_write( VipsImage *in, const char *filename,
gboolean bigtiff, gboolean bigtiff,
gboolean rgbjpeg ); gboolean rgbjpeg );
int vips__tiff_read( const char *filename, VipsImage *out, int page,
gboolean readbehind );
int vips__tiff_read_header( const char *filename, VipsImage *out, int page ); int vips__tiff_read_header( const char *filename, VipsImage *out, int page );
int vips__tiff_read( const char *filename, VipsImage *out,
int page, gboolean readbehind );
gboolean vips__istifftiled( const char *filename ); gboolean vips__istifftiled( const char *filename );
gboolean vips__istiff( const char *filename ); gboolean vips__istiff( const char *filename );
int vips__tiff_read_header_buffer( void *buf, size_t len, VipsImage *out,
int page );
int vips__tiff_read_buffer( void *buf, size_t len, VipsImage *out,
int page, gboolean readbehind );
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif /*__cplusplus*/ #endif /*__cplusplus*/

View File

@ -144,6 +144,8 @@
* 11/4/14 * 11/4/14
* - support 16 bits per sample palette images * - support 16 bits per sample palette images
* - palette images can have an alpha * - palette images can have an alpha
* 22/4/14
* - add read from buffer
*/ */
/* /*
@ -208,6 +210,8 @@ typedef struct _ReadTiff {
/* Parameters. /* Parameters.
*/ */
char *filename; char *filename;
void *buf;
size_t len;
VipsImage *out; VipsImage *out;
int page; int page;
gboolean readbehind; gboolean readbehind;
@ -225,6 +229,10 @@ typedef struct _ReadTiff {
*/ */
gboolean memcpy; gboolean memcpy;
/* The current 'file pointer' for memory buffers.
*/
size_t pos;
/* Geometry. /* Geometry.
*/ */
uint32 twidth, theight; /* Tile size */ uint32 twidth, theight; /* Tile size */
@ -1635,15 +1643,16 @@ readtiff_destroy( VipsObject *object, ReadTiff *rtiff )
} }
static ReadTiff * static ReadTiff *
readtiff_new( const char *filename, VipsImage *out, int page, readtiff_new( VipsImage *out, int page, gboolean readbehind )
gboolean readbehind )
{ {
ReadTiff *rtiff; ReadTiff *rtiff;
if( !(rtiff = VIPS_NEW( out, ReadTiff )) ) if( !(rtiff = VIPS_NEW( out, ReadTiff )) )
return( NULL ); return( NULL );
rtiff->filename = vips_strdup( VIPS_OBJECT( out ), filename ); rtiff->filename = NULL;
rtiff->buf = NULL;
rtiff->len = 0;
rtiff->out = out; rtiff->out = out;
rtiff->page = page; rtiff->page = page;
rtiff->readbehind = readbehind; rtiff->readbehind = readbehind;
@ -1651,6 +1660,7 @@ readtiff_new( const char *filename, VipsImage *out, int page,
rtiff->sfn = NULL; rtiff->sfn = NULL;
rtiff->client = NULL; rtiff->client = NULL;
rtiff->memcpy = FALSE; rtiff->memcpy = FALSE;
rtiff->pos = 0;
rtiff->twidth = 0; rtiff->twidth = 0;
rtiff->theight = 0; rtiff->theight = 0;
rtiff->separate = FALSE; rtiff->separate = FALSE;
@ -1669,33 +1679,138 @@ readtiff_new( const char *filename, VipsImage *out, int page,
return( rtiff ); return( rtiff );
} }
/* Pull out the nth directory from a TIFF file. static ReadTiff *
*/ readtiff_new_filename( const char *filename, VipsImage *out, int page,
static TIFF * gboolean readbehind )
get_directory( const char *filename, int page )
{ {
TIFF *tif; ReadTiff *rtiff;
int i; int i;
if( !(rtiff = readtiff_new( out, page, readbehind )) )
return( NULL );
rtiff->filename = vips_strdup( VIPS_OBJECT( out ), filename );
/* No mmap --- no performance advantage with libtiff, and it burns up /* No mmap --- no performance advantage with libtiff, and it burns up
* our VM if the tiff file is large. * our VM if the tiff file is large.
*/ */
if( !(tif = TIFFOpen( filename, "rm" )) ) { if( !(rtiff->tiff = TIFFOpen( filename, "rm" )) ) {
vips_error( "tiff2vips", vips_error( "tiff2vips", _( "unable to open \"%s\" for input" ),
_( "unable to open \"%s\" for input" ),
filename ); filename );
return( NULL ); return( NULL );
} }
for( i = 0; i < page; i++ ) for( i = 0; i < page; i++ )
if( !TIFFReadDirectory( tif ) ) { if( !TIFFReadDirectory( rtiff->tiff ) ) {
/* Run out of directories. vips_error( "tiff2vips",
*/ _( "TIFF does not contain page %d" ),
TIFFClose( tif ); rtiff->page );
return( NULL ); return( NULL );
} }
return( tif ); return( rtiff );
}
static tsize_t
my_tiff_read( thandle_t st, tdata_t buffer, tsize_t size )
{
ReadTiff *rtiff = (ReadTiff *) st;
size_t available = rtiff->len - rtiff->pos;
size_t copy = VIPS_MIN( size, available );
memcpy( buffer, rtiff->buf + rtiff->pos, copy );
rtiff->pos += copy;
return( copy );
}
static tsize_t
my_tiff_write( thandle_t st, tdata_t buffer, tsize_t size )
{
g_assert( 0 );
return( 0 );
}
static int
my_tiff_close( thandle_t st )
{
return 0;
}
static toff_t
my_tiff_seek( thandle_t st, toff_t pos, int whence )
{
ReadTiff *rtiff = (ReadTiff *) st;
if( whence == SEEK_SET )
rtiff->pos = pos;
else if( whence == SEEK_CUR )
rtiff->pos += pos;
else if( whence == SEEK_END )
rtiff->pos = rtiff->len + pos;
else
g_assert( 0 );
return( rtiff->pos );
}
static toff_t
my_tiff_size( thandle_t st )
{
ReadTiff *rtiff = (ReadTiff *) st;
return( rtiff->len );
}
static int
my_tiff_map( thandle_t st, tdata_t *start, toff_t *len )
{
g_assert( 0 );
return 0;
}
static void
my_tiff_unmap( thandle_t st, tdata_t start, toff_t len )
{
g_assert( 0 );
return;
}
static ReadTiff *
readtiff_new_buffer( void *buf, size_t len, VipsImage *out, int page,
gboolean readbehind )
{
ReadTiff *rtiff;
int i;
if( !(rtiff = readtiff_new( out, page, readbehind )) )
return( NULL );
rtiff->buf = buf;
rtiff->len = len;
if( !(rtiff->tiff = TIFFClientOpen( "memory buffer", "rm",
(thandle_t) rtiff,
my_tiff_read, my_tiff_write, my_tiff_seek, my_tiff_close,
my_tiff_size, my_tiff_map, my_tiff_unmap )) ) {
vips_error( "tiff2vips", "%s",
_( "unable to open memory buffer for input" ) );
return( NULL );
}
for( i = 0; i < page; i++ )
if( !TIFFReadDirectory( rtiff->tiff ) ) {
vips_error( "tiff2vips",
_( "TIFF does not contain page %d" ),
rtiff->page );
return( NULL );
}
return( rtiff );
} }
/* /*
@ -1732,15 +1847,10 @@ vips__tiff_read( const char *filename, VipsImage *out, int page,
vips__tiff_init(); vips__tiff_init();
if( !(rtiff = readtiff_new( filename, out, page, readbehind )) ) if( !(rtiff = readtiff_new_filename( filename,
out, page, readbehind )) )
return( -1 ); return( -1 );
if( !(rtiff->tiff = get_directory( rtiff->filename, rtiff->page )) ) {
vips_error( "tiff2vips", _( "TIFF file does not "
"contain page %d" ), rtiff->page );
return( -1 );
}
if( TIFFIsTiled( rtiff->tiff ) ) { if( TIFFIsTiled( rtiff->tiff ) ) {
if( read_tilewise( rtiff, out ) ) if( read_tilewise( rtiff, out ) )
return( -1 ); return( -1 );
@ -1760,16 +1870,9 @@ vips__tiff_read_header( const char *filename, VipsImage *out, int page )
vips__tiff_init(); vips__tiff_init();
if( !(rtiff = readtiff_new( filename, out, page, FALSE )) ) if( !(rtiff = readtiff_new_filename( filename, out, page, FALSE )) )
return( -1 ); return( -1 );
if( !(rtiff->tiff = get_directory( rtiff->filename, rtiff->page )) ) {
vips_error( "tiff2vips",
_( "TIFF file does not contain page %d" ),
rtiff->page );
return( -1 );
}
if( parse_header( rtiff, out ) ) if( parse_header( rtiff, out ) )
return( -1 ); return( -1 );
@ -1807,4 +1910,48 @@ vips__istiff( const char *filename )
return( FALSE ); return( FALSE );
} }
int
vips__tiff_read_header_buffer( void *buf, size_t len, VipsImage *out, int page )
{
ReadTiff *rtiff;
vips__tiff_init();
if( !(rtiff = readtiff_new_buffer( buf, len, out, page, FALSE )) )
return( -1 );
if( parse_header( rtiff, out ) )
return( -1 );
return( 0 );
}
int
vips__tiff_read_buffer( void *buf, size_t len, VipsImage *out,
int page, gboolean readbehind )
{
ReadTiff *rtiff;
#ifdef DEBUG
printf( "tiff2vips: libtiff version is \"%s\"\n", TIFFGetVersion() );
printf( "tiff2vips: libtiff starting for %s\n", filename );
#endif /*DEBUG*/
vips__tiff_init();
if( !(rtiff = readtiff_new_buffer( buf, len, out, page, readbehind )) )
return( -1 );
if( TIFFIsTiled( rtiff->tiff ) ) {
if( read_tilewise( rtiff, out ) )
return( -1 );
}
else {
if( read_stripwise( rtiff, out ) )
return( -1 );
}
return( 0 );
}
#endif /*HAVE_TIFF*/ #endif /*HAVE_TIFF*/

View File

@ -55,10 +55,6 @@
typedef struct _VipsForeignLoadTiff { typedef struct _VipsForeignLoadTiff {
VipsForeignLoad parent_object; VipsForeignLoad parent_object;
/* Filename for load.
*/
char *filename;
/* Load this page. /* Load this page.
*/ */
int page; int page;
@ -67,11 +63,58 @@ typedef struct _VipsForeignLoadTiff {
typedef VipsForeignLoadClass VipsForeignLoadTiffClass; typedef VipsForeignLoadClass VipsForeignLoadTiffClass;
G_DEFINE_TYPE( VipsForeignLoadTiff, vips_foreign_load_tiff, G_DEFINE_ABSTRACT_TYPE( VipsForeignLoadTiff, vips_foreign_load_tiff,
VIPS_TYPE_FOREIGN_LOAD ); VIPS_TYPE_FOREIGN_LOAD );
static void
vips_foreign_load_tiff_class_init( VipsForeignLoadTiffClass *class )
{
GObjectClass *gobject_class = G_OBJECT_CLASS( class );
VipsObjectClass *object_class = (VipsObjectClass *) class;
/* Other libraries may be using libtiff, we want to capture tiff
* warning and error as soon as we can.
*
* This class init will be triggered during startup.
*/
vips__tiff_init();
gobject_class->set_property = vips_object_set_property;
gobject_class->get_property = vips_object_get_property;
object_class->nickname = "tiffload_base";
object_class->description = _( "load tiff" );
VIPS_ARG_INT( class, "page", 10,
_( "Page" ),
_( "Load this page from the image" ),
VIPS_ARGUMENT_OPTIONAL_INPUT,
G_STRUCT_OFFSET( VipsForeignLoadTiff, page ),
0, 100000, 0 );
}
static void
vips_foreign_load_tiff_init( VipsForeignLoadTiff *tiff )
{
tiff->page = 0;
}
typedef struct _VipsForeignLoadTiffFile {
VipsForeignLoadTiff parent_object;
/* Filename for load.
*/
char *filename;
} VipsForeignLoadTiffFile;
typedef VipsForeignLoadTiffClass VipsForeignLoadTiffFileClass;
G_DEFINE_TYPE( VipsForeignLoadTiffFile, vips_foreign_load_tiff_file,
vips_foreign_load_tiff_get_type() );
static VipsForeignFlags static VipsForeignFlags
vips_foreign_load_tiff_get_flags_filename( const char *filename ) vips_foreign_load_tiff_file_get_flags_filename( const char *filename )
{ {
VipsForeignFlags flags; VipsForeignFlags flags;
@ -85,30 +128,33 @@ vips_foreign_load_tiff_get_flags_filename( const char *filename )
} }
static VipsForeignFlags static VipsForeignFlags
vips_foreign_load_tiff_get_flags( VipsForeignLoad *load ) vips_foreign_load_tiff_file_get_flags( VipsForeignLoad *load )
{ {
VipsForeignLoadTiff *tiff = (VipsForeignLoadTiff *) load; VipsForeignLoadTiffFile *file = (VipsForeignLoadTiffFile *) load;
return( vips_foreign_load_tiff_get_flags_filename( tiff->filename ) ); return( vips_foreign_load_tiff_file_get_flags_filename(
file->filename ) );
} }
static int static int
vips_foreign_load_tiff_header( VipsForeignLoad *load ) vips_foreign_load_tiff_file_header( VipsForeignLoad *load )
{ {
VipsForeignLoadTiff *tiff = (VipsForeignLoadTiff *) load; VipsForeignLoadTiff *tiff = (VipsForeignLoadTiff *) load;
VipsForeignLoadTiffFile *file = (VipsForeignLoadTiffFile *) load;
if( vips__tiff_read_header( tiff->filename, load->out, tiff->page ) ) if( vips__tiff_read_header( file->filename, load->out, tiff->page ) )
return( -1 ); return( -1 );
return( 0 ); return( 0 );
} }
static int static int
vips_foreign_load_tiff_load( VipsForeignLoad *load ) vips_foreign_load_tiff_file_load( VipsForeignLoad *load )
{ {
VipsForeignLoadTiff *tiff = (VipsForeignLoadTiff *) load; VipsForeignLoadTiff *tiff = (VipsForeignLoadTiff *) load;
VipsForeignLoadTiffFile *file = (VipsForeignLoadTiffFile *) load;
if( vips__tiff_read( tiff->filename, load->real, tiff->page, if( vips__tiff_read( file->filename, load->real, tiff->page,
load->access == VIPS_ACCESS_SEQUENTIAL ) ) load->access == VIPS_ACCESS_SEQUENTIAL ) )
return( -1 ); return( -1 );
@ -118,20 +164,13 @@ vips_foreign_load_tiff_load( VipsForeignLoad *load )
const char *vips__foreign_tiff_suffs[] = { ".tif", ".tiff", NULL }; const char *vips__foreign_tiff_suffs[] = { ".tif", ".tiff", NULL };
static void static void
vips_foreign_load_tiff_class_init( VipsForeignLoadTiffClass *class ) vips_foreign_load_tiff_file_class_init( VipsForeignLoadTiffFileClass *class )
{ {
GObjectClass *gobject_class = G_OBJECT_CLASS( class ); GObjectClass *gobject_class = G_OBJECT_CLASS( class );
VipsObjectClass *object_class = (VipsObjectClass *) class; VipsObjectClass *object_class = (VipsObjectClass *) class;
VipsForeignClass *foreign_class = (VipsForeignClass *) class; VipsForeignClass *foreign_class = (VipsForeignClass *) class;
VipsForeignLoadClass *load_class = (VipsForeignLoadClass *) class; VipsForeignLoadClass *load_class = (VipsForeignLoadClass *) class;
/* Other libraries may be using libtiff, we want to capture tiff
* warning and error as soon as we can.
*
* This class init will be triggered during startup.
*/
vips__tiff_init();
gobject_class->set_property = vips_object_set_property; gobject_class->set_property = vips_object_set_property;
gobject_class->get_property = vips_object_get_property; gobject_class->get_property = vips_object_get_property;
@ -142,28 +181,94 @@ vips_foreign_load_tiff_class_init( VipsForeignLoadTiffClass *class )
load_class->is_a = vips__istiff; load_class->is_a = vips__istiff;
load_class->get_flags_filename = load_class->get_flags_filename =
vips_foreign_load_tiff_get_flags_filename; vips_foreign_load_tiff_file_get_flags_filename;
load_class->get_flags = vips_foreign_load_tiff_get_flags; load_class->get_flags = vips_foreign_load_tiff_file_get_flags;
load_class->header = vips_foreign_load_tiff_header; load_class->header = vips_foreign_load_tiff_file_header;
load_class->load = vips_foreign_load_tiff_load; load_class->load = vips_foreign_load_tiff_file_load;
VIPS_ARG_STRING( class, "filename", 1, VIPS_ARG_STRING( class, "filename", 1,
_( "Filename" ), _( "Filename" ),
_( "Filename to load from" ), _( "Filename to load from" ),
VIPS_ARGUMENT_REQUIRED_INPUT, VIPS_ARGUMENT_REQUIRED_INPUT,
G_STRUCT_OFFSET( VipsForeignLoadTiff, filename ), G_STRUCT_OFFSET( VipsForeignLoadTiffFile, filename ),
NULL ); NULL );
VIPS_ARG_INT( class, "page", 10,
_( "Page" ),
_( "Load this page from the file" ),
VIPS_ARGUMENT_OPTIONAL_INPUT,
G_STRUCT_OFFSET( VipsForeignLoadTiff, page ),
0, 100000, 0 );
} }
static void static void
vips_foreign_load_tiff_init( VipsForeignLoadTiff *tiff ) vips_foreign_load_tiff_file_init( VipsForeignLoadTiffFile *file )
{
}
typedef struct _VipsForeignLoadTiffBuffer {
VipsForeignLoadTiff parent_object;
/* Load from a buffer.
*/
VipsArea *buf;
} VipsForeignLoadTiffBuffer;
typedef VipsForeignLoadTiffClass VipsForeignLoadTiffBufferClass;
G_DEFINE_TYPE( VipsForeignLoadTiffBuffer, vips_foreign_load_tiff_buffer,
vips_foreign_load_tiff_get_type() );
static int
vips_foreign_load_tiff_buffer_header( VipsForeignLoad *load )
{
VipsForeignLoadTiff *tiff = (VipsForeignLoadTiff *) load;
VipsForeignLoadTiffBuffer *buffer = (VipsForeignLoadTiffBuffer *) load;
if( vips__tiff_read_header_buffer(
buffer->buf->data, buffer->buf->length, load->out,
tiff->page ) )
return( -1 );
return( 0 );
}
static int
vips_foreign_load_tiff_buffer_load( VipsForeignLoad *load )
{
VipsForeignLoadTiff *tiff = (VipsForeignLoadTiff *) load;
VipsForeignLoadTiffBuffer *buffer = (VipsForeignLoadTiffBuffer *) load;
if( vips__tiff_read_buffer(
buffer->buf->data, buffer->buf->length, load->real,
tiff->page,
load->access == VIPS_ACCESS_SEQUENTIAL ) )
return( -1 );
return( 0 );
}
static void
vips_foreign_load_tiff_buffer_class_init(
VipsForeignLoadTiffBufferClass *class )
{
GObjectClass *gobject_class = G_OBJECT_CLASS( class );
VipsObjectClass *object_class = (VipsObjectClass *) class;
VipsForeignLoadClass *load_class = (VipsForeignLoadClass *) class;
gobject_class->set_property = vips_object_set_property;
gobject_class->get_property = vips_object_get_property;
object_class->nickname = "tiffload_buffer";
object_class->description = _( "load tiff from buffer" );
load_class->header = vips_foreign_load_tiff_buffer_header;
load_class->load = vips_foreign_load_tiff_buffer_load;
VIPS_ARG_BOXED( class, "buffer", 1,
_( "Buffer" ),
_( "Buffer to load from" ),
VIPS_ARGUMENT_REQUIRED_INPUT,
G_STRUCT_OFFSET( VipsForeignLoadTiffBuffer, buf ),
VIPS_TYPE_BLOB );
}
static void
vips_foreign_load_tiff_buffer_init( VipsForeignLoadTiffBuffer *buffer )
{ {
} }

View File

@ -397,6 +397,8 @@ typedef enum {
int vips_tiffload( const char *filename, VipsImage **out, ... ) int vips_tiffload( const char *filename, VipsImage **out, ... )
__attribute__((sentinel)); __attribute__((sentinel));
int vips_tiffload_buffer( void *buf, size_t len, VipsImage **out, ... )
__attribute__((sentinel));
int vips_tiffsave( VipsImage *in, const char *filename, ... ) int vips_tiffsave( VipsImage *in, const char *filename, ... )
__attribute__((sentinel)); __attribute__((sentinel));

View File

@ -765,16 +765,13 @@ vips__file_open_write( const char *filename, gboolean text_mode )
char * char *
vips__file_read( FILE *fp, const char *filename, unsigned int *length_out ) vips__file_read( FILE *fp, const char *filename, unsigned int *length_out )
{ {
long len; gint64 len;
size_t read; size_t read;
char *str; char *str;
/* Find length. len = vips_file_length( fileno( fp ) );
*/ if( len > 1024 * 1024 * 1024 ) {
fseek( fp, 0L, 2 ); /* Over a gb? Seems crazy!
len = ftell( fp );
if( len > 20 * 1024 * 1024 ) {
/* Seems crazy!
*/ */
vips_error( "vips__file_read", vips_error( "vips__file_read",
_( "\"%s\" too long" ), filename ); _( "\"%s\" too long" ), filename );