Index: trunk/phase3/tests/phpunit/includes/media/ExifRotationTest.php |
— | — | @@ -145,27 +145,5 @@ |
146 | 146 | ), |
147 | 147 | ); |
148 | 148 | } |
149 | | - |
150 | | - function testWidthFlipping() { |
151 | | - # Any further test require a scaler that can rotate |
152 | | - if ( !BitmapHandler::canRotate() ) { |
153 | | - $this->markTestSkipped( 'Scaler does not support rotation' ); |
154 | | - return; |
155 | | - } |
156 | | - $file = UnregisteredLocalFile::newFromPath( $this->filePath . 'portrait-rotated.jpg', 'image/jpeg' ); |
157 | | - $params = array( 'width' => '50' ); |
158 | | - $this->assertTrue( $this->handler->normaliseParams( $file, $params ) ); |
159 | | - |
160 | | - $this->assertEquals( 50, $params['height'] ); |
161 | | - $this->assertEquals( round( (768/1024)*50 ), $params['width'], '', 0.1 ); |
162 | | - } |
163 | | - function testWidthNotFlipping() { |
164 | | - $file = UnregisteredLocalFile::newFromPath( $this->filePath . 'landscape-plain.jpg', 'image/jpeg' ); |
165 | | - $params = array( 'width' => '50' ); |
166 | | - $this->assertTrue( $this->handler->normaliseParams( $file, $params ) ); |
167 | | - |
168 | | - $this->assertEquals( 50, $params['width'] ); |
169 | | - $this->assertEquals( round( (768/1024)*50 ), $params['height'], '', 0.1 ); |
170 | | - } |
171 | 149 | } |
172 | 150 | |
Index: trunk/phase3/includes/filerepo/File.php |
— | — | @@ -1342,7 +1342,11 @@ |
1343 | 1343 | * @return string |
1344 | 1344 | */ |
1345 | 1345 | function getDescriptionUrl() { |
1346 | | - return $this->repo->getDescriptionUrl( $this->getName() ); |
| 1346 | + if ( $this->repo ) { |
| 1347 | + return $this->repo->getDescriptionUrl( $this->getName() ); |
| 1348 | + } else { |
| 1349 | + return false; |
| 1350 | + } |
1347 | 1351 | } |
1348 | 1352 | |
1349 | 1353 | /** |
Index: trunk/phase3/includes/media/Bitmap.php |
— | — | @@ -43,20 +43,6 @@ |
44 | 44 | } |
45 | 45 | } |
46 | 46 | |
47 | | - |
48 | | - if ( self::canRotate() ) { |
49 | | - $rotation = $this->getRotation( $image ); |
50 | | - if ( $rotation == 90 || $rotation == 270 ) { |
51 | | - wfDebug( __METHOD__ . ": Swapping width and height because the file will be rotated $rotation degrees\n" ); |
52 | | - |
53 | | - list( $params['width'], $params['height'] ) = |
54 | | - array( $params['height'], $params['width'] ); |
55 | | - list( $params['physicalWidth'], $params['physicalHeight'] ) = |
56 | | - array( $params['physicalHeight'], $params['physicalWidth'] ); |
57 | | - } |
58 | | - } |
59 | | - |
60 | | - |
61 | 47 | # Don't thumbnail an image so big that it will fill hard drives and send servers into swap |
62 | 48 | # JPEG has the handy property of allowing thumbnailing without full decompression, so we make |
63 | 49 | # an exception for it. |
— | — | @@ -73,6 +59,11 @@ |
74 | 60 | /** |
75 | 61 | * Extracts the width/height if the image will be scaled before rotating |
76 | 62 | * |
| 63 | + * This will match the physical size/aspect ratio of the original image |
| 64 | + * prior to application of the rotation -- so for a portrait image that's |
| 65 | + * stored as raw landscape with 90-degress rotation, the resulting size |
| 66 | + * will be wider than it is tall. |
| 67 | + * |
77 | 68 | * @param $params array Parameters as returned by normaliseParams |
78 | 69 | * @param $rotation int The rotation angle that will be applied |
79 | 70 | * @return array ($width, $height) array |
— | — | @@ -249,6 +240,8 @@ |
250 | 241 | * @param $image File File associated with this thumbnail |
251 | 242 | * @param $params array Array with scaler params |
252 | 243 | * @return ThumbnailImage |
| 244 | + * |
| 245 | + * @fixme no rotation support |
253 | 246 | */ |
254 | 247 | protected function getClientScalingThumbnailImage( $image, $params ) { |
255 | 248 | return new ThumbnailImage( $image, $image->getURL(), |
— | — | @@ -685,33 +678,21 @@ |
686 | 679 | } |
687 | 680 | |
688 | 681 | /** |
689 | | - * Try to read out the orientation of the file and return the angle that |
690 | | - * the file needs to be rotated to be viewed |
| 682 | + * On supporting image formats, try to read out the low-level orientation |
| 683 | + * of the file and return the angle that the file needs to be rotated to |
| 684 | + * be viewed. |
691 | 685 | * |
| 686 | + * This information is only useful when manipulating the original file; |
| 687 | + * the width and height we normally work with is logical, and will match |
| 688 | + * any produced output views. |
| 689 | + * |
| 690 | + * The base BitmapHandler doesn't understand any metadata formats, so this |
| 691 | + * is left up to child classes to implement. |
| 692 | + * |
692 | 693 | * @param $file File |
693 | 694 | * @return int 0, 90, 180 or 270 |
694 | 695 | */ |
695 | 696 | public function getRotation( $file ) { |
696 | | - $data = $file->getMetadata(); |
697 | | - if ( !$data ) { |
698 | | - return 0; |
699 | | - } |
700 | | - wfSuppressWarnings(); |
701 | | - $data = unserialize( $data ); |
702 | | - wfRestoreWarnings(); |
703 | | - if ( isset( $data['Orientation'] ) ) { |
704 | | - # See http://sylvana.net/jpegcrop/exif_orientation.html |
705 | | - switch ( $data['Orientation'] ) { |
706 | | - case 8: |
707 | | - return 90; |
708 | | - case 3: |
709 | | - return 180; |
710 | | - case 6: |
711 | | - return 270; |
712 | | - default: |
713 | | - return 0; |
714 | | - } |
715 | | - } |
716 | 697 | return 0; |
717 | 698 | } |
718 | 699 | |
Index: trunk/phase3/includes/media/ExifBitmap.php |
— | — | @@ -124,5 +124,77 @@ |
125 | 125 | function getMetadataType( $image ) { |
126 | 126 | return 'exif'; |
127 | 127 | } |
| 128 | + |
| 129 | + /** |
| 130 | + * Wrapper for base classes ImageHandler::getImageSize() that checks for |
| 131 | + * rotation reported from metadata and swaps the sizes to match. |
| 132 | + * |
| 133 | + * @param File $image |
| 134 | + * @param string $path |
| 135 | + * @return array |
| 136 | + */ |
| 137 | + function getImageSize( $image, $path ) { |
| 138 | + $gis = parent::getImageSize( $image, $path ); |
| 139 | + |
| 140 | + // Don't just call $image->getMetadata(); File::getPropsFromPath() calls us with a bogus object. |
| 141 | + // This may mean we read EXIF data twice on initial upload. |
| 142 | + $meta = $this->getMetadata( $image, $path ); |
| 143 | + $rotation = $this->getRotationForExif( $meta ); |
| 144 | + |
| 145 | + if ($rotation == 90 || $rotation == 270) { |
| 146 | + $width = $gis[0]; |
| 147 | + $gis[0] = $gis[1]; |
| 148 | + $gis[1] = $width; |
| 149 | + } |
| 150 | + return $gis; |
| 151 | + } |
| 152 | + |
| 153 | + /** |
| 154 | + * On supporting image formats, try to read out the low-level orientation |
| 155 | + * of the file and return the angle that the file needs to be rotated to |
| 156 | + * be viewed. |
| 157 | + * |
| 158 | + * This information is only useful when manipulating the original file; |
| 159 | + * the width and height we normally work with is logical, and will match |
| 160 | + * any produced output views. |
| 161 | + * |
| 162 | + * @param $file File |
| 163 | + * @return int 0, 90, 180 or 270 |
| 164 | + */ |
| 165 | + public function getRotation( $file ) { |
| 166 | + $data = $file->getMetadata(); |
| 167 | + return $this->getRotationForExif( $data ); |
| 168 | + } |
| 169 | + |
| 170 | + /** |
| 171 | + * Given a chunk of serialized Exif metadata, return the orientation as |
| 172 | + * degrees of rotation. |
| 173 | + * |
| 174 | + * @param string $data |
| 175 | + * @return int 0, 90, 180 or 270 |
| 176 | + * @fixme orientation can include flipping as well; see if this is an issue! |
| 177 | + */ |
| 178 | + protected function getRotationForExif( $data ) { |
| 179 | + if ( !$data ) { |
| 180 | + return 0; |
| 181 | + } |
| 182 | + wfSuppressWarnings(); |
| 183 | + $data = unserialize( $data ); |
| 184 | + wfRestoreWarnings(); |
| 185 | + if ( isset( $data['Orientation'] ) ) { |
| 186 | + # See http://sylvana.net/jpegcrop/exif_orientation.html |
| 187 | + switch ( $data['Orientation'] ) { |
| 188 | + case 8: |
| 189 | + return 90; |
| 190 | + case 3: |
| 191 | + return 180; |
| 192 | + case 6: |
| 193 | + return 270; |
| 194 | + default: |
| 195 | + return 0; |
| 196 | + } |
| 197 | + } |
| 198 | + return 0; |
| 199 | + } |
128 | 200 | } |
129 | 201 | |