start adding multipage input

This commit is contained in:
John Cupitt 2019-01-24 19:01:55 +00:00
parent 086f1b2ba8
commit d75b007191

View File

@ -62,6 +62,11 @@ typedef struct _VipsForeignLoadHeif {
*/ */
char *filename; char *filename;
/* Pages to load.
*/
int page;
int n;
/* Context for this file. /* Context for this file.
*/ */
struct heif_context *ctx; struct heif_context *ctx;
@ -70,6 +75,11 @@ typedef struct _VipsForeignLoadHeif {
*/ */
int n_top; int n_top;
/* Size of each frame.
*/
int frame_width;
int frame_height;
/* Array of top-level image IDs. /* Array of top-level image IDs.
*/ */
heif_item_id *id; heif_item_id *id;
@ -302,6 +312,8 @@ vips_foreign_load_heif_header( VipsForeignLoad *load )
struct heif_error error; struct heif_error error;
heif_item_id id; heif_item_id id;
int i; int i;
int frame_width;
int frame_height;
error = heif_context_read_from_file( heif->ctx, heif->filename, NULL ); error = heif_context_read_from_file( heif->ctx, heif->filename, NULL );
if( error.code ) { if( error.code ) {
@ -310,10 +322,40 @@ vips_foreign_load_heif_header( VipsForeignLoad *load )
} }
heif->n_top = heif_context_get_number_of_top_level_images( heif->ctx ); heif->n_top = heif_context_get_number_of_top_level_images( heif->ctx );
vips_image_set_int( out, "n-pages", heif->n_top );
heif->id = VIPS_ARRAY( NULL, heif->n_top, heif_item_id ); heif->id = VIPS_ARRAY( NULL, heif->n_top, heif_item_id );
heif_context_get_list_of_top_level_image_IDs( heif->ctx, heif_context_get_list_of_top_level_image_IDs( heif->ctx,
heif->id, heif->n_top ); heif->id, heif->n_top );
if( heif->n == -1 )
heif->n = heif->n_top - heif->page;
if( heif->page < 0 ||
heif->n <= 0 ||
heif->page + heif->n > heif->n_top ) {
vips_error( class->nickname, "%s", _( "bad page number" ) );
return( -1 );
}
/* All pages must be the same size for libvips toilet roll images.
*/
if( vips_foreign_load_heif_set_handle( heif, heif->id[heif->page] ) )
return( -1 );
heif->frame_width = heif_image_handle_get_width( heif->handle );
heif->frame_height = heif_image_handle_get_height( heif->handle );
vips_image_set_int( out, "page-height", heif->frame_height );
for( i = heif->page + 1; i < heif->page + heif->n; i++ ) {
if( vips_foreign_load_heif_set_handle( heif, heif->id[i] ) )
return( -1 );
if( heif_image_handle_get_width( heif->handle ) !=
heif->frame_width ||
heif_image_handle_get_height( heif->handle ) !=
heif->frame_height ) {
vips_error( class->nickname, "%s",
_( "not all frames are the same size" ) );
return( -1 );
}
}
printf( "n_top = %d\n", heif->n_top ); printf( "n_top = %d\n", heif->n_top );
for( i = 0; i < heif->n_top; i++ ) { for( i = 0; i < heif->n_top; i++ ) {
printf( " id[%d] = %d\n", i, heif->id[i] ); printf( " id[%d] = %d\n", i, heif->id[i] );
@ -449,12 +491,27 @@ vips_foreign_load_heif_class_init( VipsForeignLoadHeifClass *class )
VIPS_ARGUMENT_REQUIRED_INPUT, VIPS_ARGUMENT_REQUIRED_INPUT,
G_STRUCT_OFFSET( VipsForeignLoadHeif, filename ), G_STRUCT_OFFSET( VipsForeignLoadHeif, filename ),
NULL ); NULL );
VIPS_ARG_INT( class, "page", 2,
_( "Page" ),
_( "Load this page from the file" ),
VIPS_ARGUMENT_OPTIONAL_INPUT,
G_STRUCT_OFFSET( VipsForeignLoadHeif, page ),
0, 100000, 0 );
VIPS_ARG_INT( class, "n", 3,
_( "n" ),
_( "Load this many pages" ),
VIPS_ARGUMENT_OPTIONAL_INPUT,
G_STRUCT_OFFSET( VipsForeignLoadHeif, n ),
-1, 100000, 1 );
} }
static void static void
vips_foreign_load_heif_init( VipsForeignLoadHeif *heif ) vips_foreign_load_heif_init( VipsForeignLoadHeif *heif )
{ {
heif->ctx = heif_context_alloc(); heif->ctx = heif_context_alloc();
heif->n = 1;
} }
#endif /*HAVE_HEIF*/ #endif /*HAVE_HEIF*/
@ -465,8 +522,19 @@ vips_foreign_load_heif_init( VipsForeignLoadHeif *heif )
* @out: (out): decompressed image * @out: (out): decompressed image
* @...: %NULL-terminated list of optional named arguments * @...: %NULL-terminated list of optional named arguments
* *
* Optional arguments:
*
* * @page: %gint, page (top-level image number) to read
* * @n: %gint, load this many pages
*
* Read a HEIF image file into a VIPS image. * Read a HEIF image file into a VIPS image.
* *
* Use @page to select a page to render, numbering from zero.
*
* Use @n to select the number of pages to render. The default is 1. Pages are
* rendered in a vertical column. Set to -1 to mean "until the end of the
* document". Use vips_grid() to reorganise pages.
*
* See also: vips_image_new_from_file(). * See also: vips_image_new_from_file().
* *
* Returns: 0 on success, -1 on error. * Returns: 0 on success, -1 on error.