3 use MediaWiki\MainConfigNames
;
6 * Tests related to auto rotation.
11 * @covers \BitmapHandler
12 * @requires extension exif
14 class ExifRotationTest
extends MediaWikiMediaTestCase
{
16 /** @var BitmapHandler */
19 protected function setUp(): void
{
22 $this->handler
= new BitmapHandler();
24 $this->overrideConfigValues( [
25 MainConfigNames
::ShowEXIF
=> true,
26 MainConfigNames
::EnableAutoRotation
=> true,
31 * Mark this test as creating thumbnail files.
34 protected function createsThumbnails() {
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" );
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,
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" );
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 ) ) {
79 'width' => $matches[1],
81 } elseif ( preg_match( '/^(\d+)x(\d+)px$/', $size, $matches ) ) {
83 'width' => $matches[1],
84 'height' => $matches[2]
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
);
96 "$name: thumb reported width check for $size"
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" );
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() {
119 'landscape-plain.jpg',
126 '80x60px' => [ 80, 60 ],
127 '9999x80px' => [ 107, 80 ],
128 '80px' => [ 80, 60 ],
129 '60px' => [ 60, 45 ],
133 'portrait-rotated.jpg',
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,
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 ) ) {
185 'width' => $matches[1],
187 } elseif ( preg_match( '/^(\d+)x(\d+)px$/', $size, $matches ) ) {
189 'width' => $matches[1],
190 'height' => $matches[2]
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() );
207 "$name: thumb reported width check for $size"
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" );
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() {
230 'landscape-plain.jpg',
237 '80x60px' => [ 80, 60 ],
238 '9999x80px' => [ 107, 80 ],
239 '80px' => [ 80, 60 ],
240 '60px' => [ 60, 45 ],
244 'portrait-rotated.jpg',
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
,
271 $this->assertEquals( $expected, $result );
274 public static function provideBitmapExtractPreRotationDimensions() {
278 [ self
::TEST_WIDTH
, self
::TEST_HEIGHT
]
282 [ self
::TEST_HEIGHT
, self
::TEST_WIDTH
]
286 [ self
::TEST_WIDTH
, self
::TEST_HEIGHT
]
290 [ self
::TEST_HEIGHT
, self
::TEST_WIDTH
]