From 692d44739bf6106d5bb03dc1b0729e9b788d9593 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Vital?= <70104194+mugulmd@users.noreply.github.com> Date: Sat, 20 May 2023 03:43:56 +0200 Subject: [PATCH] fix(raw): fix LibRaw flip to Exif orientation conversion (#3847) When reading a raw image while having a `user_flip` set to 1, we set the orientation Exif tag to LibRaw's flip value (so that LibRaw doesn't rotate and/or mirror the buffer but the image still gets displayed correctly). However LibRaw's convention for flip values differ from Exif orientation values: https://www.libraw.org/comment/5176#comment-5176. In this PR we fix this issue by converting LibRaw flip values to Exif orientation values. This conversion is based on: - https://www.libraw.org/comment/5178#comment-5178 (conversion proposed by LibRaw's maintainer) - https://github.com/LibRaw/LibRaw/blob/6fffd414bfda63dfef2276ae07f7ca36660b8888/src/write/file_write.cpp#L22 (LibRaw's function for applying the flip). Tested on: - CR2 images with flip values 1, 5 and 6 - ARW images with flip values 1 and 5 (unfortunately I could not find any image covering other flip values). Since the conversion is `[1, 2, 3, 4, 5, 6, 7, 8] -> [1, 2, 4, 3, 5, 8, 6, 7]`, the only test that came out with different results before and after the change is the one with flip value 6: in that case, the image orientation got corrected by the fix. --- src/raw.imageio/rawinput.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/raw.imageio/rawinput.cpp b/src/raw.imageio/rawinput.cpp index ede6e6eac8..88603da6d6 100644 --- a/src/raw.imageio/rawinput.cpp +++ b/src/raw.imageio/rawinput.cpp @@ -433,8 +433,15 @@ RawInput::open_raw(bool unpack, const std::string& name, m_unpacked = true; } - //Store flip before it is potentially overwritten - int original_flip = m_processor->imgdata.sizes.flip; + // Store flip before it is potentially overwritten + // LibRaw's convention for flip values differs from Exif orientation tags + // so we need to convert it + int original_flip = 1; + int libraw_flip = m_processor->imgdata.sizes.flip; + static int libraw_to_exif_flip[8] = { 1, 2, 4, 3, 5, 8, 6, 7 }; + if (libraw_flip >= 1 && libraw_flip <= 8) { + original_flip = libraw_to_exif_flip[libraw_flip - 1]; + } m_processor->adjust_sizes_info_only(); // Process image at half size if "raw:half_size" is not 0