From 39153ea6e2a77604e3302c5591fbb65496c3457a Mon Sep 17 00:00:00 2001
From: John MacFarlane <jgm@berkeley.edu>
Date: Mon, 14 Dec 2020 09:39:07 -0800
Subject: [PATCH] ImageSize: use exif width and height when available.

After the move to JuicyPixels, we were getting incorrect
width and heigh information for some images (see #6936, test-3.jpg).

The correct information was encoded in Exif tags that
JuicyPixels seemed to ignore. So we check these first
before looking at the Width and Height identified by
JuicyPixels.

Closes #6936.
---
 src/Text/Pandoc/ImageSize.hs | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/src/Text/Pandoc/ImageSize.hs b/src/Text/Pandoc/ImageSize.hs
index 665a94690..9ce5c668d 100644
--- a/src/Text/Pandoc/ImageSize.hs
+++ b/src/Text/Pandoc/ImageSize.hs
@@ -50,6 +50,7 @@ import qualified Data.Text.Encoding as TE
 import Control.Applicative
 import qualified Data.Attoparsec.ByteString.Char8 as A
 import qualified Codec.Picture.Metadata as Metadata
+import qualified Codec.Picture.Metadata.Exif as Exif
 import Codec.Picture (decodeImageWithMetadata)
 
 -- quick and dirty functions to get image sizes
@@ -300,8 +301,16 @@ getSize img =
     Left e -> Left (T.pack e)
     Right (_, meta) -> do
       pxx <- maybe (Left "Could not determine width") Right $
+                   -- first look for exif image width, then width
+                   (Metadata.lookup
+                     (Metadata.Exif (Exif.TagUnknown 0xA002)) meta >>=
+                       exifDataToWord) <|>
                    Metadata.lookup Metadata.Width meta
       pxy <- maybe (Left "Could not determine height") Right $
+                  -- first look for exif image height, then height
+                  (Metadata.lookup
+                     (Metadata.Exif (Exif.TagUnknown 0xA003)) meta >>=
+                       exifDataToWord) <|>
                   Metadata.lookup Metadata.Height meta
       dpix <- maybe (Right 72) Right $ Metadata.lookup Metadata.DpiX meta
       dpiy <- maybe (Right 72) Right $ Metadata.lookup Metadata.DpiY meta
@@ -310,6 +319,10 @@ getSize img =
                 , pxY = fromIntegral pxy
                 , dpiX = fromIntegral dpix
                 , dpiY = fromIntegral dpiy }
+ where
+  exifDataToWord (Exif.ExifLong x) = Just $ fromIntegral x
+  exifDataToWord (Exif.ExifShort x) = Just $ fromIntegral x
+  exifDataToWord _ = Nothing
 
 
 svgSize :: WriterOptions -> ByteString -> Maybe ImageSize