Merged FileBackend branch. Manually avoiding merging the many prop-only changes SVN...
[lhc/web/wiklou.git] / tests / phpunit / includes / media / ExifRotationTest.php
1 <?php
2
3 /**
4 * Tests related to auto rotation
5 */
6 class ExifRotationTest extends MediaWikiTestCase {
7
8 function setUp() {
9 parent::setUp();
10 $this->handler = new BitmapHandler();
11 $filePath = dirname( __FILE__ ) . '/../../data/media';
12 $tmpDir = wfTempDir() . '/exif-test-' . time() . '-' . mt_rand();
13 $this->backend = new FSFileBackend( array(
14 'name' => 'localtesting',
15 'lockManager' => 'nullLockManager',
16 'containerPaths' => array( 'images-thumb' => $tmpDir, 'data' => $filePath )
17 ) );
18 $this->repo = new FSRepo( array(
19 'name' => 'temp',
20 'url' => 'http://localhost/thumbtest',
21 'backend' => $this->backend
22 ) );
23 if ( !wfDl( 'exif' ) ) {
24 $this->markTestSkipped( "This test needs the exif extension." );
25 }
26 global $wgShowEXIF;
27 $this->show = $wgShowEXIF;
28 $wgShowEXIF = true;
29
30 global $wgEnableAutoRotation;
31 $this->oldAuto = $wgEnableAutoRotation;
32 $wgEnableAutoRotation = true;
33 }
34 public function tearDown() {
35 global $wgShowEXIF, $wgEnableAutoRotation;
36 $wgShowEXIF = $this->show;
37 $wgEnableAutoRotation = $this->oldAuto;
38 }
39
40 /**
41 *
42 * @dataProvider providerFiles
43 */
44 function testMetadata( $name, $type, $info ) {
45 if ( !BitmapHandler::canRotate() ) {
46 $this->markTestSkipped( "This test needs a rasterizer that can auto-rotate." );
47 }
48 $file = $this->dataFile( $name, $type );
49 $this->assertEquals( $info['width'], $file->getWidth(), "$name: width check" );
50 $this->assertEquals( $info['height'], $file->getHeight(), "$name: height check" );
51 }
52
53 /**
54 *
55 * @dataProvider providerFiles
56 */
57 function testRotationRendering( $name, $type, $info, $thumbs ) {
58 if ( !BitmapHandler::canRotate() ) {
59 $this->markTestSkipped( "This test needs a rasterizer that can auto-rotate." );
60 }
61 foreach( $thumbs as $size => $out ) {
62 if( preg_match('/^(\d+)px$/', $size, $matches ) ) {
63 $params = array(
64 'width' => $matches[1],
65 );
66 } elseif ( preg_match( '/^(\d+)x(\d+)px$/', $size, $matches ) ) {
67 $params = array(
68 'width' => $matches[1],
69 'height' => $matches[2]
70 );
71 } else {
72 throw new MWException('bogus test data format ' . $size);
73 }
74
75 $file = $this->dataFile( $name, $type );
76 $thumb = $file->transform( $params, File::RENDER_NOW | File::RENDER_FORCE );
77
78 $this->assertEquals( $out[0], $thumb->getWidth(), "$name: thumb reported width check for $size" );
79 $this->assertEquals( $out[1], $thumb->getHeight(), "$name: thumb reported height check for $size" );
80
81 $gis = getimagesize( $thumb->getLocalCopyPath() );
82 if ($out[0] > $info['width']) {
83 // Physical image won't be scaled bigger than the original.
84 $this->assertEquals( $info['width'], $gis[0], "$name: thumb actual width check for $size");
85 $this->assertEquals( $info['height'], $gis[1], "$name: thumb actual height check for $size");
86 } else {
87 $this->assertEquals( $out[0], $gis[0], "$name: thumb actual width check for $size");
88 $this->assertEquals( $out[1], $gis[1], "$name: thumb actual height check for $size");
89 }
90 }
91 }
92
93 private function dataFile( $name, $type ) {
94 return new UnregisteredLocalFile( false, $this->repo,
95 "mwstore://localtesting/data/$name", $type );
96 }
97
98 function providerFiles() {
99 return array(
100 array(
101 'landscape-plain.jpg',
102 'image/jpeg',
103 array(
104 'width' => 1024,
105 'height' => 768,
106 ),
107 array(
108 '800x600px' => array( 800, 600 ),
109 '9999x800px' => array( 1067, 800 ),
110 '800px' => array( 800, 600 ),
111 '600px' => array( 600, 450 ),
112 )
113 ),
114 array(
115 'portrait-rotated.jpg',
116 'image/jpeg',
117 array(
118 'width' => 768, // as rotated
119 'height' => 1024, // as rotated
120 ),
121 array(
122 '800x600px' => array( 450, 600 ),
123 '9999x800px' => array( 600, 800 ),
124 '800px' => array( 800, 1067 ),
125 '600px' => array( 600, 800 ),
126 )
127 )
128 );
129 }
130
131 /**
132 * Same as before, but with auto-rotation disabled.
133 * @dataProvider providerFilesNoAutoRotate
134 */
135 function testMetadataNoAutoRotate( $name, $type, $info ) {
136 global $wgEnableAutoRotation;
137 $wgEnableAutoRotation = false;
138
139 $file = $this->dataFile( $name, $type );
140 $this->assertEquals( $info['width'], $file->getWidth(), "$name: width check" );
141 $this->assertEquals( $info['height'], $file->getHeight(), "$name: height check" );
142
143 $wgEnableAutoRotation = true;
144 }
145
146 /**
147 *
148 * @dataProvider providerFilesNoAutoRotate
149 */
150 function testRotationRenderingNoAutoRotate( $name, $type, $info, $thumbs ) {
151 global $wgEnableAutoRotation;
152 $wgEnableAutoRotation = false;
153
154 foreach( $thumbs as $size => $out ) {
155 if( preg_match('/^(\d+)px$/', $size, $matches ) ) {
156 $params = array(
157 'width' => $matches[1],
158 );
159 } elseif ( preg_match( '/^(\d+)x(\d+)px$/', $size, $matches ) ) {
160 $params = array(
161 'width' => $matches[1],
162 'height' => $matches[2]
163 );
164 } else {
165 throw new MWException('bogus test data format ' . $size);
166 }
167
168 $file = $this->dataFile( $name, $type );
169 $thumb = $file->transform( $params, File::RENDER_NOW | File::RENDER_FORCE );
170
171 $this->assertEquals( $out[0], $thumb->getWidth(), "$name: thumb reported width check for $size" );
172 $this->assertEquals( $out[1], $thumb->getHeight(), "$name: thumb reported height check for $size" );
173
174 $gis = getimagesize( $thumb->getLocalCopyPath() );
175 if ($out[0] > $info['width']) {
176 // Physical image won't be scaled bigger than the original.
177 $this->assertEquals( $info['width'], $gis[0], "$name: thumb actual width check for $size");
178 $this->assertEquals( $info['height'], $gis[1], "$name: thumb actual height check for $size");
179 } else {
180 $this->assertEquals( $out[0], $gis[0], "$name: thumb actual width check for $size");
181 $this->assertEquals( $out[1], $gis[1], "$name: thumb actual height check for $size");
182 }
183 }
184 $wgEnableAutoRotation = true;
185 }
186
187 function providerFilesNoAutoRotate() {
188 return array(
189 array(
190 'landscape-plain.jpg',
191 'image/jpeg',
192 array(
193 'width' => 1024,
194 'height' => 768,
195 ),
196 array(
197 '800x600px' => array( 800, 600 ),
198 '9999x800px' => array( 1067, 800 ),
199 '800px' => array( 800, 600 ),
200 '600px' => array( 600, 450 ),
201 )
202 ),
203 array(
204 'portrait-rotated.jpg',
205 'image/jpeg',
206 array(
207 'width' => 1024, // since not rotated
208 'height' => 768, // since not rotated
209 ),
210 array(
211 '800x600px' => array( 800, 600 ),
212 '9999x800px' => array( 1067, 800 ),
213 '800px' => array( 800, 600 ),
214 '600px' => array( 600, 450 ),
215 )
216 )
217 );
218 }
219
220
221 const TEST_WIDTH = 100;
222 const TEST_HEIGHT = 200;
223
224 /**
225 * @dataProvider provideBitmapExtractPreRotationDimensions
226 */
227 function testBitmapExtractPreRotationDimensions( $rotation, $expected ) {
228 $result = $this->handler->extractPreRotationDimensions( array(
229 'physicalWidth' => self::TEST_WIDTH,
230 'physicalHeight' => self::TEST_HEIGHT,
231 ), $rotation );
232 $this->assertEquals( $expected, $result );
233 }
234
235 function provideBitmapExtractPreRotationDimensions() {
236 return array(
237 array(
238 0,
239 array( self::TEST_WIDTH, self::TEST_HEIGHT )
240 ),
241 array(
242 90,
243 array( self::TEST_HEIGHT, self::TEST_WIDTH )
244 ),
245 array(
246 180,
247 array( self::TEST_WIDTH, self::TEST_HEIGHT )
248 ),
249 array(
250 270,
251 array( self::TEST_HEIGHT, self::TEST_WIDTH )
252 ),
253 );
254 }
255 }
256