diff --git a/misc/test-exif.jpeg b/misc/test-exif.jpeg
new file mode 100644
index 0000000000000000000000000000000000000000..999354ca2ed8a710edfde222b0fc244f00894ff3
GIT binary patch
literal 15287
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
D@^VkR

literal 0
HcmV?d00001

diff --git a/src/Plugin/ImageToolkit/ImagemagickToolkit.php b/src/Plugin/ImageToolkit/ImagemagickToolkit.php
index b2cad74..3b48283 100644
--- a/src/Plugin/ImageToolkit/ImagemagickToolkit.php
+++ b/src/Plugin/ImageToolkit/ImagemagickToolkit.php
@@ -80,11 +80,11 @@ class ImagemagickToolkit extends ImageToolkitBase {
   protected $sourceFormat = '';
 
   /**
-   * The source image EXIF orientation.
+   * Keeps a copy of source image EXIF information.
    *
-   * @var string
+   * @var bool
    */
-  protected $exifOrientation = NULL;
+  protected $exifInfo = [];
 
   /**
    * The image destination URI/path on saving.
@@ -404,7 +404,10 @@ class ImagemagickToolkit extends ImageToolkitBase {
    *   The source EXIF orientation.
    */
   public function getExifOrientation() {
-    return $this->exifOrientation;
+    if (empty($this->exifInfo)) {
+      $this->parseExifData();
+    }
+    return isset($this->exifInfo['Orientation']) ? $this->exifInfo['Orientation'] : NULL;
   }
 
   /**
@@ -416,7 +419,7 @@ class ImagemagickToolkit extends ImageToolkitBase {
    * @return $this
    */
   public function setExifOrientation($exif_orientation) {
-    $this->exifOrientation = (int) $exif_orientation;
+    $this->exifInfo['Orientation'] = !empty($exif_orientation) ? ((int) $exif_orientation !== 0 ? (int) $exif_orientation : NULL) : NULL;
     return $this;
   }
 
@@ -729,6 +732,37 @@ class ImagemagickToolkit extends ImageToolkitBase {
   }
 
   /**
+   * Parses the image file EXIF data using the PHP read_exif_data() function.
+   *
+   * @return $this
+   */
+  protected function parseExifData() {
+    $continue = TRUE;
+    // Test to see if EXIF is supported by the image format.
+    $mime_type = $this->getMimeType();
+    if (!in_array($mime_type, ['image/jpeg', 'image/tiff'])) {
+      // Not an EXIF enabled image.
+      $continue = FALSE;
+    }
+    $local_path = $this->getSourceLocalPath();
+    if ($continue && empty($local_path)) {
+      // No file path available. Most likely a new image from scratch.
+      $continue = FALSE;
+    }
+    if ($continue && !function_exists('exif_read_data')) {
+      // No PHP EXIF extension enabled, return.
+      $this->logger->error('The PHP EXIF extension is not installed. The \'imagemagick\' toolkit is unable to automatically determine image orientation.');
+      $continue = FALSE;
+    }
+    if ($continue && ($exif_data = @exif_read_data($this->getSourceLocalPath()))) {
+      $this->exifInfo = $exif_data;
+      return $this;
+    }
+    $this->setExifOrientation(NULL);
+    return $this;
+  }
+
+  /**
    * Calls the identify executable on the specified file.
    *
    * @return bool
diff --git a/src/Tests/ToolkitImagemagickTest.php b/src/Tests/ToolkitImagemagickTest.php
index 2232dee..7f1eef9 100644
--- a/src/Tests/ToolkitImagemagickTest.php
+++ b/src/Tests/ToolkitImagemagickTest.php
@@ -25,6 +25,13 @@ class ToolkitImagemagickTest extends WebTestBase {
    */
   protected $imageFactory;
 
+  /**
+   * A directory for image test file results.
+   *
+   * @var string
+   */
+  protected $testDirectory;
+
   // Colors that are used in testing.
   protected $black       = array(0, 0, 0, 0);
   protected $red         = array(255, 0, 0, 0);
@@ -71,6 +78,10 @@ class ToolkitImagemagickTest extends WebTestBase {
     // Set the toolkit on the image factory.
     $this->imageFactory = $this->container->get('image.factory');
     $this->imageFactory->setToolkitId('imagemagick');
+
+    // Prepare a directory for test file results.
+    $this->testDirectory = 'public://imagetest';
+    file_prepare_directory($this->testDirectory, FILE_CREATE_DIRECTORY);
   }
 
   /**
@@ -114,7 +125,7 @@ class ToolkitImagemagickTest extends WebTestBase {
    * properly, build a list of expected color values for each of the corners and
    * the expected height and widths for the final images.
    */
-  protected function testManipulations() {
+  public function testManipulations() {
     // Test that the image factory is set to use the Imagemagick toolkit.
     $this->assertEqual($this->imageFactory->getToolkitId(), 'imagemagick', 'The image factory is set to use the \'imagemagick\' image toolkit.');
 
@@ -269,10 +280,6 @@ class ToolkitImagemagickTest extends WebTestBase {
       ),
     );
 
-    // Prepare a directory for test file results.
-    $directory = 'public://imagetest';
-    file_prepare_directory($directory, FILE_CREATE_DIRECTORY);
-
     // Prepare a copy of test files.
     $this->drupalGetTestFiles('image');
 
@@ -289,7 +296,7 @@ class ToolkitImagemagickTest extends WebTestBase {
         $image->apply($values['function'], $values['arguments']);
 
         // Save image.
-        $file_path = $directory . '/' . $op . substr($file, -4);
+        $file_path = $this->testDirectory . '/' . $op . substr($file, -4);
         $image->save($file_path);
 
         // Reload with GD to be able to check results at pixel level.
@@ -369,7 +376,7 @@ class ToolkitImagemagickTest extends WebTestBase {
       $image = $this->imageFactory->get();
       $image->createNew(50, 20, image_type_to_extension($type, FALSE), '#ffff00');
       $file = 'from_null' . image_type_to_extension($type);
-      $file_path = $directory . '/' . $file;
+      $file_path = $this->testDirectory . '/' . $file;
       $this->assertEqual(50, $image->getWidth(), SafeMarkup::format('Image file %file has the correct width.', array('%file' => $file)));
       $this->assertEqual(20, $image->getHeight(), SafeMarkup::format('Image file %file has the correct height.', array('%file' => $file)));
       $this->assertEqual(image_type_to_mime_type($type), $image->getMimeType(), SafeMarkup::format('Image file %file has the correct MIME type.', array('%file' => $file)));
@@ -404,6 +411,7 @@ class ToolkitImagemagickTest extends WebTestBase {
     $this->assertTrue($image->isValid(), 'CreateNew with valid arguments validates the Image.');
 
     // Test saving image files with filenames having non-ascii characters.
+
     $file_names = [
       'greek εικόνα δοκιμής.png',
       'russian Тестовое изображение.png',
@@ -419,10 +427,53 @@ class ToolkitImagemagickTest extends WebTestBase {
       'viet "with double quotes" hình ảnh thử nghiệm.png',
     ];
     foreach ($file_names as $file) {
-      $file_path = $directory . '/' . $file;
+      $file_path = $this->testDirectory . '/' . $file;
       $image->save($file_path);
       $image_reloaded = $this->imageFactory->get($file_path);
       $this->assertTrue($image_reloaded->isValid(), SafeMarkup::format('Image file %file loaded successfully.', array('%file' => $file)));
     }
+
+    // Test retrieval of EXIF information.
+
+    // The image files that will be tested.
+    $image_files = [
+      [
+        'path' => drupal_get_path('module', 'imagemagick') . '/misc/test-exif.jpeg',
+        'orientation' => 8,
+      ],
+      [
+        'path' => 'public://image-test.jpg',
+        'orientation' => NULL,
+      ],
+      [
+        'path' => 'public://image-test.png',
+        'orientation' => NULL,
+      ],
+      [
+        'path' => 'public://image-test.gif',
+        'orientation' => NULL,
+      ],
+      [
+        'path' => NULL,
+        'orientation' => NULL,
+      ],
+    ];
+
+    foreach($image_files as $image_file) {
+      // Get image using 'identify'.
+      \Drupal::configFactory()->getEditable('imagemagick.settings')
+        ->set('use_identify', TRUE)
+        ->save();
+      $image = $this->imageFactory->get($image_file['path']);
+      $this->assertIdentical($image_file['orientation'], $image->getToolkit()->getExifOrientation());
+
+      // Get image using 'getimagesize'.
+      \Drupal::configFactory()->getEditable('imagemagick.settings')
+        ->set('use_identify', FALSE)
+        ->save();
+      $image = $this->imageFactory->get($image_file['path']);
+      $this->assertIdentical($image_file['orientation'], $image->getToolkit()->getExifOrientation());
+    }
   }
+
 }
