move tiffload to streams
test_descriptors seems to fail now though, odd
This commit is contained in:
parent
fb2ab23e26
commit
226819b8a8
@ -52,6 +52,56 @@
|
|||||||
|
|
||||||
#include "../foreign/pforeign.h"
|
#include "../foreign/pforeign.h"
|
||||||
|
|
||||||
|
#ifdef HAVE_TIFF
|
||||||
|
static gboolean
|
||||||
|
im_istifftiled( const char *filename )
|
||||||
|
{
|
||||||
|
VipsStreamInput *input;
|
||||||
|
gboolean result;
|
||||||
|
|
||||||
|
if( !(input = vips_stream_input_new_from_filename( filename )) )
|
||||||
|
return( FALSE );
|
||||||
|
result = vips__istiff_stream( input );
|
||||||
|
VIPS_UNREF( input );
|
||||||
|
|
||||||
|
return( result );
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
im_tiff_read_header( const char *filename, VipsImage *out,
|
||||||
|
int page, int n, gboolean autorotate )
|
||||||
|
{
|
||||||
|
VipsStreamInput *input;
|
||||||
|
|
||||||
|
if( !(input = vips_stream_input_new_from_filename( filename )) )
|
||||||
|
return( -1 );
|
||||||
|
if( vips__tiff_read_header_stream( input, out, page, n, autorotate ) ) {
|
||||||
|
VIPS_UNREF( input );
|
||||||
|
return( -1 );
|
||||||
|
}
|
||||||
|
VIPS_UNREF( input );
|
||||||
|
|
||||||
|
return( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
im_tiff_read( const char *filename, VipsImage *out,
|
||||||
|
int page, int n, gboolean autorotate )
|
||||||
|
{
|
||||||
|
VipsStreamInput *input;
|
||||||
|
|
||||||
|
if( !(input = vips_stream_input_new_from_filename( filename )) )
|
||||||
|
return( -1 );
|
||||||
|
if( vips__tiff_read_stream( input, out, page, n, autorotate ) ) {
|
||||||
|
VIPS_UNREF( input );
|
||||||
|
return( -1 );
|
||||||
|
}
|
||||||
|
VIPS_UNREF( input );
|
||||||
|
|
||||||
|
return( 0 );
|
||||||
|
}
|
||||||
|
#endif /*HAVE_TIFF*/
|
||||||
|
|
||||||
static int
|
static int
|
||||||
tiff2vips( const char *name, IMAGE *out, gboolean header_only )
|
tiff2vips( const char *name, IMAGE *out, gboolean header_only )
|
||||||
{
|
{
|
||||||
@ -88,18 +138,18 @@ tiff2vips( const char *name, IMAGE *out, gboolean header_only )
|
|||||||
|
|
||||||
if( !header_only &&
|
if( !header_only &&
|
||||||
!seq &&
|
!seq &&
|
||||||
!vips__istifftiled( filename ) &&
|
!im_istifftiled( filename ) &&
|
||||||
out->dtype == VIPS_IMAGE_PARTIAL ) {
|
out->dtype == VIPS_IMAGE_PARTIAL ) {
|
||||||
if( vips__image_wio_output( out ) )
|
if( vips__image_wio_output( out ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( header_only ) {
|
if( header_only ) {
|
||||||
if( vips__tiff_read_header( filename, out, page, 1, FALSE ) )
|
if( im_tiff_read_header( filename, out, page, 1, FALSE ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if( vips__tiff_read( filename, out, page, 1, FALSE ) )
|
if( im_tiff_read( filename, out, page, 1, FALSE ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
@ -2007,6 +2007,7 @@ vips_foreign_operation_init( 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_file_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_load_tiff_buffer_get_type( void );
|
||||||
|
extern GType vips_foreign_load_tiff_stream_get_type( void );
|
||||||
extern GType vips_foreign_save_tiff_file_get_type( void );
|
extern GType vips_foreign_save_tiff_file_get_type( void );
|
||||||
extern GType vips_foreign_save_tiff_buffer_get_type( void );
|
extern GType vips_foreign_save_tiff_buffer_get_type( void );
|
||||||
extern GType vips_foreign_load_vips_get_type( void );
|
extern GType vips_foreign_load_vips_get_type( void );
|
||||||
@ -2135,6 +2136,7 @@ vips_foreign_operation_init( void )
|
|||||||
#ifdef HAVE_TIFF
|
#ifdef HAVE_TIFF
|
||||||
vips_foreign_load_tiff_file_get_type();
|
vips_foreign_load_tiff_file_get_type();
|
||||||
vips_foreign_load_tiff_buffer_get_type();
|
vips_foreign_load_tiff_buffer_get_type();
|
||||||
|
vips_foreign_load_tiff_stream_get_type();
|
||||||
vips_foreign_save_tiff_file_get_type();
|
vips_foreign_save_tiff_file_get_type();
|
||||||
vips_foreign_save_tiff_buffer_get_type();
|
vips_foreign_save_tiff_buffer_get_type();
|
||||||
#endif /*HAVE_TIFF*/
|
#endif /*HAVE_TIFF*/
|
||||||
|
@ -79,22 +79,6 @@ int vips__tiff_write_buf( VipsImage *in,
|
|||||||
VipsRegionShrink region_shrink,
|
VipsRegionShrink region_shrink,
|
||||||
int level, gboolean lossless );
|
int level, gboolean lossless );
|
||||||
|
|
||||||
int vips__tiff_read_header( const char *filename, VipsImage *out,
|
|
||||||
int page, int n, gboolean autorotate );
|
|
||||||
int vips__tiff_read( const char *filename, VipsImage *out,
|
|
||||||
int page, int n, gboolean autorotate );
|
|
||||||
|
|
||||||
gboolean vips__istiff( const char *filename );
|
|
||||||
gboolean vips__istifftiled( const char *filename );
|
|
||||||
|
|
||||||
gboolean vips__istiff_buffer( const void *buf, size_t len );
|
|
||||||
gboolean vips__istifftiled_buffer( const void *buf, size_t len );
|
|
||||||
|
|
||||||
int vips__tiff_read_header_buffer( const void *buf, size_t len, VipsImage *out,
|
|
||||||
int page, int n, gboolean autorotate );
|
|
||||||
int vips__tiff_read_buffer( const void *buf, size_t len, VipsImage *out,
|
|
||||||
int page, int n, gboolean autorotate );
|
|
||||||
|
|
||||||
gboolean vips__istiff_stream( VipsStreamInput *input );
|
gboolean vips__istiff_stream( VipsStreamInput *input );
|
||||||
gboolean vips__istifftiled_stream( VipsStreamInput *input );
|
gboolean vips__istifftiled_stream( VipsStreamInput *input );
|
||||||
int vips__tiff_read_header_stream( VipsStreamInput *input, VipsImage *out,
|
int vips__tiff_read_header_stream( VipsStreamInput *input, VipsImage *out,
|
||||||
|
@ -132,174 +132,6 @@ vips__tiff_openout( const char *path, gboolean bigtiff )
|
|||||||
return( tif );
|
return( tif );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Open TIFF for input from a file.
|
|
||||||
*/
|
|
||||||
TIFF *
|
|
||||||
vips__tiff_openin( const char *path )
|
|
||||||
{
|
|
||||||
/* No mmap --- no performance advantage with libtiff, and it burns up
|
|
||||||
* our VM if the tiff file is large.
|
|
||||||
*/
|
|
||||||
const char *mode = "rm";
|
|
||||||
|
|
||||||
TIFF *tif;
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
printf( "vips__tiff_openin( \"%s\" )\n", path );
|
|
||||||
#endif /*DEBUG*/
|
|
||||||
|
|
||||||
/* Need the utf-16 version on Windows.
|
|
||||||
*/
|
|
||||||
#ifdef OS_WIN32
|
|
||||||
{
|
|
||||||
GError *error = NULL;
|
|
||||||
wchar_t *path16;
|
|
||||||
|
|
||||||
if( !(path16 = (wchar_t *)
|
|
||||||
g_utf8_to_utf16( path, -1, NULL, NULL, &error )) ) {
|
|
||||||
vips_g_error( &error );
|
|
||||||
return( NULL );
|
|
||||||
}
|
|
||||||
|
|
||||||
tif = TIFFOpenW( path16, mode );
|
|
||||||
|
|
||||||
g_free( path16 );
|
|
||||||
}
|
|
||||||
#else /*!OS_WIN32*/
|
|
||||||
tif = TIFFOpen( path, mode );
|
|
||||||
#endif /*OS_WIN32*/
|
|
||||||
|
|
||||||
if( !tif ) {
|
|
||||||
vips_error( "tiff",
|
|
||||||
_( "unable to open \"%s\" for input" ), path );
|
|
||||||
return( NULL );
|
|
||||||
}
|
|
||||||
|
|
||||||
return( tif );
|
|
||||||
}
|
|
||||||
|
|
||||||
/* TIFF input from a memory buffer.
|
|
||||||
*/
|
|
||||||
|
|
||||||
typedef struct _VipsTiffOpeninBuffer {
|
|
||||||
size_t position;
|
|
||||||
const void *data;
|
|
||||||
size_t length;
|
|
||||||
} VipsTiffOpeninBuffer;
|
|
||||||
|
|
||||||
static tsize_t
|
|
||||||
openin_buffer_read( thandle_t st, tdata_t data, tsize_t size )
|
|
||||||
{
|
|
||||||
VipsTiffOpeninBuffer *buffer = (VipsTiffOpeninBuffer *) st;
|
|
||||||
|
|
||||||
size_t available;
|
|
||||||
size_t copied;
|
|
||||||
|
|
||||||
if( buffer->position > buffer->length ) {
|
|
||||||
vips_error( "openin_buffer_read",
|
|
||||||
"%s", _( "read beyond end of buffer" ) );
|
|
||||||
return( 0 );
|
|
||||||
}
|
|
||||||
|
|
||||||
available = buffer->length - buffer->position;
|
|
||||||
copied = VIPS_MIN( size, available );
|
|
||||||
memcpy( data,
|
|
||||||
(unsigned char *) buffer->data + buffer->position, copied );
|
|
||||||
buffer->position += copied;
|
|
||||||
|
|
||||||
return( copied );
|
|
||||||
}
|
|
||||||
|
|
||||||
static tsize_t
|
|
||||||
openin_buffer_write( thandle_t st, tdata_t buffer, tsize_t size )
|
|
||||||
{
|
|
||||||
g_assert_not_reached();
|
|
||||||
|
|
||||||
return( 0 );
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
openin_buffer_close( thandle_t st )
|
|
||||||
{
|
|
||||||
return( 0 );
|
|
||||||
}
|
|
||||||
|
|
||||||
/* After calling this, ->pos is not bound by the size of the buffer, it can
|
|
||||||
* have any positive value.
|
|
||||||
*/
|
|
||||||
static toff_t
|
|
||||||
openin_buffer_seek( thandle_t st, toff_t position, int whence )
|
|
||||||
{
|
|
||||||
VipsTiffOpeninBuffer *buffer = (VipsTiffOpeninBuffer *) st;
|
|
||||||
|
|
||||||
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();
|
|
||||||
|
|
||||||
return( buffer->position );
|
|
||||||
}
|
|
||||||
|
|
||||||
static toff_t
|
|
||||||
openin_buffer_size( thandle_t st )
|
|
||||||
{
|
|
||||||
VipsTiffOpeninBuffer *buffer = (VipsTiffOpeninBuffer *) st;
|
|
||||||
|
|
||||||
return( buffer->length );
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
openin_buffer_map( thandle_t st, tdata_t *start, toff_t *len )
|
|
||||||
{
|
|
||||||
g_assert_not_reached();
|
|
||||||
|
|
||||||
return( 0 );
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
openin_buffer_unmap( thandle_t st, tdata_t start, toff_t len )
|
|
||||||
{
|
|
||||||
g_assert_not_reached();
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
TIFF *
|
|
||||||
vips__tiff_openin_buffer( VipsImage *image, const void *data, size_t length )
|
|
||||||
{
|
|
||||||
VipsTiffOpeninBuffer *buffer;
|
|
||||||
TIFF *tiff;
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
printf( "vips__tiff_openin_buffer:\n" );
|
|
||||||
#endif /*DEBUG*/
|
|
||||||
|
|
||||||
buffer = VIPS_NEW( image, VipsTiffOpeninBuffer );
|
|
||||||
buffer->position = 0;
|
|
||||||
buffer->data = data;
|
|
||||||
buffer->length = length;
|
|
||||||
|
|
||||||
if( !(tiff = TIFFClientOpen( "memory input", "rm",
|
|
||||||
(thandle_t) buffer,
|
|
||||||
openin_buffer_read,
|
|
||||||
openin_buffer_write,
|
|
||||||
openin_buffer_seek,
|
|
||||||
openin_buffer_close,
|
|
||||||
openin_buffer_size,
|
|
||||||
openin_buffer_map,
|
|
||||||
openin_buffer_unmap )) ) {
|
|
||||||
vips_error( "vips__tiff_openin_buffer", "%s",
|
|
||||||
_( "unable to open memory buffer for input" ) );
|
|
||||||
return( NULL );
|
|
||||||
}
|
|
||||||
|
|
||||||
return( tiff );
|
|
||||||
}
|
|
||||||
|
|
||||||
/* TIFF input from a vips stream.
|
/* TIFF input from a vips stream.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -365,18 +197,20 @@ openin_stream_unmap( thandle_t st, tdata_t start, toff_t len )
|
|||||||
}
|
}
|
||||||
|
|
||||||
TIFF *
|
TIFF *
|
||||||
vips__tiff_openin_stream( VipsImage *image, VipsStreamInput *input )
|
vips__tiff_openin_stream( VipsStreamInput *input )
|
||||||
{
|
{
|
||||||
TIFF *tiff;
|
TIFF *tiff;
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printf( "vips__tiff_openin_buffer:\n" );
|
printf( "vips__tiff_openin_stream:\n" );
|
||||||
#endif /*DEBUG*/
|
#endif /*DEBUG*/
|
||||||
|
|
||||||
/* Unreffed on close(), see above.
|
/* Unreffed on close(), see above.
|
||||||
*/
|
*/
|
||||||
g_object_ref( input );
|
if( vips_stream_input_rewind( input ) )
|
||||||
|
return( NULL );
|
||||||
|
|
||||||
|
g_object_ref( input );
|
||||||
if( !(tiff = TIFFClientOpen( "stream input", "rm",
|
if( !(tiff = TIFFClientOpen( "stream input", "rm",
|
||||||
(thandle_t) input,
|
(thandle_t) input,
|
||||||
openin_stream_read,
|
openin_stream_read,
|
||||||
|
@ -37,15 +37,12 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif /*__cplusplus*/
|
#endif /*__cplusplus*/
|
||||||
|
|
||||||
TIFF *vips__tiff_openout( const char *path, gboolean bigtiff );
|
TIFF *vips__tiff_openin_stream( VipsStreamInput *input );
|
||||||
TIFF *vips__tiff_openin( const char *path );
|
|
||||||
|
|
||||||
TIFF *vips__tiff_openin_buffer( VipsImage *image,
|
TIFF *vips__tiff_openout( const char *path, gboolean bigtiff );
|
||||||
const void *data, size_t length );
|
|
||||||
TIFF *vips__tiff_openout_buffer( VipsImage *image,
|
TIFF *vips__tiff_openout_buffer( VipsImage *image,
|
||||||
gboolean bigtiff, void **out_data, size_t *out_length );
|
gboolean bigtiff, void **out_data, size_t *out_length );
|
||||||
|
|
||||||
TIFF *vips__tiff_openin_stream( VipsImage *image, VipsStreamInput *input );
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
@ -189,6 +189,8 @@
|
|||||||
* 7/6/19
|
* 7/6/19
|
||||||
* - istiff reads the first directory rather than just testing the magic
|
* - istiff reads the first directory rather than just testing the magic
|
||||||
* number, so it ignores more TIFF-like, but not TIFF images
|
* number, so it ignores more TIFF-like, but not TIFF images
|
||||||
|
* 17/10/19
|
||||||
|
* - switch to stream input
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -2341,68 +2343,6 @@ rtiff_header_read_all( Rtiff *rtiff )
|
|||||||
return( 0 );
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
static Rtiff *
|
|
||||||
rtiff_new_filename( const char *filename, VipsImage *out,
|
|
||||||
int page, int n, gboolean autorotate )
|
|
||||||
{
|
|
||||||
Rtiff *rtiff;
|
|
||||||
|
|
||||||
if( !(rtiff = rtiff_new( out, page, n, autorotate )) ||
|
|
||||||
!(rtiff->tiff = vips__tiff_openin( filename )) ||
|
|
||||||
rtiff_header_read_all( rtiff ) )
|
|
||||||
return( NULL );
|
|
||||||
|
|
||||||
rtiff->filename = vips_strdup( VIPS_OBJECT( out ), filename );
|
|
||||||
|
|
||||||
return( rtiff );
|
|
||||||
}
|
|
||||||
|
|
||||||
static Rtiff *
|
|
||||||
rtiff_new_buffer( const void *buf, size_t len, VipsImage *out,
|
|
||||||
int page, int n, gboolean autorotate )
|
|
||||||
{
|
|
||||||
Rtiff *rtiff;
|
|
||||||
|
|
||||||
if( !(rtiff = rtiff_new( out, page, n, autorotate )) ||
|
|
||||||
!(rtiff->tiff = vips__tiff_openin_buffer( out, buf, len )) ||
|
|
||||||
rtiff_header_read_all( rtiff ) )
|
|
||||||
return( NULL );
|
|
||||||
|
|
||||||
return( rtiff );
|
|
||||||
}
|
|
||||||
|
|
||||||
/* For istiffpyramid(), see vips_thumbnail_get_tiff_pyramid().
|
|
||||||
*/
|
|
||||||
|
|
||||||
int
|
|
||||||
vips__tiff_read( const char *filename, VipsImage *out,
|
|
||||||
int page, int n, gboolean autorotate )
|
|
||||||
{
|
|
||||||
Rtiff *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 = rtiff_new_filename( filename, out,
|
|
||||||
page, n, autorotate )) )
|
|
||||||
return( -1 );
|
|
||||||
|
|
||||||
if( rtiff->header.tiled ) {
|
|
||||||
if( rtiff_read_tilewise( rtiff, out ) )
|
|
||||||
return( -1 );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if( rtiff_read_stripwise( rtiff, out ) )
|
|
||||||
return( -1 );
|
|
||||||
}
|
|
||||||
|
|
||||||
return( 0 );
|
|
||||||
}
|
|
||||||
|
|
||||||
/* On a header-only read, we can just swap width/height if orientation is 6 or
|
/* On a header-only read, we can just swap width/height if orientation is 6 or
|
||||||
* 8.
|
* 8.
|
||||||
*/
|
*/
|
||||||
@ -2426,186 +2366,17 @@ vips__tiff_read_header_orientation( Rtiff *rtiff, VipsImage *out )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
|
||||||
vips__tiff_read_header( const char *filename, VipsImage *out,
|
|
||||||
int page, int n, gboolean autorotate )
|
|
||||||
{
|
|
||||||
Rtiff *rtiff;
|
|
||||||
|
|
||||||
vips__tiff_init();
|
|
||||||
|
|
||||||
if( !(rtiff =
|
|
||||||
rtiff_new_filename( filename, out, page, n, autorotate )) )
|
|
||||||
return( -1 );
|
|
||||||
|
|
||||||
if( rtiff_set_header( rtiff, out ) )
|
|
||||||
return( -1 );
|
|
||||||
|
|
||||||
vips__tiff_read_header_orientation( rtiff, out );
|
|
||||||
|
|
||||||
/* Just a header read: we can free the tiff read early and save an fd.
|
|
||||||
*/
|
|
||||||
rtiff_free( rtiff );
|
|
||||||
|
|
||||||
return( 0 );
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef gboolean (*TiffPropertyFn)( TIFF *tif );
|
typedef gboolean (*TiffPropertyFn)( TIFF *tif );
|
||||||
|
|
||||||
static gboolean
|
|
||||||
vips__testtiff( const char *filename, TiffPropertyFn fn )
|
|
||||||
{
|
|
||||||
TIFF *tif;
|
|
||||||
gboolean property;
|
|
||||||
|
|
||||||
vips__tiff_init();
|
|
||||||
|
|
||||||
if( !(tif = vips__tiff_openin( filename )) ) {
|
|
||||||
vips_error_clear();
|
|
||||||
return( FALSE );
|
|
||||||
}
|
|
||||||
|
|
||||||
property = fn ? fn( tif ) : TRUE;
|
|
||||||
|
|
||||||
TIFFClose( tif );
|
|
||||||
|
|
||||||
return( property );
|
|
||||||
}
|
|
||||||
|
|
||||||
gboolean
|
|
||||||
vips__testtiff_buffer( const void *buf, size_t len, TiffPropertyFn fn )
|
|
||||||
{
|
|
||||||
VipsImage *im;
|
|
||||||
TIFF *tif;
|
|
||||||
gboolean property;
|
|
||||||
|
|
||||||
vips__tiff_init();
|
|
||||||
|
|
||||||
im = vips_image_new();
|
|
||||||
|
|
||||||
if( !(tif = vips__tiff_openin_buffer( im, buf, len )) ) {
|
|
||||||
g_object_unref( im );
|
|
||||||
vips_error_clear();
|
|
||||||
return( FALSE );
|
|
||||||
}
|
|
||||||
|
|
||||||
property = fn ? fn( tif ) : TRUE;
|
|
||||||
|
|
||||||
TIFFClose( tif );
|
|
||||||
g_object_unref( im );
|
|
||||||
|
|
||||||
return( property );
|
|
||||||
}
|
|
||||||
|
|
||||||
gboolean
|
|
||||||
vips__istifftiled( const char *filename )
|
|
||||||
{
|
|
||||||
return( vips__testtiff( filename, TIFFIsTiled ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
/* We test for TIFF by trying to read the first directory. We could just test
|
|
||||||
* the magic number, but many formats (eg. ARW) use a TIFF-like container and
|
|
||||||
* we don't want to open those with vips tiffload.
|
|
||||||
*/
|
|
||||||
gboolean
|
|
||||||
vips__istiff( const char *filename )
|
|
||||||
{
|
|
||||||
return( vips__testtiff( filename, NULL ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
gboolean
|
|
||||||
vips__istiff_buffer( const void *buf, size_t len )
|
|
||||||
{
|
|
||||||
return( vips__testtiff_buffer( buf, len, NULL ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
vips__tiff_read_header_buffer( const void *buf, size_t len, VipsImage *out,
|
|
||||||
int page, int n, gboolean autorotate )
|
|
||||||
{
|
|
||||||
Rtiff *rtiff;
|
|
||||||
|
|
||||||
vips__tiff_init();
|
|
||||||
|
|
||||||
if( !(rtiff = rtiff_new_buffer( buf, len, out, page, n, autorotate )) )
|
|
||||||
return( -1 );
|
|
||||||
|
|
||||||
if( rtiff_set_header( rtiff, out ) )
|
|
||||||
return( -1 );
|
|
||||||
|
|
||||||
vips__tiff_read_header_orientation( rtiff, out );
|
|
||||||
|
|
||||||
return( 0 );
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
vips__tiff_read_buffer( const void *buf, size_t len,
|
|
||||||
VipsImage *out, int page, int n, gboolean autorotate )
|
|
||||||
{
|
|
||||||
Rtiff *rtiff;
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
printf( "tiff2vips: libtiff version is \"%s\"\n", TIFFGetVersion() );
|
|
||||||
printf( "tiff2vips: libtiff starting for buffer %p\n", buf );
|
|
||||||
#endif /*DEBUG*/
|
|
||||||
|
|
||||||
vips__tiff_init();
|
|
||||||
|
|
||||||
if( !(rtiff = rtiff_new_buffer( buf, len, out, page, n, autorotate )) )
|
|
||||||
return( -1 );
|
|
||||||
|
|
||||||
if( rtiff->header.tiled ) {
|
|
||||||
if( rtiff_read_tilewise( rtiff, out ) )
|
|
||||||
return( -1 );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if( rtiff_read_stripwise( rtiff, out ) )
|
|
||||||
return( -1 );
|
|
||||||
}
|
|
||||||
|
|
||||||
return( 0 );
|
|
||||||
}
|
|
||||||
|
|
||||||
gboolean
|
|
||||||
vips__istifftiled_buffer( const void *buf, size_t len )
|
|
||||||
{
|
|
||||||
VipsImage *im;
|
|
||||||
TIFF *tif;
|
|
||||||
gboolean tiled;
|
|
||||||
|
|
||||||
vips__tiff_init();
|
|
||||||
|
|
||||||
im = vips_image_new();
|
|
||||||
|
|
||||||
if( !(tif = vips__tiff_openin_buffer( im, buf, len )) ) {
|
|
||||||
g_object_unref( im );
|
|
||||||
vips_error_clear();
|
|
||||||
return( FALSE );
|
|
||||||
}
|
|
||||||
|
|
||||||
tiled = TIFFIsTiled( tif );
|
|
||||||
|
|
||||||
TIFFClose( tif );
|
|
||||||
g_object_unref( im );
|
|
||||||
|
|
||||||
return( tiled );
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
vips__testtiff_stream( VipsStreamInput *input, TiffPropertyFn fn )
|
vips__testtiff_stream( VipsStreamInput *input, TiffPropertyFn fn )
|
||||||
{
|
{
|
||||||
VipsImage *im;
|
|
||||||
TIFF *tif;
|
TIFF *tif;
|
||||||
gboolean property;
|
gboolean property;
|
||||||
|
|
||||||
vips__tiff_init();
|
vips__tiff_init();
|
||||||
|
|
||||||
im = vips_image_new();
|
if( !(tif = vips__tiff_openin_stream( input )) ) {
|
||||||
|
|
||||||
if( vips_stream_input_rewind( input ) )
|
|
||||||
return( FALSE );
|
|
||||||
if( !(tif = vips__tiff_openin_stream( im, input )) ) {
|
|
||||||
g_object_unref( im );
|
|
||||||
vips_error_clear();
|
vips_error_clear();
|
||||||
return( FALSE );
|
return( FALSE );
|
||||||
}
|
}
|
||||||
@ -2613,7 +2384,6 @@ vips__testtiff_stream( VipsStreamInput *input, TiffPropertyFn fn )
|
|||||||
property = fn ? fn( tif ) : TRUE;
|
property = fn ? fn( tif ) : TRUE;
|
||||||
|
|
||||||
TIFFClose( tif );
|
TIFFClose( tif );
|
||||||
g_object_unref( im );
|
|
||||||
|
|
||||||
return( property );
|
return( property );
|
||||||
}
|
}
|
||||||
@ -2637,7 +2407,7 @@ rtiff_new_stream( VipsStreamInput *input, VipsImage *out,
|
|||||||
Rtiff *rtiff;
|
Rtiff *rtiff;
|
||||||
|
|
||||||
if( !(rtiff = rtiff_new( out, page, n, autorotate )) ||
|
if( !(rtiff = rtiff_new( out, page, n, autorotate )) ||
|
||||||
!(rtiff->tiff = vips__tiff_openin_stream( out, input )) ||
|
!(rtiff->tiff = vips__tiff_openin_stream( input )) ||
|
||||||
rtiff_header_read_all( rtiff ) )
|
rtiff_header_read_all( rtiff ) )
|
||||||
return( NULL );
|
return( NULL );
|
||||||
|
|
||||||
|
@ -138,17 +138,37 @@ typedef VipsForeignLoadTiffClass VipsForeignLoadTiffFileClass;
|
|||||||
G_DEFINE_TYPE( VipsForeignLoadTiffFile, vips_foreign_load_tiff_file,
|
G_DEFINE_TYPE( VipsForeignLoadTiffFile, vips_foreign_load_tiff_file,
|
||||||
vips_foreign_load_tiff_get_type() );
|
vips_foreign_load_tiff_get_type() );
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
vips_foreign_load_tiff_file_is_a( const char *filename )
|
||||||
|
{
|
||||||
|
VipsStreamInput *input;
|
||||||
|
gboolean result;
|
||||||
|
|
||||||
|
if( !(input = vips_stream_input_new_from_filename( filename )) )
|
||||||
|
return( FALSE );
|
||||||
|
result = vips__istiff_stream( input );
|
||||||
|
VIPS_UNREF( input );
|
||||||
|
|
||||||
|
return( result );
|
||||||
|
}
|
||||||
|
|
||||||
static VipsForeignFlags
|
static VipsForeignFlags
|
||||||
vips_foreign_load_tiff_file_get_flags_filename( const char *filename )
|
vips_foreign_load_tiff_file_get_flags_filename( const char *filename )
|
||||||
{
|
{
|
||||||
|
VipsStreamInput *input;
|
||||||
VipsForeignFlags flags;
|
VipsForeignFlags flags;
|
||||||
|
|
||||||
|
if( !(input = vips_stream_input_new_from_filename( filename )) )
|
||||||
|
return( 0 );
|
||||||
|
|
||||||
flags = 0;
|
flags = 0;
|
||||||
if( vips__istifftiled( filename ) )
|
if( vips__istifftiled_stream( input ) )
|
||||||
flags |= VIPS_FOREIGN_PARTIAL;
|
flags |= VIPS_FOREIGN_PARTIAL;
|
||||||
else
|
else
|
||||||
flags |= VIPS_FOREIGN_SEQUENTIAL;
|
flags |= VIPS_FOREIGN_SEQUENTIAL;
|
||||||
|
|
||||||
|
VIPS_UNREF( input );
|
||||||
|
|
||||||
return( flags );
|
return( flags );
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -167,9 +187,16 @@ vips_foreign_load_tiff_file_header( VipsForeignLoad *load )
|
|||||||
VipsForeignLoadTiff *tiff = (VipsForeignLoadTiff *) load;
|
VipsForeignLoadTiff *tiff = (VipsForeignLoadTiff *) load;
|
||||||
VipsForeignLoadTiffFile *file = (VipsForeignLoadTiffFile *) load;
|
VipsForeignLoadTiffFile *file = (VipsForeignLoadTiffFile *) load;
|
||||||
|
|
||||||
if( vips__tiff_read_header( file->filename, load->out,
|
VipsStreamInput *input;
|
||||||
tiff->page, tiff->n, tiff->autorotate ) )
|
|
||||||
|
if( !(input = vips_stream_input_new_from_filename( file->filename )) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
if( vips__tiff_read_header_stream( input, load->out,
|
||||||
|
tiff->page, tiff->n, tiff->autorotate ) ) {
|
||||||
|
VIPS_UNREF( input );
|
||||||
|
return( -1 );
|
||||||
|
}
|
||||||
|
VIPS_UNREF( input );
|
||||||
|
|
||||||
VIPS_SETSTR( load->out->filename, file->filename );
|
VIPS_SETSTR( load->out->filename, file->filename );
|
||||||
|
|
||||||
@ -182,9 +209,16 @@ vips_foreign_load_tiff_file_load( VipsForeignLoad *load )
|
|||||||
VipsForeignLoadTiff *tiff = (VipsForeignLoadTiff *) load;
|
VipsForeignLoadTiff *tiff = (VipsForeignLoadTiff *) load;
|
||||||
VipsForeignLoadTiffFile *file = (VipsForeignLoadTiffFile *) load;
|
VipsForeignLoadTiffFile *file = (VipsForeignLoadTiffFile *) load;
|
||||||
|
|
||||||
if( vips__tiff_read( file->filename, load->real,
|
VipsStreamInput *input;
|
||||||
tiff->page, tiff->n, tiff->autorotate ) )
|
|
||||||
|
if( !(input = vips_stream_input_new_from_filename( file->filename )) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
if( vips__tiff_read_stream( input, load->real,
|
||||||
|
tiff->page, tiff->n, tiff->autorotate ) ) {
|
||||||
|
VIPS_UNREF( input );
|
||||||
|
return( -1 );
|
||||||
|
}
|
||||||
|
VIPS_UNREF( input );
|
||||||
|
|
||||||
return( 0 );
|
return( 0 );
|
||||||
}
|
}
|
||||||
@ -211,7 +245,7 @@ vips_foreign_load_tiff_file_class_init( VipsForeignLoadTiffFileClass *class )
|
|||||||
|
|
||||||
foreign_class->suffs = vips__foreign_tiff_suffs;
|
foreign_class->suffs = vips__foreign_tiff_suffs;
|
||||||
|
|
||||||
load_class->is_a = vips__istiff;
|
load_class->is_a = vips_foreign_load_tiff_file_is_a;
|
||||||
load_class->get_flags_filename =
|
load_class->get_flags_filename =
|
||||||
vips_foreign_load_tiff_file_get_flags_filename;
|
vips_foreign_load_tiff_file_get_flags_filename;
|
||||||
load_class->get_flags = vips_foreign_load_tiff_file_get_flags;
|
load_class->get_flags = vips_foreign_load_tiff_file_get_flags;
|
||||||
@ -245,18 +279,37 @@ typedef VipsForeignLoadTiffClass VipsForeignLoadTiffBufferClass;
|
|||||||
G_DEFINE_TYPE( VipsForeignLoadTiffBuffer, vips_foreign_load_tiff_buffer,
|
G_DEFINE_TYPE( VipsForeignLoadTiffBuffer, vips_foreign_load_tiff_buffer,
|
||||||
vips_foreign_load_tiff_get_type() );
|
vips_foreign_load_tiff_get_type() );
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
vips_foreign_load_tiff_buffer_is_a_buffer( const void *buf, size_t len )
|
||||||
|
{
|
||||||
|
VipsStreamInput *input;
|
||||||
|
gboolean result;
|
||||||
|
|
||||||
|
if( !(input = vips_stream_input_new_from_memory( buf, len )) )
|
||||||
|
return( FALSE );
|
||||||
|
result = vips__istiff_stream( input );
|
||||||
|
VIPS_UNREF( input );
|
||||||
|
|
||||||
|
return( result );
|
||||||
|
}
|
||||||
|
|
||||||
static VipsForeignFlags
|
static VipsForeignFlags
|
||||||
vips_foreign_load_tiff_buffer_get_flags( VipsForeignLoad *load )
|
vips_foreign_load_tiff_buffer_get_flags( VipsForeignLoad *load )
|
||||||
{
|
{
|
||||||
VipsForeignLoadTiffBuffer *buffer = (VipsForeignLoadTiffBuffer *) load;
|
VipsForeignLoadTiffBuffer *buffer = (VipsForeignLoadTiffBuffer *) load;
|
||||||
|
|
||||||
|
VipsStreamInput *input;
|
||||||
VipsForeignFlags flags;
|
VipsForeignFlags flags;
|
||||||
|
|
||||||
|
if( !(input = vips_stream_input_new_from_memory(
|
||||||
|
buffer->buf->data, buffer->buf->length )) )
|
||||||
|
return( FALSE );
|
||||||
flags = 0;
|
flags = 0;
|
||||||
if( vips__istifftiled_buffer( buffer->buf->data, buffer->buf->length ) )
|
if( vips__istifftiled_stream( input ) )
|
||||||
flags |= VIPS_FOREIGN_PARTIAL;
|
flags |= VIPS_FOREIGN_PARTIAL;
|
||||||
else
|
else
|
||||||
flags |= VIPS_FOREIGN_SEQUENTIAL;
|
flags |= VIPS_FOREIGN_SEQUENTIAL;
|
||||||
|
VIPS_UNREF( input );
|
||||||
|
|
||||||
return( flags );
|
return( flags );
|
||||||
}
|
}
|
||||||
@ -267,10 +320,17 @@ vips_foreign_load_tiff_buffer_header( VipsForeignLoad *load )
|
|||||||
VipsForeignLoadTiff *tiff = (VipsForeignLoadTiff *) load;
|
VipsForeignLoadTiff *tiff = (VipsForeignLoadTiff *) load;
|
||||||
VipsForeignLoadTiffBuffer *buffer = (VipsForeignLoadTiffBuffer *) load;
|
VipsForeignLoadTiffBuffer *buffer = (VipsForeignLoadTiffBuffer *) load;
|
||||||
|
|
||||||
if( vips__tiff_read_header_buffer(
|
VipsStreamInput *input;
|
||||||
buffer->buf->data, buffer->buf->length, load->out,
|
|
||||||
tiff->page, tiff->n, tiff->autorotate ) )
|
if( !(input = vips_stream_input_new_from_memory(
|
||||||
|
buffer->buf->data, buffer->buf->length )) )
|
||||||
|
return( FALSE );
|
||||||
|
if( vips__tiff_read_header_stream( input, load->out,
|
||||||
|
tiff->page, tiff->n, tiff->autorotate ) ) {
|
||||||
|
VIPS_UNREF( input );
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
}
|
||||||
|
VIPS_UNREF( input );
|
||||||
|
|
||||||
return( 0 );
|
return( 0 );
|
||||||
}
|
}
|
||||||
@ -281,10 +341,17 @@ vips_foreign_load_tiff_buffer_load( VipsForeignLoad *load )
|
|||||||
VipsForeignLoadTiff *tiff = (VipsForeignLoadTiff *) load;
|
VipsForeignLoadTiff *tiff = (VipsForeignLoadTiff *) load;
|
||||||
VipsForeignLoadTiffBuffer *buffer = (VipsForeignLoadTiffBuffer *) load;
|
VipsForeignLoadTiffBuffer *buffer = (VipsForeignLoadTiffBuffer *) load;
|
||||||
|
|
||||||
if( vips__tiff_read_buffer(
|
VipsStreamInput *input;
|
||||||
buffer->buf->data, buffer->buf->length, load->real,
|
|
||||||
tiff->page, tiff->n, tiff->autorotate ) )
|
if( !(input = vips_stream_input_new_from_memory(
|
||||||
|
buffer->buf->data, buffer->buf->length )) )
|
||||||
|
return( FALSE );
|
||||||
|
if( vips__tiff_read_stream( input, load->real,
|
||||||
|
tiff->page, tiff->n, tiff->autorotate ) ) {
|
||||||
|
VIPS_UNREF( input );
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
}
|
||||||
|
VIPS_UNREF( input );
|
||||||
|
|
||||||
return( 0 );
|
return( 0 );
|
||||||
}
|
}
|
||||||
@ -303,7 +370,7 @@ vips_foreign_load_tiff_buffer_class_init(
|
|||||||
object_class->nickname = "tiffload_buffer";
|
object_class->nickname = "tiffload_buffer";
|
||||||
object_class->description = _( "load tiff from buffer" );
|
object_class->description = _( "load tiff from buffer" );
|
||||||
|
|
||||||
load_class->is_a_buffer = vips__istiff_buffer;
|
load_class->is_a_buffer = vips_foreign_load_tiff_buffer_is_a_buffer;
|
||||||
load_class->get_flags = vips_foreign_load_tiff_buffer_get_flags;
|
load_class->get_flags = vips_foreign_load_tiff_buffer_get_flags;
|
||||||
load_class->header = vips_foreign_load_tiff_buffer_header;
|
load_class->header = vips_foreign_load_tiff_buffer_header;
|
||||||
load_class->load = vips_foreign_load_tiff_buffer_load;
|
load_class->load = vips_foreign_load_tiff_buffer_load;
|
||||||
@ -321,6 +388,96 @@ vips_foreign_load_tiff_buffer_init( VipsForeignLoadTiffBuffer *buffer )
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct _VipsForeignLoadTiffStream {
|
||||||
|
VipsForeignLoadTiff parent_object;
|
||||||
|
|
||||||
|
/* Load from a stream.
|
||||||
|
*/
|
||||||
|
VipsStreamInput *input;
|
||||||
|
|
||||||
|
} VipsForeignLoadTiffStream;
|
||||||
|
|
||||||
|
typedef VipsForeignLoadTiffClass VipsForeignLoadTiffStreamClass;
|
||||||
|
|
||||||
|
G_DEFINE_TYPE( VipsForeignLoadTiffStream, vips_foreign_load_tiff_stream,
|
||||||
|
vips_foreign_load_tiff_get_type() );
|
||||||
|
|
||||||
|
static VipsForeignFlags
|
||||||
|
vips_foreign_load_tiff_stream_get_flags( VipsForeignLoad *load )
|
||||||
|
{
|
||||||
|
VipsForeignLoadTiffStream *stream = (VipsForeignLoadTiffStream *) load;
|
||||||
|
|
||||||
|
VipsForeignFlags flags;
|
||||||
|
|
||||||
|
flags = 0;
|
||||||
|
if( vips__istifftiled_stream( stream->input ) )
|
||||||
|
flags |= VIPS_FOREIGN_PARTIAL;
|
||||||
|
else
|
||||||
|
flags |= VIPS_FOREIGN_SEQUENTIAL;
|
||||||
|
|
||||||
|
return( flags );
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
vips_foreign_load_tiff_stream_header( VipsForeignLoad *load )
|
||||||
|
{
|
||||||
|
VipsForeignLoadTiff *tiff = (VipsForeignLoadTiff *) load;
|
||||||
|
VipsForeignLoadTiffStream *stream = (VipsForeignLoadTiffStream *) load;
|
||||||
|
|
||||||
|
if( vips__tiff_read_header_stream( stream->input, load->out,
|
||||||
|
tiff->page, tiff->n, tiff->autorotate ) )
|
||||||
|
return( -1 );
|
||||||
|
|
||||||
|
return( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
vips_foreign_load_tiff_stream_load( VipsForeignLoad *load )
|
||||||
|
{
|
||||||
|
VipsForeignLoadTiff *tiff = (VipsForeignLoadTiff *) load;
|
||||||
|
VipsForeignLoadTiffStream *stream = (VipsForeignLoadTiffStream *) load;
|
||||||
|
|
||||||
|
if( vips__tiff_read_stream( stream->input, load->real,
|
||||||
|
tiff->page, tiff->n, tiff->autorotate ) )
|
||||||
|
return( -1 );
|
||||||
|
|
||||||
|
return( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
vips_foreign_load_tiff_stream_class_init(
|
||||||
|
VipsForeignLoadTiffStreamClass *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_stream";
|
||||||
|
object_class->description = _( "load tiff from stream" );
|
||||||
|
|
||||||
|
load_class->is_a_stream = vips__istiff_stream;
|
||||||
|
load_class->get_flags = vips_foreign_load_tiff_stream_get_flags;
|
||||||
|
load_class->header = vips_foreign_load_tiff_stream_header;
|
||||||
|
load_class->load = vips_foreign_load_tiff_stream_load;
|
||||||
|
|
||||||
|
VIPS_ARG_OBJECT( class, "input", 1,
|
||||||
|
_( "Input" ),
|
||||||
|
_( "Stream to load from" ),
|
||||||
|
VIPS_ARGUMENT_REQUIRED_INPUT,
|
||||||
|
G_STRUCT_OFFSET( VipsForeignLoadTiffStream, input ),
|
||||||
|
VIPS_TYPE_STREAM_INPUT );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
vips_foreign_load_tiff_stream_init( VipsForeignLoadTiffStream *stream )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif /*HAVE_TIFF*/
|
#endif /*HAVE_TIFF*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -426,3 +583,35 @@ vips_tiffload_buffer( void *buf, size_t len, VipsImage **out, ... )
|
|||||||
|
|
||||||
return( result );
|
return( result );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* vips_tiffload_stream:
|
||||||
|
* @input: stream to load
|
||||||
|
* @out: (out): image to write
|
||||||
|
* @...: %NULL-terminated list of optional named arguments
|
||||||
|
*
|
||||||
|
* Optional arguments:
|
||||||
|
*
|
||||||
|
* * @page: %gint, load this page
|
||||||
|
* * @n: %gint, load this many pages
|
||||||
|
* * @autorotate: %gboolean, use orientation tag to rotate the image
|
||||||
|
* during load
|
||||||
|
*
|
||||||
|
* Exactly as vips_tiffload(), but read from a stream.
|
||||||
|
*
|
||||||
|
* See also: vips_tiffload().
|
||||||
|
*
|
||||||
|
* Returns: 0 on success, -1 on error.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
vips_tiffload_stream( VipsStreamInput *input, VipsImage **out, ... )
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
int result;
|
||||||
|
|
||||||
|
va_start( ap, out );
|
||||||
|
result = vips_call_split( "tiffload_stream", ap, input, out );
|
||||||
|
va_end( ap );
|
||||||
|
|
||||||
|
return( result );
|
||||||
|
}
|
||||||
|
@ -1713,6 +1713,7 @@ wtiff_gather( Wtiff *wtiff )
|
|||||||
wtiff->layer->below )
|
wtiff->layer->below )
|
||||||
for( layer = wtiff->layer->below; layer;
|
for( layer = wtiff->layer->below; layer;
|
||||||
layer = layer->below ) {
|
layer = layer->below ) {
|
||||||
|
VipsStreamInput *input;
|
||||||
TIFF *in;
|
TIFF *in;
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
@ -1720,15 +1721,23 @@ wtiff_gather( Wtiff *wtiff )
|
|||||||
#endif /*DEBUG*/
|
#endif /*DEBUG*/
|
||||||
|
|
||||||
if( layer->lname ) {
|
if( layer->lname ) {
|
||||||
if( !(in = vips__tiff_openin( layer->lname )) )
|
if( !(input =
|
||||||
|
vips_stream_input_new_from_filename(
|
||||||
|
layer->lname )) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if( !(in = vips__tiff_openin_buffer( wtiff->im,
|
if( !(input = vips_stream_input_new_from_memory(
|
||||||
layer->buf, layer->len )) )
|
layer->buf, layer->len )) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( !(in = vips__tiff_openin_stream( input )) ) {
|
||||||
|
VIPS_UNREF( input );
|
||||||
|
return( -1 );
|
||||||
|
}
|
||||||
|
VIPS_UNREF( input );
|
||||||
|
|
||||||
if( wtiff_copy_tiff( wtiff, wtiff->layer->tif, in ) ) {
|
if( wtiff_copy_tiff( wtiff, wtiff->layer->tif, in ) ) {
|
||||||
TIFFClose( in );
|
TIFFClose( in );
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
@ -481,6 +481,8 @@ int vips_tiffload( const char *filename, VipsImage **out, ... )
|
|||||||
__attribute__((sentinel));
|
__attribute__((sentinel));
|
||||||
int vips_tiffload_buffer( void *buf, size_t len, VipsImage **out, ... )
|
int vips_tiffload_buffer( void *buf, size_t len, VipsImage **out, ... )
|
||||||
__attribute__((sentinel));
|
__attribute__((sentinel));
|
||||||
|
int vips_tiffload_stream( VipsStreamInput *input, VipsImage **out, ... )
|
||||||
|
__attribute__((sentinel));
|
||||||
int vips_tiffsave( VipsImage *in, const char *filename, ... )
|
int vips_tiffsave( VipsImage *in, const char *filename, ... )
|
||||||
__attribute__((sentinel));
|
__attribute__((sentinel));
|
||||||
int vips_tiffsave_buffer( VipsImage *in, void **buf, size_t *len, ... )
|
int vips_tiffsave_buffer( VipsImage *in, void **buf, size_t *len, ... )
|
||||||
|
Loading…
Reference in New Issue
Block a user