start adding read many page support
but it's not easy ... we'll need to be very strict about every page being identical if we want to share readers
This commit is contained in:
parent
92c549e995
commit
3ef6a4695a
4
TODO
4
TODO
@ -1,3 +1,7 @@
|
||||
- all toilet roll loaders need to set "page-height"
|
||||
|
||||
magick, pdf and tiff need to use the same page/n interface
|
||||
|
||||
- not sure about utf8 error messages on win
|
||||
|
||||
- strange:
|
||||
|
@ -94,11 +94,11 @@ tiff2vips( const char *name, IMAGE *out, gboolean header_only )
|
||||
}
|
||||
|
||||
if( header_only ) {
|
||||
if( vips__tiff_read_header( filename, out, page, FALSE ) )
|
||||
if( vips__tiff_read_header( filename, out, page, 1, FALSE ) )
|
||||
return( -1 );
|
||||
}
|
||||
else {
|
||||
if( vips__tiff_read( filename, out, page, FALSE, TRUE ) )
|
||||
if( vips__tiff_read( filename, out, page, 1, FALSE, TRUE ) )
|
||||
return( -1 );
|
||||
}
|
||||
#else
|
||||
|
@ -66,17 +66,17 @@ int vips__tiff_write_buf( VipsImage *in,
|
||||
gboolean properties, gboolean strip );
|
||||
|
||||
int vips__tiff_read_header( const char *filename, VipsImage *out,
|
||||
int page, gboolean autorotate );
|
||||
int page, int n, gboolean autorotate );
|
||||
int vips__tiff_read( const char *filename, VipsImage *out,
|
||||
int page, gboolean autorotate, gboolean readbehind );
|
||||
int page, int n, gboolean autorotate, gboolean readbehind );
|
||||
gboolean vips__istifftiled( const char *filename );
|
||||
gboolean vips__istiff_buffer( const void *buf, size_t len );
|
||||
gboolean vips__istiff( const char *filename );
|
||||
|
||||
int vips__tiff_read_header_buffer( const void *buf, size_t len, VipsImage *out,
|
||||
int page, gboolean autorotate );
|
||||
int page, int n, gboolean autorotate );
|
||||
int vips__tiff_read_buffer( const void *buf, size_t len, VipsImage *out,
|
||||
int page, gboolean autorotate, gboolean readbehind );
|
||||
int page, int n, gboolean autorotate, gboolean readbehind );
|
||||
|
||||
extern const char *vips__foreign_tiff_suffs[];
|
||||
|
||||
|
@ -1787,9 +1787,21 @@ readtiff_close( VipsObject *object, ReadTiff *rtiff )
|
||||
readtiff_free( rtiff );
|
||||
}
|
||||
|
||||
static int
|
||||
readtiff_set_directory( ReadTiff *rtiff, int page )
|
||||
{
|
||||
if( !TIFFSetDirectory( rtiff->tiff, page ) ) {
|
||||
vips_error( "tiff2vips",
|
||||
_( "TIFF does not contain page %d" ), rtiff->page );
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
static ReadTiff *
|
||||
readtiff_new( VipsImage *out,
|
||||
int page, gboolean autorotate, gboolean readbehind )
|
||||
int page, int n, gboolean autorotate, gboolean readbehind )
|
||||
{
|
||||
ReadTiff *rtiff;
|
||||
|
||||
@ -1824,25 +1836,13 @@ readtiff_new( VipsImage *out,
|
||||
return( rtiff );
|
||||
}
|
||||
|
||||
static int
|
||||
readtiff_set_directory( ReadTiff *rtiff, int page )
|
||||
{
|
||||
if( !TIFFSetDirectory( rtiff->tiff, page ) ) {
|
||||
vips_error( "tiff2vips",
|
||||
_( "TIFF does not contain page %d" ), rtiff->page );
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
static ReadTiff *
|
||||
readtiff_new_filename( const char *filename, VipsImage *out,
|
||||
int page, gboolean autorotate, gboolean readbehind )
|
||||
int page, int n, gboolean autorotate, gboolean readbehind )
|
||||
{
|
||||
ReadTiff *rtiff;
|
||||
|
||||
if( !(rtiff = readtiff_new( out, page, autorotate, readbehind )) ||
|
||||
if( !(rtiff = readtiff_new( out, page, n, autorotate, readbehind )) ||
|
||||
!(rtiff->tiff = vips__tiff_openin( filename )) ||
|
||||
readtiff_set_directory( rtiff, page ) )
|
||||
return( NULL );
|
||||
@ -1854,11 +1854,11 @@ readtiff_new_filename( const char *filename, VipsImage *out,
|
||||
|
||||
static ReadTiff *
|
||||
readtiff_new_buffer( const void *buf, size_t len, VipsImage *out,
|
||||
int page, gboolean autorotate, gboolean readbehind )
|
||||
int page, int n, gboolean autorotate, gboolean readbehind )
|
||||
{
|
||||
ReadTiff *rtiff;
|
||||
|
||||
if( !(rtiff = readtiff_new( out, page, autorotate, readbehind )) ||
|
||||
if( !(rtiff = readtiff_new( out, page, n, autorotate, readbehind )) ||
|
||||
!(rtiff->tiff = vips__tiff_openin_buffer( out, buf, len )) ||
|
||||
readtiff_set_directory( rtiff, page ) )
|
||||
return( NULL );
|
||||
@ -1889,7 +1889,7 @@ istiffpyramid( const char *name )
|
||||
|
||||
int
|
||||
vips__tiff_read( const char *filename, VipsImage *out,
|
||||
int page, gboolean autorotate, gboolean readbehind )
|
||||
int page, int n, gboolean autorotate, gboolean readbehind )
|
||||
{
|
||||
ReadTiff *rtiff;
|
||||
|
||||
@ -1901,7 +1901,7 @@ vips__tiff_read( const char *filename, VipsImage *out,
|
||||
vips__tiff_init();
|
||||
|
||||
if( !(rtiff = readtiff_new_filename( filename,
|
||||
out, page, autorotate, readbehind )) )
|
||||
out, page, n, autorotate, readbehind )) )
|
||||
return( -1 );
|
||||
|
||||
if( TIFFIsTiled( rtiff->tiff ) ) {
|
||||
@ -1941,14 +1941,14 @@ vips__tiff_read_header_orientation( ReadTiff *rtiff, VipsImage *out )
|
||||
|
||||
int
|
||||
vips__tiff_read_header( const char *filename, VipsImage *out,
|
||||
int page, gboolean autorotate )
|
||||
int page, int n, gboolean autorotate )
|
||||
{
|
||||
ReadTiff *rtiff;
|
||||
|
||||
vips__tiff_init();
|
||||
|
||||
if( !(rtiff = readtiff_new_filename( filename, out,
|
||||
page, autorotate, FALSE )) )
|
||||
page, n, autorotate, FALSE )) )
|
||||
return( -1 );
|
||||
|
||||
if( parse_header( rtiff, out ) )
|
||||
@ -2010,14 +2010,14 @@ vips__istiff( const char *filename )
|
||||
|
||||
int
|
||||
vips__tiff_read_header_buffer( const void *buf, size_t len, VipsImage *out,
|
||||
int page, gboolean autorotate )
|
||||
int page, int n, gboolean autorotate )
|
||||
{
|
||||
ReadTiff *rtiff;
|
||||
|
||||
vips__tiff_init();
|
||||
|
||||
if( !(rtiff = readtiff_new_buffer( buf, len, out,
|
||||
page, autorotate, FALSE )) )
|
||||
page, n, autorotate, FALSE )) )
|
||||
return( -1 );
|
||||
|
||||
if( parse_header( rtiff, out ) )
|
||||
@ -2030,7 +2030,8 @@ vips__tiff_read_header_buffer( const void *buf, size_t len, VipsImage *out,
|
||||
|
||||
int
|
||||
vips__tiff_read_buffer( const void *buf, size_t len,
|
||||
VipsImage *out, int page, gboolean autorotate, gboolean readbehind )
|
||||
VipsImage *out, int page, int n, gboolean autorotate,
|
||||
gboolean readbehind )
|
||||
{
|
||||
ReadTiff *rtiff;
|
||||
|
||||
@ -2042,7 +2043,7 @@ vips__tiff_read_buffer( const void *buf, size_t len,
|
||||
vips__tiff_init();
|
||||
|
||||
if( !(rtiff = readtiff_new_buffer( buf, len, out,
|
||||
page, autorotate, readbehind )) )
|
||||
page, n, autorotate, readbehind )) )
|
||||
return( -1 );
|
||||
|
||||
if( TIFFIsTiled( rtiff->tiff ) ) {
|
||||
|
@ -59,6 +59,10 @@ typedef struct _VipsForeignLoadTiff {
|
||||
*/
|
||||
int page;
|
||||
|
||||
/* Load this many pages.
|
||||
*/
|
||||
int n;
|
||||
|
||||
/* Autorotate using orientation tag.
|
||||
*/
|
||||
gboolean autorotate;
|
||||
@ -96,7 +100,14 @@ vips_foreign_load_tiff_class_init( VipsForeignLoadTiffClass *class )
|
||||
G_STRUCT_OFFSET( VipsForeignLoadTiff, page ),
|
||||
0, 100000, 0 );
|
||||
|
||||
VIPS_ARG_BOOL( class, "autorotate", 11,
|
||||
VIPS_ARG_INT( class, "n", 11,
|
||||
_( "n" ),
|
||||
_( "Load this many pages" ),
|
||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||
G_STRUCT_OFFSET( VipsForeignLoadTiff, n ),
|
||||
-1, 100000, 1 );
|
||||
|
||||
VIPS_ARG_BOOL( class, "autorotate", 12,
|
||||
_( "Autorotate" ),
|
||||
_( "Rotate image using orientation tag" ),
|
||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||
@ -108,6 +119,7 @@ static void
|
||||
vips_foreign_load_tiff_init( VipsForeignLoadTiff *tiff )
|
||||
{
|
||||
tiff->page = 0;
|
||||
tiff->n = 1;
|
||||
}
|
||||
|
||||
typedef struct _VipsForeignLoadTiffFile {
|
||||
@ -154,7 +166,7 @@ vips_foreign_load_tiff_file_header( VipsForeignLoad *load )
|
||||
VipsForeignLoadTiffFile *file = (VipsForeignLoadTiffFile *) load;
|
||||
|
||||
if( vips__tiff_read_header( file->filename, load->out,
|
||||
tiff->page, tiff->autorotate ) )
|
||||
tiff->page, tiff->n, tiff->autorotate ) )
|
||||
return( -1 );
|
||||
|
||||
VIPS_SETSTR( load->out->filename, file->filename );
|
||||
@ -168,8 +180,9 @@ vips_foreign_load_tiff_file_load( VipsForeignLoad *load )
|
||||
VipsForeignLoadTiff *tiff = (VipsForeignLoadTiff *) load;
|
||||
VipsForeignLoadTiffFile *file = (VipsForeignLoadTiffFile *) load;
|
||||
|
||||
if( vips__tiff_read( file->filename, load->real, tiff->page,
|
||||
tiff->autorotate, load->access == VIPS_ACCESS_SEQUENTIAL ) )
|
||||
if( vips__tiff_read( file->filename, load->real,
|
||||
tiff->page, tiff->n, tiff->autorotate,
|
||||
load->access == VIPS_ACCESS_SEQUENTIAL ) )
|
||||
return( -1 );
|
||||
|
||||
return( 0 );
|
||||
@ -239,7 +252,7 @@ vips_foreign_load_tiff_buffer_header( VipsForeignLoad *load )
|
||||
|
||||
if( vips__tiff_read_header_buffer(
|
||||
buffer->buf->data, buffer->buf->length, load->out,
|
||||
tiff->page, tiff->autorotate ) )
|
||||
tiff->page, tiff->n, tiff->autorotate ) )
|
||||
return( -1 );
|
||||
|
||||
return( 0 );
|
||||
@ -253,7 +266,7 @@ vips_foreign_load_tiff_buffer_load( VipsForeignLoad *load )
|
||||
|
||||
if( vips__tiff_read_buffer(
|
||||
buffer->buf->data, buffer->buf->length, load->real,
|
||||
tiff->page, tiff->autorotate,
|
||||
tiff->page, tiff->n, tiff->autorotate,
|
||||
load->access == VIPS_ACCESS_SEQUENTIAL ) )
|
||||
return( -1 );
|
||||
|
||||
@ -302,6 +315,7 @@ vips_foreign_load_tiff_buffer_init( VipsForeignLoadTiffBuffer *buffer )
|
||||
* Optional arguments:
|
||||
*
|
||||
* * @page: %gint, load this page
|
||||
* * @n: %gint, load this many pages
|
||||
* * @autorotate: %gboolean, use orientation tag to rotate the image
|
||||
* during load
|
||||
*
|
||||
@ -310,7 +324,12 @@ vips_foreign_load_tiff_buffer_init( VipsForeignLoadTiffBuffer *buffer )
|
||||
* pyramidal images and JPEG compression. including CMYK and YCbCr.
|
||||
*
|
||||
* @page means load this page from the file. By default the first page (page
|
||||
* 0) is read.
|
||||
* 0) is read.
|
||||
*
|
||||
* @n means load this many pages. By default a single page is read. All the
|
||||
* pages must have the same dimensions, and they are loaded as a tall, thin
|
||||
* "toilet roll" image. The "page-height" metadata tag gives the height in
|
||||
* pixels of each page. Use -1 to load all pages.
|
||||
*
|
||||
* Setting @autorotate to %TRUE will make the loader interpret the
|
||||
* orientation tag and automatically rotate the image appropriately during
|
||||
@ -357,6 +376,7 @@ vips_tiffload( const char *filename, VipsImage **out, ... )
|
||||
* Optional arguments:
|
||||
*
|
||||
* * @page: %gint, load this page
|
||||
* * @n: %gint, load this many pages
|
||||
* * @autorotate: %gboolean, use orientation tag to rotate the image
|
||||
* during load
|
||||
*
|
||||
|
Loading…
Reference in New Issue
Block a user