Apply EXIF rotation to X-Content-Dimensions
authorGilles Dubuc <gilles@wikimedia.org>
Tue, 16 May 2017 12:56:26 +0000 (14:56 +0200)
committerGilles Dubuc <gdubuc@wikimedia.org>
Tue, 16 May 2017 13:57:00 +0000 (15:57 +0200)
Also adds integration tests for a few formats.

Bug: T150741
Change-Id: I686f7ef42457faf5bc688e60e6ce09a8550ca5aa

includes/media/BitmapMetadataHandler.php
includes/media/ExifBitmap.php
tests/phpunit/includes/media/XContentDimensionsTest.php [new file with mode: 0644]

index 7999bbb..c5f9cbb 100644 (file)
@@ -160,6 +160,7 @@ class BitmapMetadataHandler {
                $meta = new self();
 
                $seg = JpegMetadataExtractor::segmentSplitter( $filename );
+
                if ( isset( $seg['COM'] ) && isset( $seg['COM'][0] ) ) {
                        $meta->addMetadata( [ 'JPEGFileComment' => $seg['COM'] ], 'native' );
                }
@@ -182,9 +183,8 @@ class BitmapMetadataHandler {
                                $meta->addMetadata( $array, $type );
                        }
                }
-               if ( isset( $seg['byteOrder'] ) ) {
-                       $meta->getExif( $filename, $seg['byteOrder'] );
-               }
+
+               $meta->getExif( $filename, isset( $seg['byteOrder'] ) ? $seg['byteOrder'] : 'BE' );
 
                return $meta->getMetadataArray();
        }
index 2fe4872..cf4b12e 100644 (file)
@@ -254,8 +254,23 @@ class ExifBitmapHandler extends BitmapHandler {
                }
 
                $dimensionsMetadata = [];
-               $dimensionsMetadata['width'] = $metadata['Width'];
-               $dimensionsMetadata['height'] = $metadata['Height'];
+
+               if ( $this->autoRotateEnabled() && isset( $metadata['Orientation'] ) ) {
+                       switch ( $metadata['Orientation'] ) {
+                               case 5: // CCW flipped
+                               case 6: // CCW
+                               case 7: // CW flipped
+                               case 8: // CW
+                                       $dimensionsMetadata['width'] = $metadata['Height'];
+                                       $dimensionsMetadata['height'] = $metadata['Width'];
+                                       break;
+                       }
+               }
+
+               if ( !isset( $dimensionsMetadata['width'] ) ) {
+                       $dimensionsMetadata['width'] = $metadata['Width'];
+                       $dimensionsMetadata['height'] = $metadata['Height'];
+               }
 
                return parent::getContentHeaders( $dimensionsMetadata );
        }
diff --git a/tests/phpunit/includes/media/XContentDimensionsTest.php b/tests/phpunit/includes/media/XContentDimensionsTest.php
new file mode 100644 (file)
index 0000000..dddcc98
--- /dev/null
@@ -0,0 +1,31 @@
+<?php
+
+/**
+ * @group Media
+ */
+class XContentDimensionsTest extends MediaWikiMediaTestCase {
+       /**
+        * @param string $filename
+        * @param string $expectedXContentDimensions
+        * @dataProvider provideGetContentHeaders
+        * @covers File::getContentHeaders
+        */
+       public function testGetContentHeaders( $filename, $expectedXContentDimensions ) {
+               $file = $this->dataFile( $filename );
+               $headers = $file->getContentHeaders();
+               $this->assertEquals( true, isset( $headers['X-Content-Dimensions'] ) );
+               $this->assertEquals( $headers['X-Content-Dimensions'], $expectedXContentDimensions );
+       }
+
+       public static function provideGetContentHeaders() {
+               return [
+                       [ '80x60-2layers.xcf', '80x60:1' ],
+                       [ 'animated.gif', '45x30:1' ],
+                       [ 'landscape-plain.jpg', '1024x768:1' ],
+                       [ 'portrait-rotated.jpg', '768x1024:1' ],
+                       [ 'Wikimedia-logo.svg', '1024x1024:1' ],
+                       [ 'webp_animated.webp', '300x225:1' ],
+                       [ 'test.tiff', '20x20:1' ],
+               ];
+       }
+}