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