From: Colin Clark Date: Sun, 12 Sep 2021 14:41:32 +0000 (+0100) Subject: Fix #923: Wrong orientation in HEIC using EXIF X-Git-Tag: v1.7~59 X-Git-Url: http://geeqie.org/cgi-bin/gitweb.cgi?p=geeqie.git;a=commitdiff_plain;h=ac15f03b0b11ea0b5261818ab210a42f75033359 Fix #923: Wrong orientation in HEIC using EXIF https://github.com/BestImageViewer/geeqie/issues/923 This is an excerpt from ISO/IEC 23008-12:2017(E): --------- Metadata specified in Annex A or according to the item type and MIME type values is descriptive and does not normatively affect the presentation. In particular, an image item can be rotated by 90°, 180°, or 270° using the 'irot' transformative item property. Rotation metadata, e.g. according to Annex A, is ignored in the displaying process. 8.2 Metadata for image items ------------ Therefore libheif is rotating the image in accordance with the irot property - and then Geeqie rotates it again using the Exif value. If the libheif decoding option "ignore_transformations" is used, the result is different on two systems I use - one one system the option is ignored, and on the other system the option is used, but then no Exif data is displayed for the file. As the compiled code is the same in both cases, there must be an influence from other system library files. The implemented solution ignores the Exif rotation parameter and inhibits writing manually applied rotation metadata for all files processed by libheif. --- diff --git a/src/filedata.c b/src/filedata.c index f2c8795e..e25b9d07 100644 --- a/src/filedata.c +++ b/src/filedata.c @@ -716,6 +716,7 @@ static void file_data_free(FileData *fd) g_free(fd->owner); g_free(fd->group); g_free(fd->sym_link); + g_free(fd->format_name); g_assert(fd->sidecar_files == NULL); /* sidecar files must be freed before calling this */ file_data_change_info_free(NULL, fd); diff --git a/src/image-load.c b/src/image-load.c index 0b164577..e899ada7 100644 --- a/src/image-load.c +++ b/src/image-load.c @@ -887,6 +887,8 @@ static void image_loader_setup_loader(ImageLoader *il) g_free(format); #endif + il->fd->format_name = il->backend.get_format_name(il->loader); + g_mutex_unlock(il->data_mutex); } diff --git a/src/image.c b/src/image.c index 889f241e..30a4bc18 100644 --- a/src/image.c +++ b/src/image.c @@ -589,7 +589,14 @@ void image_alter_orientation(ImageWindow *imd, FileData *fd_n, AlterType type) else if (options->metadata.write_orientation) { - orientation = metadata_read_int(fd_n, ORIENTATION_KEY, EXIF_ORIENTATION_TOP_LEFT); + if (g_strcmp0(imd->image_fd->format_name, "heif") == 0) + { + orientation = EXIF_ORIENTATION_TOP_LEFT; + } + else + { + orientation = metadata_read_int(fd_n, ORIENTATION_KEY, EXIF_ORIENTATION_TOP_LEFT); + } } } @@ -620,13 +627,21 @@ void image_alter_orientation(ImageWindow *imd, FileData *fd_n, AlterType type) if (orientation != (fd_n->exif_orientation ? fd_n->exif_orientation : 1)) { - if (!options->metadata.write_orientation) + if (g_strcmp0(fd_n->format_name, "heif") != 0) + { + if (!options->metadata.write_orientation) + { + /* user_orientation does not work together with options->metadata.write_orientation, + use either one or the other. + we must however handle switching metadata.write_orientation on and off, therefore + we just disable referencing new fd's, not unreferencing the old ones + */ + if (fd_n->user_orientation == 0) file_data_ref(fd_n); + fd_n->user_orientation = orientation; + } + } + else { - /* user_orientation does not work together with options->metadata.write_orientation, - use either one or the other. - we must however handle switching metadata.write_orientation on and off, therefore - we just disable referencing new fd's, not unreferencing the old ones - */ if (fd_n->user_orientation == 0) file_data_ref(fd_n); fd_n->user_orientation = orientation; } @@ -637,15 +652,18 @@ void image_alter_orientation(ImageWindow *imd, FileData *fd_n, AlterType type) fd_n->user_orientation = 0; } - if (options->metadata.write_orientation) + if (g_strcmp0(fd_n->format_name, "heif") != 0) { - if (type == ALTER_NONE) - { - metadata_write_revert(fd_n, ORIENTATION_KEY); - } - else + if (options->metadata.write_orientation) { - metadata_write_int(fd_n, ORIENTATION_KEY, orientation); + if (type == ALTER_NONE) + { + metadata_write_revert(fd_n, ORIENTATION_KEY); + } + else + { + metadata_write_int(fd_n, ORIENTATION_KEY, orientation); + } } } @@ -1377,8 +1395,16 @@ void image_change_pixbuf(ImageWindow *imd, GdkPixbuf *pixbuf, gdouble zoom, gboo } else if (options->image.exif_rotate_enable) { - imd->orientation = metadata_read_int(imd->image_fd, ORIENTATION_KEY, EXIF_ORIENTATION_TOP_LEFT); - imd->image_fd->exif_orientation = imd->orientation; + if (g_strcmp0(imd->image_fd->format_name, "heif") == 0) + { + imd->orientation = EXIF_ORIENTATION_TOP_LEFT; + imd->image_fd->exif_orientation = imd->orientation; + } + else + { + imd->orientation = metadata_read_int(imd->image_fd, ORIENTATION_KEY, EXIF_ORIENTATION_TOP_LEFT); + imd->image_fd->exif_orientation = imd->orientation; + } } } diff --git a/src/layout_image.c b/src/layout_image.c index b26f956b..83e4170e 100644 --- a/src/layout_image.c +++ b/src/layout_image.c @@ -1279,7 +1279,14 @@ void layout_image_reset_orientation(LayoutWindow *lw) if (options->image.exif_rotate_enable) { - imd->orientation = metadata_read_int(imd->image_fd, ORIENTATION_KEY, EXIF_ORIENTATION_TOP_LEFT); + if (g_strcmp0(imd->image_fd->format_name, "heif") != 0) + { + imd->orientation = metadata_read_int(imd->image_fd, ORIENTATION_KEY, EXIF_ORIENTATION_TOP_LEFT); + } + else + { + imd->orientation = EXIF_ORIENTATION_TOP_LEFT; + } } else { diff --git a/src/pan-view/pan-view.c b/src/pan-view/pan-view.c index 956ec92f..a17962e6 100644 --- a/src/pan-view/pan-view.c +++ b/src/pan-view/pan-view.c @@ -147,7 +147,14 @@ static void pan_queue_image_done_cb(ImageLoader *il, gpointer data) { if (!il->fd->exif_orientation) { - il->fd->exif_orientation = metadata_read_int(il->fd, ORIENTATION_KEY, EXIF_ORIENTATION_TOP_LEFT); + if (g_strcmp0(il->fd->format_name, "heif") != 0) + { + il->fd->exif_orientation = metadata_read_int(il->fd, ORIENTATION_KEY, EXIF_ORIENTATION_TOP_LEFT); + } + else + { + il->fd->exif_orientation = EXIF_ORIENTATION_TOP_LEFT; + } } if (il->fd->exif_orientation != EXIF_ORIENTATION_TOP_LEFT) diff --git a/src/thumb.c b/src/thumb.c index 65b03872..2ab21c63 100644 --- a/src/thumb.c +++ b/src/thumb.c @@ -155,7 +155,14 @@ static void thumb_loader_done_cb(ImageLoader *il, gpointer data) { if (!tl->fd->exif_orientation) { - tl->fd->exif_orientation = metadata_read_int(tl->fd, ORIENTATION_KEY, EXIF_ORIENTATION_TOP_LEFT); + if (g_strcmp0(il->fd->format_name, "heif") != 0) + { + tl->fd->exif_orientation = metadata_read_int(tl->fd, ORIENTATION_KEY, EXIF_ORIENTATION_TOP_LEFT); + } + else + { + tl->fd->exif_orientation = EXIF_ORIENTATION_TOP_LEFT; + } } if (tl->fd->exif_orientation != EXIF_ORIENTATION_TOP_LEFT) diff --git a/src/thumb_standard.c b/src/thumb_standard.c index 3ac2b4b4..3f7a5cca 100644 --- a/src/thumb_standard.c +++ b/src/thumb_standard.c @@ -497,7 +497,14 @@ static GdkPixbuf *thumb_loader_std_finish(ThumbLoaderStd *tl, GdkPixbuf *pixbuf, { if (!tl->fd->exif_orientation) { - tl->fd->exif_orientation = metadata_read_int(tl->fd, ORIENTATION_KEY, EXIF_ORIENTATION_TOP_LEFT); + if (g_strcmp0(tl->fd->format_name, "heif") != 0) + { + tl->fd->exif_orientation = metadata_read_int(tl->fd, ORIENTATION_KEY, EXIF_ORIENTATION_TOP_LEFT); + } + else + { + tl->fd->exif_orientation = EXIF_ORIENTATION_TOP_LEFT; + } } if (tl->fd->exif_orientation != EXIF_ORIENTATION_TOP_LEFT) diff --git a/src/typedefs.h b/src/typedefs.h index 1625b518..7d6095f1 100644 --- a/src/typedefs.h +++ b/src/typedefs.h @@ -599,6 +599,7 @@ struct _FileData { const gchar *extension; gchar *extended_extension; FileFormatClass format_class; + gchar *format_name; /**< set by the image loader */ gchar *collate_key_name; gchar *collate_key_name_nocase; gint64 size;