try to work around some broken heic images

see https://github.com/libvips/libvips/issues/1574
This commit is contained in:
John Cupitt 2020-07-31 17:41:23 +01:00
parent 95a221dd6e
commit 80abdce923
1 changed files with 69 additions and 20 deletions

View File

@ -18,6 +18,8 @@
* - revise for new VipsSource API
* 10/5/20
* - deprecate autorotate -- it's too difficult to support properly
* 31/7/20
* - block broken thumbnails, if we can
*/
/*
@ -277,6 +279,71 @@ vips_foreign_load_heif_get_flags( VipsForeignLoad *load )
return( VIPS_FOREIGN_SEQUENTIAL );
}
/* We've selcted the page. Try to select the associated thumbnail instead,
* if we can.
*/
static int
vips_foreign_load_heif_set_thumbnail( VipsForeignLoadHeif *heif )
{
double main_aspect;
double thumb_aspect;
heif_item_id thumb_ids[1];
int n_thumbs;
struct heif_image_handle *thumb_handle;
struct heif_image *thumb_img;
struct heif_error error;
/* We need the main image aspect ratio so we can sanity-check
* the thumbnail.
*/
main_aspect = (double)
heif_image_handle_get_width( heif->handle ) /
heif_image_handle_get_height( heif->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 );
}
/* Just checking the width and height of the handle isn't
* enough -- we have to decode it and test the decoded
* dimensions.
*/
error = heif_decode_image( thumb_handle, &thumb_img,
heif_colorspace_RGB,
heif_chroma_interleaved_RGB,
NULL );
if( error.code ) {
vips__heif_error( &error );
return( -1 );
}
thumb_aspect = (double)
heif_image_get_width( thumb_img,
heif_channel_interleaved ) /
heif_image_get_height( thumb_img,
heif_channel_interleaved );
VIPS_FREEF( heif_image_release, thumb_img );
if( fabs( main_aspect - thumb_aspect ) < 0.1 ) {
VIPS_FREEF( heif_image_handle_release, heif->handle );
heif->handle = thumb_handle;
}
else {
VIPS_FREEF( heif_image_handle_release, thumb_handle );
}
}
return( 0 );
}
/* Select a page. If thumbnail is set, select the thumbnail for that page, if
* there is one.
*/
@ -307,26 +374,8 @@ vips_foreign_load_heif_set_page( VipsForeignLoadHeif *heif,
}
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;
}
if( vips_foreign_load_heif_set_thumbnail( heif ) )
return( -1 );
/* If we were asked to select the thumbnail, say we
* did, even if there are no thumbnails and we just