gallery: Fix phan annotation for ImageGalleryBase::getImages
[mediawiki.git] / tests / phpunit / includes / media / ExifRotationTest.php
blob94bea31ca9be94988ce3ab968be51f599a768e5e
1 <?php
3 use MediaWiki\MainConfigNames;
5 /**
6 * Tests related to auto rotation.
8 * @group Media
9 * @group medium
11 * @covers \BitmapHandler
12 * @requires extension exif
14 class ExifRotationTest extends MediaWikiMediaTestCase {
16 /** @var BitmapHandler */
17 private $handler;
19 protected function setUp(): void {
20 parent::setUp();
22 $this->handler = new BitmapHandler();
24 $this->overrideConfigValues( [
25 MainConfigNames::ShowEXIF => true,
26 MainConfigNames::EnableAutoRotation => true,
27 ] );
30 /**
31 * Mark this test as creating thumbnail files.
32 * @inheritDoc
34 protected function createsThumbnails() {
35 return true;
38 /**
39 * @dataProvider provideFiles
41 public function testMetadata( $name, $type, $info ) {
42 if ( !$this->handler->canRotate() ) {
43 $this->markTestSkipped( "This test needs a rasterizer that can auto-rotate." );
45 $file = $this->dataFile( $name, $type );
46 $this->assertEquals( $info['width'], $file->getWidth(), "$name: width check" );
47 $this->assertEquals( $info['height'], $file->getHeight(), "$name: height check" );
50 /**
51 * Same as before, but with auto-rotation set to auto.
53 * This sets scaler to image magick, which we should detect as
54 * supporting rotation.
55 * @dataProvider provideFiles
57 public function testMetadataAutoRotate( $name, $type, $info ) {
58 $this->overrideConfigValues( [
59 MainConfigNames::EnableAutoRotation => null,
60 MainConfigNames::UseImageMagick => true,
61 MainConfigNames::UseImageResize => true,
62 ] );
64 $file = $this->dataFile( $name, $type );
65 $this->assertEquals( $info['width'], $file->getWidth(), "$name: width check" );
66 $this->assertEquals( $info['height'], $file->getHeight(), "$name: height check" );
69 /**
70 * @dataProvider provideFiles
72 public function testRotationRendering( $name, $type, $info, $thumbs ) {
73 if ( !$this->handler->canRotate() ) {
74 $this->markTestSkipped( "This test needs a rasterizer that can auto-rotate." );
76 foreach ( $thumbs as $size => $out ) {
77 if ( preg_match( '/^(\d+)px$/', $size, $matches ) ) {
78 $params = [
79 'width' => $matches[1],
81 } elseif ( preg_match( '/^(\d+)x(\d+)px$/', $size, $matches ) ) {
82 $params = [
83 'width' => $matches[1],
84 'height' => $matches[2]
86 } else {
87 throw new InvalidArgumentException( 'bogus test data format ' . $size );
90 $file = $this->dataFile( $name, $type );
91 $thumb = $file->transform( $params, File::RENDER_NOW | File::RENDER_FORCE );
93 $this->assertEquals(
94 $out[0],
95 $thumb->getWidth(),
96 "$name: thumb reported width check for $size"
98 $this->assertEquals(
99 $out[1],
100 $thumb->getHeight(),
101 "$name: thumb reported height check for $size"
104 $gis = getimagesize( $thumb->getLocalCopyPath() );
105 if ( $out[0] > $info['width'] ) {
106 // Physical image won't be scaled bigger than the original.
107 $this->assertEquals( $info['width'], $gis[0], "$name: thumb actual width check for $size" );
108 $this->assertEquals( $info['height'], $gis[1], "$name: thumb actual height check for $size" );
109 } else {
110 $this->assertEquals( $out[0], $gis[0], "$name: thumb actual width check for $size" );
111 $this->assertEquals( $out[1], $gis[1], "$name: thumb actual height check for $size" );
116 public static function provideFiles() {
117 return [
119 'landscape-plain.jpg',
120 'image/jpeg',
122 'width' => 160,
123 'height' => 120,
126 '80x60px' => [ 80, 60 ],
127 '9999x80px' => [ 107, 80 ],
128 '80px' => [ 80, 60 ],
129 '60px' => [ 60, 45 ],
133 'portrait-rotated.jpg',
134 'image/jpeg',
136 'width' => 120, // as rotated
137 'height' => 160, // as rotated
140 '80x60px' => [ 45, 60 ],
141 '9999x80px' => [ 60, 80 ],
142 '80px' => [ 80, 107 ],
143 '60px' => [ 60, 80 ],
150 * Same as before, but with auto-rotation disabled.
151 * @dataProvider provideFilesNoAutoRotate
153 public function testMetadataNoAutoRotate( $name, $type, $info ) {
154 $this->overrideConfigValue( MainConfigNames::EnableAutoRotation, false );
156 $file = $this->dataFile( $name, $type );
157 $this->assertEquals( $info['width'], $file->getWidth(), "$name: width check" );
158 $this->assertEquals( $info['height'], $file->getHeight(), "$name: height check" );
162 * Same as before, but with auto-rotation set to auto and an image scaler that doesn't support it.
163 * @dataProvider provideFilesNoAutoRotate
165 public function testMetadataAutoRotateUnsupported( $name, $type, $info ) {
166 $this->overrideConfigValues( [
167 MainConfigNames::EnableAutoRotation => null,
168 MainConfigNames::UseImageResize => false,
169 ] );
171 $file = $this->dataFile( $name, $type );
172 $this->assertEquals( $info['width'], $file->getWidth(), "$name: width check" );
173 $this->assertEquals( $info['height'], $file->getHeight(), "$name: height check" );
177 * @dataProvider provideFilesNoAutoRotate
179 public function testRotationRenderingNoAutoRotate( $name, $type, $info, $thumbs ) {
180 $this->overrideConfigValue( MainConfigNames::EnableAutoRotation, false );
182 foreach ( $thumbs as $size => $out ) {
183 if ( preg_match( '/^(\d+)px$/', $size, $matches ) ) {
184 $params = [
185 'width' => $matches[1],
187 } elseif ( preg_match( '/^(\d+)x(\d+)px$/', $size, $matches ) ) {
188 $params = [
189 'width' => $matches[1],
190 'height' => $matches[2]
192 } else {
193 throw new InvalidArgumentException( 'bogus test data format ' . $size );
196 $file = $this->dataFile( $name, $type );
197 $thumb = $file->transform( $params, File::RENDER_NOW | File::RENDER_FORCE );
199 if ( $thumb->isError() ) {
200 /** @var MediaTransformError $thumb */
201 $this->fail( $thumb->toText() );
204 $this->assertEquals(
205 $out[0],
206 $thumb->getWidth(),
207 "$name: thumb reported width check for $size"
209 $this->assertEquals(
210 $out[1],
211 $thumb->getHeight(),
212 "$name: thumb reported height check for $size"
215 $gis = getimagesize( $thumb->getLocalCopyPath() );
216 if ( $out[0] > $info['width'] ) {
217 // Physical image won't be scaled bigger than the original.
218 $this->assertEquals( $info['width'], $gis[0], "$name: thumb actual width check for $size" );
219 $this->assertEquals( $info['height'], $gis[1], "$name: thumb actual height check for $size" );
220 } else {
221 $this->assertEquals( $out[0], $gis[0], "$name: thumb actual width check for $size" );
222 $this->assertEquals( $out[1], $gis[1], "$name: thumb actual height check for $size" );
227 public static function provideFilesNoAutoRotate() {
228 return [
230 'landscape-plain.jpg',
231 'image/jpeg',
233 'width' => 160,
234 'height' => 120,
237 '80x60px' => [ 80, 60 ],
238 '9999x80px' => [ 107, 80 ],
239 '80px' => [ 80, 60 ],
240 '60px' => [ 60, 45 ],
244 'portrait-rotated.jpg',
245 'image/jpeg',
247 'width' => 160, // since not rotated
248 'height' => 120, // since not rotated
251 '80x60px' => [ 80, 60 ],
252 '9999x80px' => [ 107, 80 ],
253 '80px' => [ 80, 60 ],
254 '60px' => [ 60, 45 ],
260 private const TEST_WIDTH = 100;
261 private const TEST_HEIGHT = 200;
264 * @dataProvider provideBitmapExtractPreRotationDimensions
266 public function testBitmapExtractPreRotationDimensions( $rotation, $expected ) {
267 $result = $this->handler->extractPreRotationDimensions( [
268 'physicalWidth' => self::TEST_WIDTH,
269 'physicalHeight' => self::TEST_HEIGHT,
270 ], $rotation );
271 $this->assertEquals( $expected, $result );
274 public static function provideBitmapExtractPreRotationDimensions() {
275 return [
278 [ self::TEST_WIDTH, self::TEST_HEIGHT ]
282 [ self::TEST_HEIGHT, self::TEST_WIDTH ]
285 180,
286 [ self::TEST_WIDTH, self::TEST_HEIGHT ]
289 270,
290 [ self::TEST_HEIGHT, self::TEST_WIDTH ]