add subifd select to tiff load
This commit is contained in:
parent
9e4b78215e
commit
dc29f8dde6
@ -76,7 +76,7 @@ im_tiff_read_header( const char *filename, VipsImage *out,
|
||||
if( !(source = vips_source_new_from_file( filename )) )
|
||||
return( -1 );
|
||||
if( vips__tiff_read_header_source( source,
|
||||
out, page, n, autorotate ) ) {
|
||||
out, page, n, autorotate, -1 ) ) {
|
||||
VIPS_UNREF( source );
|
||||
return( -1 );
|
||||
}
|
||||
@ -93,7 +93,7 @@ im_tiff_read( const char *filename, VipsImage *out,
|
||||
|
||||
if( !(source = vips_source_new_from_file( filename )) )
|
||||
return( -1 );
|
||||
if( vips__tiff_read_source( source, out, page, n, autorotate ) ) {
|
||||
if( vips__tiff_read_source( source, out, page, n, autorotate, -1 ) ) {
|
||||
VIPS_UNREF( source );
|
||||
return( -1 );
|
||||
}
|
||||
|
@ -88,9 +88,9 @@ int vips__tiff_write_buf( VipsImage *in,
|
||||
gboolean vips__istiff_source( VipsSource *source );
|
||||
gboolean vips__istifftiled_source( VipsSource *source );
|
||||
int vips__tiff_read_header_source( VipsSource *source, VipsImage *out,
|
||||
int page, int n, gboolean autorotate );
|
||||
int page, int n, gboolean autorotate, int subifd );
|
||||
int vips__tiff_read_source( VipsSource *source, VipsImage *out,
|
||||
int page, int n, gboolean autorotate );
|
||||
int page, int n, gboolean autorotate, int subifd );
|
||||
|
||||
extern const char *vips__foreign_tiff_suffs[];
|
||||
|
||||
|
@ -197,6 +197,8 @@
|
||||
* - read logluv images as XYZ
|
||||
* 11/4/20 petoor
|
||||
* - better handling of aligned reads in multipage tiffs
|
||||
* 28/5/20
|
||||
* - add subifd
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -320,6 +322,7 @@ typedef struct _Rtiff {
|
||||
int page;
|
||||
int n;
|
||||
gboolean autorotate;
|
||||
int subifd;
|
||||
|
||||
/* The TIFF we read.
|
||||
*/
|
||||
@ -527,7 +530,7 @@ rtiff_minimise_cb( VipsImage *image, Rtiff *rtiff )
|
||||
|
||||
static Rtiff *
|
||||
rtiff_new( VipsSource *source, VipsImage *out,
|
||||
int page, int n, gboolean autorotate )
|
||||
int page, int n, gboolean autorotate, int subifd )
|
||||
{
|
||||
Rtiff *rtiff;
|
||||
|
||||
@ -540,6 +543,7 @@ rtiff_new( VipsSource *source, VipsImage *out,
|
||||
rtiff->page = page;
|
||||
rtiff->n = n;
|
||||
rtiff->autorotate = autorotate;
|
||||
rtiff->subifd = subifd;
|
||||
rtiff->tiff = NULL;
|
||||
rtiff->n_pages = 0;
|
||||
rtiff->current_page = -1;
|
||||
@ -608,7 +612,8 @@ rtiff_set_page( Rtiff *rtiff, int page )
|
||||
{
|
||||
if( rtiff->current_page != page ) {
|
||||
#ifdef DEBUG
|
||||
printf( "rtiff_set_page: selecting page %d\n", page );
|
||||
printf( "rtiff_set_page: selecting page %d, subifd %d\n",
|
||||
page, rtiff->subifd );
|
||||
#endif /*DEBUG*/
|
||||
|
||||
if( !TIFFSetDirectory( rtiff->tiff, page ) ) {
|
||||
@ -617,6 +622,35 @@ rtiff_set_page( Rtiff *rtiff, int page )
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
if( rtiff->subifd >= 0 ) {
|
||||
int subifd_count;
|
||||
toff_t *subifd_offsets;
|
||||
|
||||
if( !TIFFGetField( rtiff->tiff, TIFFTAG_SUBIFD,
|
||||
&subifd_count, &subifd_offsets ) ) {
|
||||
vips_error( "tiff2vips",
|
||||
"%s", _( "no SUBIFD tag" ) );
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
if( subifd_count <= 0 ||
|
||||
rtiff->subifd >= subifd_count ) {
|
||||
vips_error( "tiff2vips",
|
||||
_( "subifd %d out of range, "
|
||||
"only %d available" ),
|
||||
rtiff->subifd,
|
||||
subifd_count );
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
if( !TIFFSetSubDirectory( rtiff->tiff,
|
||||
subifd_offsets[rtiff->subifd] ) ) {
|
||||
vips_error( "tiff2vips",
|
||||
"%s", _( "subdirectory unreadable" ) );
|
||||
return( -1 );
|
||||
}
|
||||
}
|
||||
|
||||
rtiff->current_page = page;
|
||||
}
|
||||
|
||||
@ -2646,13 +2680,13 @@ vips__istifftiled_source( VipsSource *source )
|
||||
|
||||
int
|
||||
vips__tiff_read_header_source( VipsSource *source, VipsImage *out,
|
||||
int page, int n, gboolean autorotate )
|
||||
int page, int n, gboolean autorotate, int subifd )
|
||||
{
|
||||
Rtiff *rtiff;
|
||||
|
||||
vips__tiff_init();
|
||||
|
||||
if( !(rtiff = rtiff_new( source, out, page, n, autorotate )) ||
|
||||
if( !(rtiff = rtiff_new( source, out, page, n, autorotate, subifd )) ||
|
||||
rtiff_header_read_all( rtiff ) )
|
||||
return( -1 );
|
||||
|
||||
@ -2671,7 +2705,7 @@ vips__tiff_read_header_source( VipsSource *source, VipsImage *out,
|
||||
|
||||
int
|
||||
vips__tiff_read_source( VipsSource *source, VipsImage *out,
|
||||
int page, int n, gboolean autorotate )
|
||||
int page, int n, gboolean autorotate, int subifd )
|
||||
{
|
||||
Rtiff *rtiff;
|
||||
|
||||
@ -2681,7 +2715,7 @@ vips__tiff_read_source( VipsSource *source, VipsImage *out,
|
||||
|
||||
vips__tiff_init();
|
||||
|
||||
if( !(rtiff = rtiff_new( source, out, page, n, autorotate )) ||
|
||||
if( !(rtiff = rtiff_new( source, out, page, n, autorotate, subifd )) ||
|
||||
rtiff_header_read_all( rtiff ) )
|
||||
return( -1 );
|
||||
|
||||
|
@ -69,6 +69,10 @@ typedef struct _VipsForeignLoadTiff {
|
||||
*/
|
||||
int n;
|
||||
|
||||
/* Select subifd index. -1 for main image.
|
||||
*/
|
||||
int subifd;
|
||||
|
||||
/* Autorotate using orientation tag.
|
||||
*/
|
||||
gboolean autorotate;
|
||||
@ -133,7 +137,7 @@ vips_foreign_load_tiff_header( VipsForeignLoad *load )
|
||||
VipsForeignLoadTiff *tiff = (VipsForeignLoadTiff *) load;
|
||||
|
||||
if( vips__tiff_read_header_source( tiff->source, load->out,
|
||||
tiff->page, tiff->n, tiff->autorotate ) )
|
||||
tiff->page, tiff->n, tiff->autorotate, tiff->subifd ) )
|
||||
return( -1 );
|
||||
|
||||
return( 0 );
|
||||
@ -145,7 +149,7 @@ vips_foreign_load_tiff_load( VipsForeignLoad *load )
|
||||
VipsForeignLoadTiff *tiff = (VipsForeignLoadTiff *) load;
|
||||
|
||||
if( vips__tiff_read_source( tiff->source, load->real,
|
||||
tiff->page, tiff->n, tiff->autorotate ) )
|
||||
tiff->page, tiff->n, tiff->autorotate, tiff->subifd ) )
|
||||
return( -1 );
|
||||
|
||||
return( 0 );
|
||||
@ -203,6 +207,14 @@ vips_foreign_load_tiff_class_init( VipsForeignLoadTiffClass *class )
|
||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||
G_STRUCT_OFFSET( VipsForeignLoadTiff, autorotate ),
|
||||
FALSE );
|
||||
|
||||
VIPS_ARG_INT( class, "subifd", 21,
|
||||
_( "subifd" ),
|
||||
_( "Select subifd index" ),
|
||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||
G_STRUCT_OFFSET( VipsForeignLoadTiff, subifd ),
|
||||
-1, 100000, -1 );
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
@ -210,6 +222,7 @@ vips_foreign_load_tiff_init( VipsForeignLoadTiff *tiff )
|
||||
{
|
||||
tiff->page = 0;
|
||||
tiff->n = 1;
|
||||
tiff->subifd = -1;
|
||||
}
|
||||
|
||||
typedef struct _VipsForeignLoadTiffSource {
|
||||
@ -454,6 +467,7 @@ vips_foreign_load_tiff_buffer_init( VipsForeignLoadTiffBuffer *buffer )
|
||||
* * @n: %gint, load this many pages
|
||||
* * @autorotate: %gboolean, use orientation tag to rotate the image
|
||||
* during load
|
||||
* * @subifd: %gint, select this subifd index
|
||||
*
|
||||
* Read a TIFF file into a VIPS image. It is a full baseline TIFF 6 reader,
|
||||
* with extensions for tiled images, multipage images, XYZ and LAB colour
|
||||
@ -478,6 +492,14 @@ vips_foreign_load_tiff_buffer_init( VipsForeignLoadTiffBuffer *buffer )
|
||||
* operations will use #VIPS_META_ORIENTATION, if present, to set the
|
||||
* orientation of output images.
|
||||
*
|
||||
* If @autorotate is TRUE, the image will be rotated upright during load and
|
||||
* no metadata attached. This can be very slow.
|
||||
*
|
||||
* If @subifd is -1 (the default), the main image is selected for each page.
|
||||
* If it is 0 or greater and there is a SUBIFD tag, the indexed SUBIFD is
|
||||
* selected. This can be used to read lower resolution layers from
|
||||
* bioformats-style image pyramids.
|
||||
*
|
||||
* Any ICC profile is read and attached to the VIPS image as
|
||||
* #VIPS_META_ICC_NAME. Any XMP metadata is read and attached to the image
|
||||
* as #VIPS_META_XMP_NAME. Any IPTC is attached as #VIPS_META_IPTC_NAME. The
|
||||
@ -515,6 +537,7 @@ vips_tiffload( const char *filename, VipsImage **out, ... )
|
||||
* * @n: %gint, load this many pages
|
||||
* * @autorotate: %gboolean, use orientation tag to rotate the image
|
||||
* during load
|
||||
* * @subifd: %gint, select this subifd index
|
||||
*
|
||||
* Read a TIFF-formatted memory block into a VIPS image. Exactly as
|
||||
* vips_tiffload(), but read from a memory source.
|
||||
@ -558,6 +581,7 @@ vips_tiffload_buffer( void *buf, size_t len, VipsImage **out, ... )
|
||||
* * @n: %gint, load this many pages
|
||||
* * @autorotate: %gboolean, use orientation tag to rotate the image
|
||||
* during load
|
||||
* * @subifd: %gint, select this subifd index
|
||||
*
|
||||
* Exactly as vips_tiffload(), but read from a source.
|
||||
*
|
||||
|
Loading…
Reference in New Issue
Block a user