remove autorotate from libheif
not possible to support this properly with current libheif
This commit is contained in:
parent
f209870e7b
commit
3010a4a865
@ -33,9 +33,9 @@
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
#define DEBUG_VERBOSE
|
#define DEBUG_VERBOSE
|
||||||
*/
|
|
||||||
#define VIPS_DEBUG
|
#define VIPS_DEBUG
|
||||||
#define DEBUG
|
#define DEBUG
|
||||||
|
*/
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
@ -56,6 +56,17 @@
|
|||||||
|
|
||||||
#include "pforeign.h"
|
#include "pforeign.h"
|
||||||
|
|
||||||
|
/* FIXME ... autorotate
|
||||||
|
*
|
||||||
|
* This is very hard to support properly with libheif. There's a thing to
|
||||||
|
* disable autorot on decode, but the dimensions you get from querying the
|
||||||
|
* image handle sometimes do and sometimes don't apply this rotation for you,
|
||||||
|
* depending on the image. And the only way to discover if an image has an
|
||||||
|
* orientation is to query the exif, which is not reliable.
|
||||||
|
*
|
||||||
|
* Perhaps we'll be able to support this in a future libheif.
|
||||||
|
*/
|
||||||
|
|
||||||
typedef struct _VipsForeignLoadHeif {
|
typedef struct _VipsForeignLoadHeif {
|
||||||
VipsForeignLoad parent_object;
|
VipsForeignLoad parent_object;
|
||||||
|
|
||||||
@ -64,11 +75,6 @@ typedef struct _VipsForeignLoadHeif {
|
|||||||
int page;
|
int page;
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
/* Set to apply image transforms (flip, rotate, crop) stored in the file
|
|
||||||
* header.
|
|
||||||
*/
|
|
||||||
gboolean autorotate;
|
|
||||||
|
|
||||||
/* Fetch the thumbnail instead of the image. If there is no thumbnail,
|
/* Fetch the thumbnail instead of the image. If there is no thumbnail,
|
||||||
* just fetch the image.
|
* just fetch the image.
|
||||||
*/
|
*/
|
||||||
@ -260,9 +266,6 @@ vips_foreign_load_heif_set_header( VipsForeignLoadHeif *heif, VipsImage *out )
|
|||||||
heif_item_id id[16];
|
heif_item_id id[16];
|
||||||
int n_metadata;
|
int n_metadata;
|
||||||
struct heif_error error;
|
struct heif_error error;
|
||||||
VipsAngle angle;
|
|
||||||
int image_page_width;
|
|
||||||
int image_page_height;
|
|
||||||
|
|
||||||
/* FIXME .. need to test XMP and IPCT.
|
/* FIXME .. need to test XMP and IPCT.
|
||||||
*/
|
*/
|
||||||
@ -377,36 +380,20 @@ vips_foreign_load_heif_set_header( VipsForeignLoadHeif *heif, VipsImage *out )
|
|||||||
}
|
}
|
||||||
#endif /*HAVE_HEIF_COLOR_PROFILE*/
|
#endif /*HAVE_HEIF_COLOR_PROFILE*/
|
||||||
|
|
||||||
/* Use the EXIF orientation to swap width/height, if necessary. The
|
/* We always use libheif's autorotate, so remove the exif one.
|
||||||
* actual rotation will be done by libheif during decode.
|
|
||||||
*/
|
*/
|
||||||
image_page_width = heif->page_width;
|
vips_autorot_remove_angle( out );
|
||||||
image_page_height = heif->page_height;
|
|
||||||
angle = vips_autorot_get_angle( out );
|
|
||||||
#ifdef HAVE_EXIF
|
|
||||||
if( !heif->autorotate ) {
|
|
||||||
if( angle == VIPS_ANGLE_D90 ||
|
|
||||||
angle == VIPS_ANGLE_D270 ) {
|
|
||||||
#ifdef DEBUG
|
|
||||||
printf( "swapping width/height\n" );
|
|
||||||
#endif /*DEBUG*/
|
|
||||||
VIPS_SWAP( int, image_page_width, image_page_height );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
vips_autorot_remove_angle( out );
|
|
||||||
#endif /*HAVE_EXIF*/
|
|
||||||
|
|
||||||
vips_image_set_int( out, "heif-primary", heif->primary_page );
|
vips_image_set_int( out, "heif-primary", heif->primary_page );
|
||||||
vips_image_set_int( out, "n-pages", heif->n_top );
|
vips_image_set_int( out, "n-pages", heif->n_top );
|
||||||
vips_image_set_int( out, "page-height", image_page_height );
|
vips_image_set_int( out, "page-height", heif->page_height );
|
||||||
|
|
||||||
/* FIXME .. we always decode to RGB in generate. We should check for
|
/* FIXME .. we always decode to RGB in generate. We should check for
|
||||||
* all grey images, perhaps.
|
* all grey images, perhaps.
|
||||||
*/
|
*/
|
||||||
vips_image_pipelinev( out, VIPS_DEMAND_STYLE_SMALLTILE, NULL );
|
vips_image_pipelinev( out, VIPS_DEMAND_STYLE_SMALLTILE, NULL );
|
||||||
vips_image_init_fields( out,
|
vips_image_init_fields( out,
|
||||||
image_page_width, image_page_height * heif->n, bands,
|
heif->page_width, heif->page_height * heif->n, bands,
|
||||||
VIPS_FORMAT_UCHAR, VIPS_CODING_NONE, VIPS_INTERPRETATION_sRGB,
|
VIPS_FORMAT_UCHAR, VIPS_CODING_NONE, VIPS_INTERPRETATION_sRGB,
|
||||||
1.0, 1.0 );
|
1.0, 1.0 );
|
||||||
|
|
||||||
@ -573,15 +560,8 @@ vips_foreign_load_heif_generate( VipsRegion *or,
|
|||||||
*
|
*
|
||||||
* FIXME What will this do for RGBA? Or is alpha always
|
* FIXME What will this do for RGBA? Or is alpha always
|
||||||
* separate?
|
* separate?
|
||||||
*
|
|
||||||
* If we are missing EXIF support, we won't be able to get
|
|
||||||
* orientation, so we won't be able to predict the result of
|
|
||||||
* the rotation, so our width/height are probably wrong.
|
|
||||||
*/
|
*/
|
||||||
options = heif_decoding_options_alloc();
|
options = heif_decoding_options_alloc();
|
||||||
#ifdef HAVE_EXIF
|
|
||||||
options->ignore_transformations = !heif->autorotate;
|
|
||||||
#endif /*HAVE_EXIF*/
|
|
||||||
error = heif_decode_image( heif->handle, &heif->img,
|
error = heif_decode_image( heif->handle, &heif->img,
|
||||||
heif_colorspace_RGB, heif_chroma_interleaved_RGB,
|
heif_colorspace_RGB, heif_chroma_interleaved_RGB,
|
||||||
options );
|
options );
|
||||||
@ -708,13 +688,6 @@ vips_foreign_load_heif_class_init( VipsForeignLoadHeifClass *class )
|
|||||||
G_STRUCT_OFFSET( VipsForeignLoadHeif, n ),
|
G_STRUCT_OFFSET( VipsForeignLoadHeif, n ),
|
||||||
-1, 100000, 1 );
|
-1, 100000, 1 );
|
||||||
|
|
||||||
VIPS_ARG_BOOL( class, "autorotate", 4,
|
|
||||||
_( "Autorotate" ),
|
|
||||||
_( "Apply image transformations" ),
|
|
||||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
|
||||||
G_STRUCT_OFFSET( VipsForeignLoadHeif, autorotate ),
|
|
||||||
FALSE );
|
|
||||||
|
|
||||||
VIPS_ARG_BOOL( class, "thumbnail", 4,
|
VIPS_ARG_BOOL( class, "thumbnail", 4,
|
||||||
_( "Thumbnail" ),
|
_( "Thumbnail" ),
|
||||||
_( "Fetch thumbnail image" ),
|
_( "Fetch thumbnail image" ),
|
||||||
@ -900,7 +873,6 @@ vips_foreign_load_heif_buffer_init( VipsForeignLoadHeifBuffer *buffer )
|
|||||||
*
|
*
|
||||||
* * @page: %gint, page (top-level image number) to read
|
* * @page: %gint, page (top-level image number) to read
|
||||||
* * @n: %gint, load this many pages
|
* * @n: %gint, load this many pages
|
||||||
* * @autorotate: %gboolean, apply image transformations
|
|
||||||
* * @thumbnail: %gboolean, fetch thumbnail instead of image
|
* * @thumbnail: %gboolean, fetch thumbnail instead of image
|
||||||
*
|
*
|
||||||
* Read a HEIF image file into a VIPS image.
|
* Read a HEIF image file into a VIPS image.
|
||||||
@ -915,9 +887,6 @@ vips_foreign_load_heif_buffer_init( VipsForeignLoadHeifBuffer *buffer )
|
|||||||
* HEIF images have a primary image. The metadata item `heif-primary` gives
|
* HEIF images have a primary image. The metadata item `heif-primary` gives
|
||||||
* the page number of the primary.
|
* the page number of the primary.
|
||||||
*
|
*
|
||||||
* HEIF images can have transformations like rotate, flip and crop stored in
|
|
||||||
* the header. Set @autorotate %TRUE to apply these during load.
|
|
||||||
*
|
|
||||||
* If @thumbnail is %TRUE, then fetch a stored thumbnail rather than the
|
* If @thumbnail is %TRUE, then fetch a stored thumbnail rather than the
|
||||||
* image.
|
* image.
|
||||||
*
|
*
|
||||||
@ -949,7 +918,6 @@ vips_heifload( const char *filename, VipsImage **out, ... )
|
|||||||
*
|
*
|
||||||
* * @page: %gint, page (top-level image number) to read
|
* * @page: %gint, page (top-level image number) to read
|
||||||
* * @n: %gint, load this many pages
|
* * @n: %gint, load this many pages
|
||||||
* * @autorotate: %gboolean, apply image transformations
|
|
||||||
* * @thumbnail: %gboolean, fetch thumbnail instead of image
|
* * @thumbnail: %gboolean, fetch thumbnail instead of image
|
||||||
*
|
*
|
||||||
* Read a HEIF image file into a VIPS image.
|
* Read a HEIF image file into a VIPS image.
|
||||||
|
@ -836,8 +836,8 @@ class TestForeign:
|
|||||||
def heif_valid(im):
|
def heif_valid(im):
|
||||||
a = im(10, 10)
|
a = im(10, 10)
|
||||||
assert_almost_equal_objects(a, [75.0, 86.0, 81.0])
|
assert_almost_equal_objects(a, [75.0, 86.0, 81.0])
|
||||||
assert im.width == 3024
|
assert im.width == 4032
|
||||||
assert im.height == 4032
|
assert im.height == 3024
|
||||||
assert im.bands == 3
|
assert im.bands == 3
|
||||||
|
|
||||||
self.file_loader("heifload", HEIC_FILE, heif_valid)
|
self.file_loader("heifload", HEIC_FILE, heif_valid)
|
||||||
@ -876,10 +876,10 @@ class TestForeign:
|
|||||||
z = pyvips.Image.new_from_file(JPEG_FILE)
|
z = pyvips.Image.new_from_file(JPEG_FILE)
|
||||||
if z.get_typeof("exif-ifd0-Orientation") != 0:
|
if z.get_typeof("exif-ifd0-Orientation") != 0:
|
||||||
x = self.colour.copy()
|
x = self.colour.copy()
|
||||||
x.set("orientation", 6)
|
x.set("exif-ifd0-Make", "banana")
|
||||||
buf = x.heifsave_buffer()
|
buf = x.heifsave_buffer()
|
||||||
y = pyvips.Image.new_from_buffer(buf, "")
|
y = pyvips.Image.new_from_buffer(buf, "")
|
||||||
assert y.get("orientation") == 6
|
assert y.get("exif-ifd0-Make").split(" ")[0] == "banana"
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
pytest.main()
|
pytest.main()
|
||||||
|
Loading…
Reference in New Issue
Block a user