-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Align pixel orientation with exif:Orientation in HEIC decoder #1233
Conversation
It turns out that in HEIC the pixels are never rotated and the metadata only indicates the orientation of the sensor when the photo was taken. Hence, there was a discrepancy between `Image->orientation` and actual pixel orientation in images loaded with the `heic` coder. Particularly, this led to incorrect behavior of the `-auto-orient` which in this case tried to compensate non-existing pixel rotation. ImageMagick#1232
A question to the maintainers: where in the docs is the best place to describe the new option |
Is it not enough to call |
@dlemstra Absolutely. In most common cases it is really enough to reset Unfortunately, there are application which rely on the original pixel rotation for historical reasons. This is why I have also implemented the option |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you do the final tweaks so we can merge this?
coders/heic.c
Outdated
@@ -85,6 +86,8 @@ static MagickBooleanType | |||
WriteHEICImage(const ImageInfo *,Image *,ExceptionInfo *); | |||
#endif | |||
|
|||
static Image *CompensateOrientation(Image *image, ExceptionInfo *exception); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you move this method above the ReadHEICImage
method, near IsHeifSuccess
? We can then remove this line.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Of course, will do 👍
coders/heic.c
Outdated
*/ | ||
option=GetImageOption(image_info,"heic:preserve-orientation"); | ||
if (IsStringTrue(option) == MagickTrue) | ||
image = CompensateOrientation(image, exception); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This statement leaks memory. The methods FlipImage
, RotateImage
return a new image.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, my. That's right, I will free the old image here
coders/heic.c
Outdated
return(GetFirstImageInList(image)); | ||
} | ||
|
||
/* An inverse of AutoOrientImage */ | ||
static Image *CompensateOrientation(Image *image, ExceptionInfo *exception) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Image *image
should be const Image *image
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes sense, I will change it to a const pointer type
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is a problem. There is a bypass statement which needs to return a non-const result from the const parameter:
value=GetImageProperty(image,"exif:Orientation",exception);
if (value == NULL)
{
return image;
}
So I can factor this EXIF check out of this function (to the call site at ReadHEICImage
) or simply don't put the const
. Which way do you think is better?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point. I missed that, probably better to not change the signature to a const.
133db37
to
fd199ae
Compare
Hi @dlemstra, About the docs, it seems the most appropriate place to document Should I just edit that |
You should edit the command line options here: https://github.com/ImageMagick/Website |
coders/heic.c
Outdated
Image | ||
*original_image = image; | ||
image = CompensateOrientation(original_image, exception); | ||
DestroyImageList(original_image); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You should handle this inside the CompensateOrientation
method. You are now destroying the image
when exif:Orientation
is not set.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, true. Fill fix promptly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pushed.
I am sorry for the silly mistake
fd199ae
to
84a98b1
Compare
Pull request for docs: ImageMagick/Website#19 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the patch. Needs a few code style tweaks but I will apply them myself.
Dank u wel, Dirk! |
It turns out that in HEIC the pixels are never rotated and the metadata only
indicates the orientation of the sensor when the photo was taken.
Hence, there was a discrepancy between
Image->orientation
and actual pixelorientation in images loaded with the
heic
coder. Particularly, this led toincorrect behavior of the
-auto-orient
which in this case tried to compensatenon-existing pixel rotation.
This is a fix for #1232
The fix provides two solutions for the problem described above: reset
exif:Orientation
to "1" in HEIC decoder output (default behavior) or rotate pixels to match the originalexif:Orientation
, as some application might rely on the original sensor rotation. The latter is enabled byheic:preserve-orientation
read define.