add @thumbnail support to heifload
This commit is contained in:
parent
50a955e357
commit
6a75536619
@ -32,9 +32,9 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
#define DEBUG
|
|
||||||
#define VIPS_DEBUG
|
#define VIPS_DEBUG
|
||||||
*/
|
*/
|
||||||
|
#define DEBUG
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
@ -68,6 +68,11 @@ typedef struct _VipsForeignLoadHeif {
|
|||||||
*/
|
*/
|
||||||
gboolean autorotate;
|
gboolean autorotate;
|
||||||
|
|
||||||
|
/* Fetch the thumbnail instead of the image. If there is no thumbnail,
|
||||||
|
* just fetch the image.
|
||||||
|
*/
|
||||||
|
gboolean thumbnail;
|
||||||
|
|
||||||
/* Context for this image.
|
/* Context for this image.
|
||||||
*/
|
*/
|
||||||
struct heif_context *ctx;
|
struct heif_context *ctx;
|
||||||
@ -90,6 +95,11 @@ typedef struct _VipsForeignLoadHeif {
|
|||||||
*/
|
*/
|
||||||
int page_no;
|
int page_no;
|
||||||
|
|
||||||
|
/* TRUE if @handle has selected the thumbnail rather than the main
|
||||||
|
* image.
|
||||||
|
*/
|
||||||
|
gboolean thumbnail_set;
|
||||||
|
|
||||||
/* The page number of the primary image.
|
/* The page number of the primary image.
|
||||||
*/
|
*/
|
||||||
int primary_page;
|
int primary_page;
|
||||||
@ -180,16 +190,22 @@ vips_foreign_load_heif_get_flags( VipsForeignLoad *load )
|
|||||||
return( VIPS_FOREIGN_SEQUENTIAL );
|
return( VIPS_FOREIGN_SEQUENTIAL );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Select a page. If thumbnail is set, select the thumbnail for that page, if
|
||||||
|
* there is one.
|
||||||
|
*/
|
||||||
static int
|
static int
|
||||||
vips_foreign_load_heif_set_page( VipsForeignLoadHeif *heif, int page_no )
|
vips_foreign_load_heif_set_page( VipsForeignLoadHeif *heif,
|
||||||
|
int page_no, gboolean thumbnail )
|
||||||
{
|
{
|
||||||
if( !heif->handle ||
|
if( !heif->handle ||
|
||||||
page_no != heif->page_no ) {
|
page_no != heif->page_no ||
|
||||||
|
thumbnail != heif->thumbnail_set ) {
|
||||||
struct heif_error error;
|
struct heif_error error;
|
||||||
|
|
||||||
VIPS_FREEF( heif_image_handle_release, heif->handle );
|
VIPS_FREEF( heif_image_handle_release, heif->handle );
|
||||||
VIPS_FREEF( heif_image_release, heif->img );
|
VIPS_FREEF( heif_image_release, heif->img );
|
||||||
heif->data = NULL;
|
heif->data = NULL;
|
||||||
|
heif->thumbnail_set = FALSE;
|
||||||
|
|
||||||
error = heif_context_get_image_handle( heif->ctx,
|
error = heif_context_get_image_handle( heif->ctx,
|
||||||
heif->id[page_no], &heif->handle );
|
heif->id[page_no], &heif->handle );
|
||||||
@ -198,6 +214,30 @@ vips_foreign_load_heif_set_page( VipsForeignLoadHeif *heif, int page_no )
|
|||||||
return( -1 );
|
return( -1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( thumbnail ) {
|
||||||
|
heif_item_id thumb_ids[1];
|
||||||
|
int n_thumbs;
|
||||||
|
struct heif_image_handle *thumb_handle;
|
||||||
|
|
||||||
|
n_thumbs = heif_image_handle_get_list_of_thumbnail_IDs(
|
||||||
|
heif->handle, thumb_ids, 1 );
|
||||||
|
|
||||||
|
if( n_thumbs > 0 ) {
|
||||||
|
error = heif_image_handle_get_thumbnail(
|
||||||
|
heif->handle,
|
||||||
|
thumb_ids[0], &thumb_handle );
|
||||||
|
if( error.code ) {
|
||||||
|
vips__heif_error( &error );
|
||||||
|
return( -1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
VIPS_FREEF( heif_image_handle_release,
|
||||||
|
heif->handle );
|
||||||
|
heif->handle = thumb_handle;
|
||||||
|
heif->thumbnail_set = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
heif->page_no = page_no;
|
heif->page_no = page_no;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -387,14 +427,53 @@ vips_foreign_load_heif_header( VipsForeignLoad *load )
|
|||||||
return( -1 );
|
return( -1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
for( i = heif->page; i < heif->page + heif->n; i++ ) {
|
||||||
|
heif_item_id thumb_ids[1];
|
||||||
|
int n_items;
|
||||||
|
int n_thumbs;
|
||||||
|
int j;
|
||||||
|
|
||||||
|
if( vips_foreign_load_heif_set_page( heif, i, FALSE ) )
|
||||||
|
return( -1 );
|
||||||
|
|
||||||
|
n_thumbs = heif_image_handle_get_number_of_thumbnails(
|
||||||
|
heif->handle );
|
||||||
|
n_items = heif_image_handle_get_list_of_thumbnail_IDs(
|
||||||
|
heif->handle, thumb_ids, 1 );
|
||||||
|
|
||||||
|
printf( "page = %d\n", i );
|
||||||
|
printf( "n_thumbs = %d\n", n_thumbs );
|
||||||
|
printf( "n_items = %d\n", n_items );
|
||||||
|
|
||||||
|
for( j = 0; j < n_items; j++ ) {
|
||||||
|
struct heif_image_handle *thumb_handle;
|
||||||
|
|
||||||
|
error = heif_image_handle_get_thumbnail( heif->handle,
|
||||||
|
thumb_ids[j], &thumb_handle );
|
||||||
|
if( error.code ) {
|
||||||
|
vips__heif_error( &error );
|
||||||
|
return( -1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
printf( " thumb %d\n", j );
|
||||||
|
printf( " width = %d\n",
|
||||||
|
heif_image_handle_get_width( thumb_handle ) );
|
||||||
|
printf( " height = %d\n",
|
||||||
|
heif_image_handle_get_height( thumb_handle ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /*DEBUG*/
|
||||||
|
|
||||||
/* All pages must be the same size for libvips toilet roll images.
|
/* All pages must be the same size for libvips toilet roll images.
|
||||||
*/
|
*/
|
||||||
if( vips_foreign_load_heif_set_page( heif, heif->page ) )
|
if( vips_foreign_load_heif_set_page( heif, heif->page, heif->thumbnail ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
heif->page_width = heif_image_handle_get_width( heif->handle );
|
heif->page_width = heif_image_handle_get_width( heif->handle );
|
||||||
heif->page_height = heif_image_handle_get_height( heif->handle );
|
heif->page_height = heif_image_handle_get_height( heif->handle );
|
||||||
for( i = heif->page + 1; i < heif->page + heif->n; i++ ) {
|
for( i = heif->page + 1; i < heif->page + heif->n; i++ ) {
|
||||||
if( vips_foreign_load_heif_set_page( heif, i ) )
|
if( vips_foreign_load_heif_set_page( heif,
|
||||||
|
i, heif->thumbnail ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
if( heif_image_handle_get_width( heif->handle ) !=
|
if( heif_image_handle_get_width( heif->handle ) !=
|
||||||
heif->page_width ||
|
heif->page_width ||
|
||||||
@ -410,7 +489,7 @@ vips_foreign_load_heif_header( VipsForeignLoad *load )
|
|||||||
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] );
|
||||||
if( vips_foreign_load_heif_set_page( heif, i ) )
|
if( vips_foreign_load_heif_set_page( heif, i, FALSE ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
printf( " width = %d\n",
|
printf( " width = %d\n",
|
||||||
heif_image_handle_get_width( heif->handle ) );
|
heif_image_handle_get_width( heif->handle ) );
|
||||||
@ -450,7 +529,7 @@ vips_foreign_load_heif_generate( VipsRegion *or,
|
|||||||
|
|
||||||
g_assert( r->height == 1 );
|
g_assert( r->height == 1 );
|
||||||
|
|
||||||
if( vips_foreign_load_heif_set_page( heif, page ) )
|
if( vips_foreign_load_heif_set_page( heif, page, heif->thumbnail ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
if( !heif->img ) {
|
if( !heif->img ) {
|
||||||
@ -552,6 +631,13 @@ vips_foreign_load_heif_class_init( VipsForeignLoadHeifClass *class )
|
|||||||
G_STRUCT_OFFSET( VipsForeignLoadHeif, autorotate ),
|
G_STRUCT_OFFSET( VipsForeignLoadHeif, autorotate ),
|
||||||
FALSE );
|
FALSE );
|
||||||
|
|
||||||
|
VIPS_ARG_BOOL( class, "thumbnail", 4,
|
||||||
|
_( "Thumbnail" ),
|
||||||
|
_( "Fetch thumbnail image" ),
|
||||||
|
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||||
|
G_STRUCT_OFFSET( VipsForeignLoadHeif, thumbnail ),
|
||||||
|
FALSE );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
Loading…
Reference in New Issue
Block a user