heifload: add unlimited option, default to false (#2677)

This commit is contained in:
Lovell Fuller 2022-02-23 10:34:07 +00:00 committed by GitHub
parent 1e4cd2d5c2
commit 4ca4b07654
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 45 additions and 1 deletions

View File

@ -938,6 +938,18 @@ if test x"$with_heif" = x"yes"; then
LIBS="$save_LIBS"
fi
# heif_context_set_maximum_image_size_limit added in 1.6.0
if test x"$with_heif" = x"yes"; then
save_LIBS="$LIBS"
LIBS="$LIBS $HEIF_LIBS"
AC_CHECK_FUNCS(heif_context_set_maximum_image_size_limit,[
AC_DEFINE(HAVE_HEIF_SET_MAX_IMAGE_SIZE_LIMIT,1,
[define if you have heif_context_set_maximum_image_size_limit.])
],[]
)
LIBS="$save_LIBS"
fi
# heif_main_brand added in 1.4.0, but heif_avif appeared in 1.7 ... just check
# the libheif version number since testing for enums is annoying
if test x"$with_heif" = x"yes"; then

View File

@ -2119,6 +2119,7 @@ vips_foreign_find_save_buffer( const char *name )
* * @page: %gint, page (top-level image number) to read
* * @n: %gint, load this many pages
* * @thumbnail: %gboolean, fetch thumbnail instead of image
* * @unlimited: %gboolean, remove all denial of service limits
*
* Read a HEIF image file into a VIPS image.
*
@ -2135,6 +2136,9 @@ vips_foreign_find_save_buffer( const char *name )
* If @thumbnail is %TRUE, then fetch a stored thumbnail rather than the
* image.
*
* By default, input image dimensions are limited to 16384x16384.
* If @unlimited is %TRUE, this increases to the maximum of 65535x65535.
*
* The bitdepth of the heic image is recorded in the metadata item
* `heif-bitdepth`.
*
@ -2167,6 +2171,7 @@ vips_heifload( const char *filename, VipsImage **out, ... )
* * @page: %gint, page (top-level image number) to read
* * @n: %gint, load this many pages
* * @thumbnail: %gboolean, fetch thumbnail instead of image
* * @unlimited: %gboolean, remove all denial of service limits
*
* Read a HEIF image file into a VIPS image.
* Exactly as vips_heifload(), but read from a memory buffer.
@ -2209,6 +2214,7 @@ vips_heifload_buffer( void *buf, size_t len, VipsImage **out, ... )
* * @page: %gint, page (top-level image number) to read
* * @n: %gint, load this many pages
* * @thumbnail: %gboolean, fetch thumbnail instead of image
* * @unlimited: %gboolean, remove all denial of service limits
*
* Exactly as vips_heifload(), but read from a source.
*

View File

@ -139,6 +139,10 @@ typedef struct _VipsForeignLoadHeif {
*/
gboolean autorotate;
/* remove all denial of service limits.
*/
gboolean unlimited;
/* Context for this image.
*/
struct heif_context *ctx;
@ -257,6 +261,10 @@ vips_foreign_load_heif_build( VipsObject *object )
struct heif_error error;
heif->ctx = heif_context_alloc();
#ifdef HAVE_HEIF_SET_MAX_IMAGE_SIZE_LIMIT
heif_context_set_maximum_image_size_limit( heif->ctx,
heif->unlimited ? USHRT_MAX : 0x4000 );
#endif /* HAVE_HEIF_SET_MAX_IMAGE_SIZE_LIMIT */
error = heif_context_read_from_reader( heif->ctx,
heif->reader, heif, NULL );
if( error.code ) {
@ -1081,6 +1089,12 @@ vips_foreign_load_heif_class_init( VipsForeignLoadHeifClass *class )
G_STRUCT_OFFSET( VipsForeignLoadHeif, autorotate ),
FALSE );
VIPS_ARG_BOOL( class, "unlimited", 22,
_( "Unlimited" ),
_( "Remove all denial of service limits" ),
VIPS_ARGUMENT_OPTIONAL_INPUT,
G_STRUCT_OFFSET( VipsForeignLoadHeif, unlimited ),
FALSE );
}
static gint64

View File

@ -407,6 +407,9 @@ if libheif_dep.found()
if cc.has_member('struct heif_decoding_options', 'convert_hdr_to_8bit', prefix: '#include <libheif/heif.h>', dependencies: libheif_dep)
cfg_var.set('HAVE_HEIF_DECODING_OPTIONS_CONVERT_HDR_TO_8BIT', '1')
endif
if cc.has_function('heif_context_set_maximum_image_size_limit', prefix: '#include <libheif/heif.h>', dependencies: libheif_dep)
cfg_var.set('HAVE_HEIF_SET_MAX_IMAGE_SIZE_LIMIT', '1')
endif
# heif_main_brand added in 1.4.0, but heif_avif appeared in 1.7 ... just check
# the libheif version number since testing for enums is annoying
if libheif_dep.version().version_compare('>=1.7.0')

View File

@ -44,6 +44,7 @@ ICO_FILE = os.path.join(IMAGES, "favicon.ico")
TGA_FILE = os.path.join(IMAGES, "targa.tga")
SGI_FILE = os.path.join(IMAGES, "silicongraphics.sgi")
AVIF_FILE = os.path.join(IMAGES, "avif-orientation-6.avif")
AVIF_FILE_HUGE = os.path.join(IMAGES, "16x17000.avif")
HEIC_FILE = os.path.join(IMAGES, "heic-orientation-6.heic")
RGBA_FILE = os.path.join(IMAGES, "rgba.png")
RGBA_CORRECT_FILE = os.path.join(IMAGES, "rgba-correct.ppm")

Binary file not shown.

View File

@ -10,7 +10,8 @@ from helpers import \
JPEG_FILE, SRGB_FILE, MATLAB_FILE, PNG_FILE, TIF_FILE, OME_FILE, \
ANALYZE_FILE, GIF_FILE, WEBP_FILE, EXR_FILE, FITS_FILE, OPENSLIDE_FILE, \
PDF_FILE, SVG_FILE, SVGZ_FILE, SVG_GZ_FILE, GIF_ANIM_FILE, DICOM_FILE, \
BMP_FILE, NIFTI_FILE, ICO_FILE, TGA_FILE, SGI_FILE, AVIF_FILE, TRUNCATED_FILE, \
BMP_FILE, NIFTI_FILE, ICO_FILE, TGA_FILE, SGI_FILE, AVIF_FILE, \
AVIF_FILE_HUGE, TRUNCATED_FILE, \
GIF_ANIM_EXPECTED_PNG_FILE, GIF_ANIM_DISPOSE_BACKGROUND_FILE, \
GIF_ANIM_DISPOSE_BACKGROUND_EXPECTED_PNG_FILE, \
GIF_ANIM_DISPOSE_PREVIOUS_FILE, \
@ -1173,6 +1174,13 @@ class TestForeign:
self.file_loader("heifload", AVIF_FILE, heif_valid)
self.buffer_loader("heifload_buffer", AVIF_FILE, heif_valid)
with pytest.raises(Exception) as e_info:
im = pyvips.Image.heifload(AVIF_FILE_HUGE)
assert im.avg() == 0.0
im = pyvips.Image.heifload(AVIF_FILE_HUGE, unlimited=True)
assert im.avg() == 0.0
@skip_if_no("heifsave")
@pytest.mark.skipif(sys.platform == "darwin", reason="fails with latest libheif/aom from Homebrew")
def test_avifsave(self):