MediaWiki  master
ExifRotationTest.php
Go to the documentation of this file.
00001 <?php
00002 
00006 class ExifRotationTest extends MediaWikiTestCase {
00007 
00008         protected function setUp() {
00009                 parent::setUp();
00010                 $this->handler = new BitmapHandler();
00011                 $filePath = __DIR__ . '/../../data/media';
00012 
00013                 $tmpDir = $this->getNewTempDirectory();
00014 
00015                 $this->repo = new FSRepo( array(
00016                         'name'            => 'temp',
00017                         'url'             => 'http://localhost/thumbtest',
00018                         'backend'         => new FSFileBackend( array(
00019                                 'name'           => 'localtesting',
00020                                 'lockManager'    => 'nullLockManager',
00021                                 'containerPaths' => array( 'temp-thumb' => $tmpDir, 'data' => $filePath )
00022                         ) )
00023                 ) );
00024                 if ( !wfDl( 'exif' ) ) {
00025                         $this->markTestSkipped( "This test needs the exif extension." );
00026                 }
00027                 global $wgShowEXIF;
00028                 $this->show = $wgShowEXIF;
00029                 $wgShowEXIF = true;
00030 
00031                 global $wgEnableAutoRotation;
00032                 $this->oldAuto = $wgEnableAutoRotation;
00033                 $wgEnableAutoRotation = true;
00034         }
00035 
00036         protected function tearDown() {
00037                 global $wgShowEXIF, $wgEnableAutoRotation;
00038                 $wgShowEXIF = $this->show;
00039                 $wgEnableAutoRotation = $this->oldAuto;
00040 
00041                 parent::tearDown();
00042         }
00043 
00048         function testMetadata( $name, $type, $info ) {
00049                 if ( !BitmapHandler::canRotate() ) {
00050                         $this->markTestSkipped( "This test needs a rasterizer that can auto-rotate." );
00051                 }
00052                 $file = $this->dataFile( $name, $type );
00053                 $this->assertEquals( $info['width'], $file->getWidth(), "$name: width check" );
00054                 $this->assertEquals( $info['height'], $file->getHeight(), "$name: height check" );
00055         }
00056 
00061         function testRotationRendering( $name, $type, $info, $thumbs ) {
00062                 if ( !BitmapHandler::canRotate() ) {
00063                         $this->markTestSkipped( "This test needs a rasterizer that can auto-rotate." );
00064                 }
00065                 foreach( $thumbs as $size => $out ) {
00066                         if( preg_match('/^(\d+)px$/', $size, $matches ) ) {
00067                                 $params = array(
00068                                         'width' => $matches[1],
00069                                 );
00070                         } elseif ( preg_match( '/^(\d+)x(\d+)px$/', $size, $matches ) ) {
00071                                 $params = array(
00072                                         'width' => $matches[1],
00073                                         'height' => $matches[2]
00074                                 );
00075                         } else {
00076                                 throw new MWException('bogus test data format ' . $size);
00077                         }
00078 
00079                         $file = $this->dataFile( $name, $type );
00080                         $thumb = $file->transform( $params, File::RENDER_NOW | File::RENDER_FORCE );
00081 
00082                         $this->assertEquals( $out[0], $thumb->getWidth(), "$name: thumb reported width check for $size" );
00083                         $this->assertEquals( $out[1], $thumb->getHeight(), "$name: thumb reported height check for $size" );
00084 
00085                         $gis = getimagesize( $thumb->getLocalCopyPath() );
00086                         if ($out[0] > $info['width']) {
00087                                 // Physical image won't be scaled bigger than the original.
00088                                 $this->assertEquals( $info['width'], $gis[0], "$name: thumb actual width check for $size");
00089                                 $this->assertEquals( $info['height'], $gis[1], "$name: thumb actual height check for $size");
00090                         } else {
00091                                 $this->assertEquals( $out[0], $gis[0], "$name: thumb actual width check for $size");
00092                                 $this->assertEquals( $out[1], $gis[1], "$name: thumb actual height check for $size");
00093                         }
00094                 }
00095         }
00096 
00097         /* Utility function */
00098         private function dataFile( $name, $type ) {
00099                 return new UnregisteredLocalFile( false, $this->repo,
00100                         "mwstore://localtesting/data/$name", $type );
00101         }
00102 
00103         public static function provideFiles() {
00104                 return array(
00105                         array(
00106                                 'landscape-plain.jpg',
00107                                 'image/jpeg',
00108                                 array(
00109                                         'width' => 1024,
00110                                         'height' => 768,
00111                                 ),
00112                                 array(
00113                                         '800x600px' => array( 800, 600 ),
00114                                         '9999x800px' => array( 1067, 800 ),
00115                                         '800px' => array( 800, 600 ),
00116                                         '600px' => array( 600, 450 ),
00117                                 )
00118                         ),
00119                         array(
00120                                 'portrait-rotated.jpg',
00121                                 'image/jpeg',
00122                                 array(
00123                                         'width' => 768, // as rotated
00124                                         'height' => 1024, // as rotated
00125                                 ),
00126                                 array(
00127                                         '800x600px' => array( 450, 600 ),
00128                                         '9999x800px' => array( 600, 800 ),
00129                                         '800px' => array( 800, 1067 ),
00130                                         '600px' => array( 600, 800 ),
00131                                 )
00132                         )
00133                 );
00134         }
00135 
00140         function testMetadataNoAutoRotate( $name, $type, $info ) {
00141                 global $wgEnableAutoRotation;
00142                 $wgEnableAutoRotation = false;
00143 
00144                 $file = $this->dataFile( $name, $type );
00145                 $this->assertEquals( $info['width'], $file->getWidth(), "$name: width check" );
00146                 $this->assertEquals( $info['height'], $file->getHeight(), "$name: height check" );
00147 
00148                 $wgEnableAutoRotation = true;
00149         }
00150 
00155         function testRotationRenderingNoAutoRotate( $name, $type, $info, $thumbs ) {
00156                 global $wgEnableAutoRotation;
00157                 $wgEnableAutoRotation = false;
00158 
00159                 foreach( $thumbs as $size => $out ) {
00160                         if( preg_match('/^(\d+)px$/', $size, $matches ) ) {
00161                                 $params = array(
00162                                         'width' => $matches[1],
00163                                 );
00164                         } elseif ( preg_match( '/^(\d+)x(\d+)px$/', $size, $matches ) ) {
00165                                 $params = array(
00166                                         'width' => $matches[1],
00167                                         'height' => $matches[2]
00168                                 );
00169                         } else {
00170                                 throw new MWException('bogus test data format ' . $size);
00171                         }
00172 
00173                         $file = $this->dataFile( $name, $type );
00174                         $thumb = $file->transform( $params, File::RENDER_NOW | File::RENDER_FORCE );
00175 
00176                         $this->assertEquals( $out[0], $thumb->getWidth(), "$name: thumb reported width check for $size" );
00177                         $this->assertEquals( $out[1], $thumb->getHeight(), "$name: thumb reported height check for $size" );
00178 
00179                         $gis = getimagesize( $thumb->getLocalCopyPath() );
00180                         if ($out[0] > $info['width']) {
00181                                 // Physical image won't be scaled bigger than the original.
00182                                 $this->assertEquals( $info['width'], $gis[0], "$name: thumb actual width check for $size");
00183                                 $this->assertEquals( $info['height'], $gis[1], "$name: thumb actual height check for $size");
00184                         } else {
00185                                 $this->assertEquals( $out[0], $gis[0], "$name: thumb actual width check for $size");
00186                                 $this->assertEquals( $out[1], $gis[1], "$name: thumb actual height check for $size");
00187                         }
00188                 }
00189                 $wgEnableAutoRotation = true;
00190         }
00191 
00192         public static function provideFilesNoAutoRotate() {
00193                 return array(
00194                         array(
00195                                 'landscape-plain.jpg',
00196                                 'image/jpeg',
00197                                 array(
00198                                         'width' => 1024,
00199                                         'height' => 768,
00200                                 ),
00201                                 array(
00202                                         '800x600px' => array( 800, 600 ),
00203                                         '9999x800px' => array( 1067, 800 ),
00204                                         '800px' => array( 800, 600 ),
00205                                         '600px' => array( 600, 450 ),
00206                                 )
00207                         ),
00208                         array(
00209                                 'portrait-rotated.jpg',
00210                                 'image/jpeg',
00211                                 array(
00212                                         'width' => 1024, // since not rotated
00213                                         'height' => 768, // since not rotated
00214                                 ),
00215                                 array(
00216                                         '800x600px' => array( 800, 600 ),
00217                                         '9999x800px' => array( 1067, 800 ),
00218                                         '800px' => array( 800, 600 ),
00219                                         '600px' => array( 600, 450 ),
00220                                 )
00221                         )
00222                 );
00223         }
00224         
00225         
00226         const TEST_WIDTH = 100;
00227         const TEST_HEIGHT = 200;
00228         
00232         function testBitmapExtractPreRotationDimensions( $rotation, $expected ) {
00233                 $result = $this->handler->extractPreRotationDimensions( array(
00234                                 'physicalWidth' => self::TEST_WIDTH, 
00235                                 'physicalHeight' => self::TEST_HEIGHT,
00236                         ), $rotation );
00237                 $this->assertEquals( $expected, $result );
00238         }
00239         
00240         function provideBitmapExtractPreRotationDimensions() {
00241                 return array(
00242                         array(
00243                                 0,
00244                                 array( self::TEST_WIDTH, self::TEST_HEIGHT ) 
00245                         ),
00246                         array(
00247                                 90,
00248                                 array( self::TEST_HEIGHT, self::TEST_WIDTH ) 
00249                         ),
00250                         array(
00251                                 180,
00252                                 array( self::TEST_WIDTH, self::TEST_HEIGHT ) 
00253                         ),
00254                         array(
00255                                 270,
00256                                 array( self::TEST_HEIGHT, self::TEST_WIDTH ) 
00257                         ),
00258                 );
00259         }
00260 }
00261