autorot looks in every ifd
some images have multiple orientation tags ... look and remove orientation tags everywhere
This commit is contained in:
parent
5b79403ea3
commit
a7e564ed97
@ -2,6 +2,8 @@
|
|||||||
*
|
*
|
||||||
* 19/10/14
|
* 19/10/14
|
||||||
* - from jpegload
|
* - from jpegload
|
||||||
|
* 12/4/16
|
||||||
|
* - test and remove orientation from every ifd
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -53,34 +55,26 @@ typedef VipsConversionClass VipsAutorotClass;
|
|||||||
|
|
||||||
G_DEFINE_TYPE( VipsAutorot, vips_autorot, VIPS_TYPE_CONVERSION );
|
G_DEFINE_TYPE( VipsAutorot, vips_autorot, VIPS_TYPE_CONVERSION );
|
||||||
|
|
||||||
#define ORIENTATION ("exif-ifd0-Orientation")
|
static void *
|
||||||
|
vips_autorot_get_angle_sub( VipsImage *image,
|
||||||
/**
|
const char *field, GValue *value, void *my_data )
|
||||||
* vips_autorot_get_angle:
|
|
||||||
* @im: image to fetch orientation from
|
|
||||||
*
|
|
||||||
* Examine the metadata on @im and return the #VipsAngle to rotate by to turn
|
|
||||||
* the image upright.
|
|
||||||
*
|
|
||||||
* See also: vips_autorot().
|
|
||||||
*
|
|
||||||
* Returns: the #VipsAngle to rotate by to make the image upright.
|
|
||||||
*/
|
|
||||||
VipsAngle
|
|
||||||
vips_autorot_get_angle( VipsImage *im )
|
|
||||||
{
|
{
|
||||||
VipsAngle angle;
|
VipsAngle *angle = (VipsAngle *) my_data;
|
||||||
|
|
||||||
const char *orientation;
|
const char *orientation;
|
||||||
|
|
||||||
angle = VIPS_ANGLE_D0;
|
if( vips_isprefix( "exif-", field ) &&
|
||||||
if( vips_image_get_typeof( im, ORIENTATION ) &&
|
vips_ispostfix( "-Orientation", field ) &&
|
||||||
!vips_image_get_string( im, ORIENTATION, &orientation ) ) {
|
!vips_image_get_string( image, field, &orientation ) ) {
|
||||||
if( vips_isprefix( "6", orientation ) )
|
if( vips_isprefix( "6", orientation ) )
|
||||||
angle = VIPS_ANGLE_D90;
|
*angle = VIPS_ANGLE_D90;
|
||||||
else if( vips_isprefix( "8", orientation ) )
|
else if( vips_isprefix( "8", orientation ) )
|
||||||
angle = VIPS_ANGLE_D270;
|
*angle = VIPS_ANGLE_D270;
|
||||||
else if( vips_isprefix( "3", orientation ) )
|
else if( vips_isprefix( "3", orientation ) )
|
||||||
angle = VIPS_ANGLE_D180;
|
*angle = VIPS_ANGLE_D180;
|
||||||
|
else
|
||||||
|
*angle = VIPS_ANGLE_D0;
|
||||||
|
|
||||||
/* Other values do rotate + mirror, don't bother handling them
|
/* Other values do rotate + mirror, don't bother handling them
|
||||||
* though, how common can mirroring be.
|
* though, how common can mirroring be.
|
||||||
*
|
*
|
||||||
@ -90,9 +84,56 @@ vips_autorot_get_angle( VipsImage *im )
|
|||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return( NULL );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* vips_autorot_get_angle:
|
||||||
|
* @image: image to fetch orientation from
|
||||||
|
*
|
||||||
|
* Examine the metadata on @im and return the #VipsAngle to rotate by to turn
|
||||||
|
* the image upright.
|
||||||
|
*
|
||||||
|
* See also: vips_autorot().
|
||||||
|
*
|
||||||
|
* Returns: the #VipsAngle to rotate by to make the image upright.
|
||||||
|
*/
|
||||||
|
VipsAngle
|
||||||
|
vips_autorot_get_angle( VipsImage *image )
|
||||||
|
{
|
||||||
|
VipsAngle angle;
|
||||||
|
|
||||||
|
angle = VIPS_ANGLE_D0;
|
||||||
|
(void) vips_image_map( image, vips_autorot_get_angle_sub, &angle );
|
||||||
|
|
||||||
return( angle );
|
return( angle );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void *
|
||||||
|
vips_autorot_remove_angle_sub( VipsImage *image,
|
||||||
|
const char *field, GValue *value, void *my_data )
|
||||||
|
{
|
||||||
|
if( vips_isprefix( "exif-", field ) &&
|
||||||
|
vips_ispostfix( "-Orientation", field ) )
|
||||||
|
(void) vips_image_remove( image, field );
|
||||||
|
|
||||||
|
return( NULL );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* vips_autorot_remove_angle:
|
||||||
|
* @im: image to remove orientation from
|
||||||
|
*
|
||||||
|
* Remove any EXIF tag on @im which looks like orientation.
|
||||||
|
*
|
||||||
|
* See also: vips_autorot_get_angle().
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
vips_autorot_remove_angle( VipsImage *image )
|
||||||
|
{
|
||||||
|
(void) vips_image_map( image, vips_autorot_remove_angle_sub, NULL );
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
vips_autorot_build( VipsObject *object )
|
vips_autorot_build( VipsObject *object )
|
||||||
{
|
{
|
||||||
@ -106,11 +147,11 @@ vips_autorot_build( VipsObject *object )
|
|||||||
g_object_set( object,
|
g_object_set( object,
|
||||||
"angle", vips_autorot_get_angle( autorot->in ),
|
"angle", vips_autorot_get_angle( autorot->in ),
|
||||||
NULL );
|
NULL );
|
||||||
autorot->angle = vips_autorot_get_angle( autorot->in );
|
if( vips_rot( autorot->in, &t[0], autorot->angle, NULL ) )
|
||||||
if( vips_rot( autorot->in, &t[0], autorot->angle, NULL ) ||
|
return( -1 );
|
||||||
vips_image_write( t[0], conversion->out ) )
|
vips_autorot_remove_angle( t[0] );
|
||||||
|
if( vips_image_write( t[0], conversion->out ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
(void) vips_image_remove( conversion->out, ORIENTATION );
|
|
||||||
|
|
||||||
return( 0 );
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
@ -126,7 +126,7 @@ int vips_rot( VipsImage *in, VipsImage **out, VipsAngle angle, ... )
|
|||||||
__attribute__((sentinel));
|
__attribute__((sentinel));
|
||||||
int vips_rot45( VipsImage *in, VipsImage **out, ... )
|
int vips_rot45( VipsImage *in, VipsImage **out, ... )
|
||||||
__attribute__((sentinel));
|
__attribute__((sentinel));
|
||||||
VipsAngle vips_autorot_get_angle( VipsImage *im );
|
VipsAngle vips_autorot_get_angle( VipsImage *image );
|
||||||
int vips_autorot( VipsImage *in, VipsImage **out, ... )
|
int vips_autorot( VipsImage *in, VipsImage **out, ... )
|
||||||
__attribute__((sentinel));
|
__attribute__((sentinel));
|
||||||
int vips_zoom( VipsImage *in, VipsImage **out, int xfac, int yfac, ... )
|
int vips_zoom( VipsImage *in, VipsImage **out, int xfac, int yfac, ... )
|
||||||
|
Loading…
Reference in New Issue
Block a user