Skip to content

Commit 0091d09

Browse files
joojooooy-guyon
andauthored
Fixes wrong EXIF Orientation from Irot Imir (#2729)
Add test and CHANGELOG entry. --------- Co-authored-by: Yannis Guyon <[email protected]>
1 parent ce66ee8 commit 0091d09

File tree

4 files changed

+25
-3
lines changed

4 files changed

+25
-3
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@ The changes are relative to the previous release, unless the baseline is specifi
2020
* Update libsharpyuv: v1.5.0
2121
* Update libxml2.cmd/LocalLibXml2.cmake: v2.14.0
2222
* Update libyuv.cmd: dc47c71b3 (1907)
23+
* Fix wrong Exif orientation set in JPEG or PNG output by avifdec when the input
24+
AVIF file has an ImageRotation property with angle set to 1 or 3, has no
25+
ImageMirror property, and carries an Exif chunk. Note that Exif orientation is
26+
usually ignored in PNG files, so this mainly impacts JPEG files.
2327

2428
## [1.2.1] - 2025-03-17
2529

apps/shared/avifexif.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ uint8_t avifImageGetExifOrientationFromIrotImir(const avifImage * image)
1313
}
1414
return 5; // 90 degrees anti-clockwise then swap top and bottom.
1515
}
16-
return 6; // 90 degrees anti-clockwise.
16+
return 8; // 90 degrees anti-clockwise.
1717
}
1818
if ((image->transformFlags & AVIF_TRANSFORM_IROT) && (image->irot.angle == 2)) {
1919
if (image->transformFlags & AVIF_TRANSFORM_IMIR) {
@@ -31,7 +31,7 @@ uint8_t avifImageGetExifOrientationFromIrotImir(const avifImage * image)
3131
}
3232
return 7; // 270 degrees anti-clockwise then swap top and bottom.
3333
}
34-
return 8; // 270 degrees anti-clockwise.
34+
return 6; // 270 degrees anti-clockwise.
3535
}
3636
if (image->transformFlags & AVIF_TRANSFORM_IMIR) {
3737
if (image->imir.axis) {

tests/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ if(AVIF_GTEST)
126126
add_avif_gtest_with_data(avifiostatstest)
127127
add_avif_gtest_with_data(avifkeyframetest)
128128
add_avif_gtest_with_data(aviflosslesstest)
129-
add_avif_gtest_with_data(avifmetadatatest)
129+
add_avif_internal_gtest_with_data(avifmetadatatest)
130130

131131
if(AVIF_ENABLE_EXPERIMENTAL_MINI)
132132
add_avif_gtest(avifminitest)

tests/gtest/avifmetadatatest.cc

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99

1010
#include "avif/avif.h"
1111
#include "avif/avif_cxx.h"
12+
#include "avif/internal.h"
13+
#include "avifexif.h"
1214
#include "avifjpeg.h"
1315
#include "avifpng.h"
1416
#include "aviftest_helpers.h"
@@ -284,6 +286,22 @@ TEST(MetadataTest, ExifOrientation) {
284286
EXPECT_EQ(image->width, temp_image->width /* should be height here */);
285287
}
286288

289+
TEST(MetadataTest, AllExifOrientations) {
290+
const ImagePtr image =
291+
testutil::ReadImage(data_path, "paris_exif_orientation_5.jpg");
292+
ASSERT_NE(image, nullptr);
293+
image->transformFlags = AVIF_TRANSFORM_NONE;
294+
for (uint8_t orientation = 1; orientation <= 8; ++orientation) {
295+
// Check roundtrip.
296+
ASSERT_EQ(avifSetExifOrientation(&image->exif, orientation),
297+
AVIF_RESULT_OK);
298+
ASSERT_EQ(avifImageExtractExifOrientationToIrotImir(image.get()),
299+
AVIF_RESULT_OK);
300+
ASSERT_EQ(avifImageGetExifOrientationFromIrotImir(image.get()),
301+
orientation);
302+
}
303+
}
304+
287305
TEST(MetadataTest, ExifOrientationAndForcedImir) {
288306
const ImagePtr image =
289307
testutil::ReadImage(data_path, "paris_exif_orientation_5.jpg");

0 commit comments

Comments
 (0)