Merge "Drop cache interwiki"
[mediawiki.git] / tests / phpunit / includes / media / PNGMetadataExtractorTest.php
blob257c06e84ca5d2c6287c80b9dff92f36f302bcaa
1 <?php
3 /**
4 * @group Media
5 * @covers \PNGMetadataExtractor
6 */
7 class PNGMetadataExtractorTest extends MediaWikiIntegrationTestCase {
8 private const FILE_PATH = __DIR__ . '/../../data/media/';
10 /**
11 * Tests zTXt tag (compressed textual metadata)
12 * @requires extension zlib
14 public function testPngNativetZtxt() {
15 $meta = PNGMetadataExtractor::getMetadata( self::FILE_PATH .
16 'Png-native-test.png' );
17 $expected = "foo bar baz foo foo foo foof foo foo foo foo";
18 $this->assertArrayHasKey( 'text', $meta );
19 $meta = $meta['text'];
20 $this->assertArrayHasKey( 'Make', $meta );
21 $this->assertArrayHasKey( 'x-default', $meta['Make'] );
23 $this->assertEquals( $expected, $meta['Make']['x-default'] );
26 /**
27 * Test tEXt tag (Uncompressed textual metadata)
29 public function testPngNativeText() {
30 $meta = PNGMetadataExtractor::getMetadata( self::FILE_PATH .
31 'Png-native-test.png' );
32 $expected = "Some long image desc";
33 $this->assertArrayHasKey( 'text', $meta );
34 $meta = $meta['text'];
35 $this->assertArrayHasKey( 'ImageDescription', $meta );
36 $this->assertArrayHasKey( 'x-default', $meta['ImageDescription'] );
37 $this->assertArrayHasKey( '_type', $meta['ImageDescription'] );
39 $this->assertEquals( $expected, $meta['ImageDescription']['x-default'] );
42 /**
43 * tEXt tags must be encoded iso-8859-1 (vs iTXt which are utf-8)
44 * Make sure non-ascii characters get converted properly
46 public function testPngNativeTextNonAscii() {
47 $meta = PNGMetadataExtractor::getMetadata( self::FILE_PATH .
48 'Png-native-test.png' );
50 // Note the Copyright symbol here is a utf-8 one
51 // (aka \xC2\xA9) where in the file its iso-8859-1
52 // encoded as just \xA9.
53 $expected = "© 2010 Bawolff";
55 $this->assertArrayHasKey( 'text', $meta );
56 $meta = $meta['text'];
57 $this->assertArrayHasKey( 'Copyright', $meta );
58 $this->assertArrayHasKey( 'x-default', $meta['Copyright'] );
60 $this->assertEquals( $expected, $meta['Copyright']['x-default'] );
63 /**
64 * Given a normal static PNG, check the animation metadata returned.
66 public function testStaticPngAnimationMetadata() {
67 $meta = PNGMetadataExtractor::getMetadata( self::FILE_PATH .
68 'Png-native-test.png' );
70 $this->assertSame( 0, $meta['frameCount'] );
71 $this->assertSame( 1, $meta['loopCount'] );
72 $this->assertSame( 0.0, $meta['duration'] );
75 /**
76 * Given an animated APNG image file
77 * check it gets animated metadata right.
79 public function testApngAnimationMetadata() {
80 $meta = PNGMetadataExtractor::getMetadata( self::FILE_PATH .
81 'Animated_PNG_example_bouncing_beach_ball.png' );
83 $this->assertEquals( 20, $meta['frameCount'] );
84 // Note loop count of 0 = infinity
85 $this->assertSame( 0, $meta['loopCount'] );
86 $this->assertEqualsWithDelta( 1.5, $meta['duration'], 0.00001, '' );
89 public function testPngBitDepth8() {
90 $meta = PNGMetadataExtractor::getMetadata( self::FILE_PATH .
91 'Png-native-test.png' );
93 $this->assertEquals( 8, $meta['bitDepth'] );
96 public function testPngBitDepth1() {
97 $meta = PNGMetadataExtractor::getMetadata( self::FILE_PATH .
98 '1bit-png.png' );
99 $this->assertSame( 1, $meta['bitDepth'] );
102 public function testPngIndexColour() {
103 $meta = PNGMetadataExtractor::getMetadata( self::FILE_PATH .
104 'Png-native-test.png' );
106 $this->assertEquals( 'index-coloured', $meta['colorType'] );
109 public function testPngRgbColour() {
110 $meta = PNGMetadataExtractor::getMetadata( self::FILE_PATH .
111 'rgb-png.png' );
112 $this->assertEquals( 'truecolour-alpha', $meta['colorType'] );
115 public function testPngRgbNoAlphaColour() {
116 $meta = PNGMetadataExtractor::getMetadata( self::FILE_PATH .
117 'rgb-na-png.png' );
118 $this->assertEquals( 'truecolour', $meta['colorType'] );
121 public function testPngGreyscaleColour() {
122 $meta = PNGMetadataExtractor::getMetadata( self::FILE_PATH .
123 'greyscale-png.png' );
124 $this->assertEquals( 'greyscale-alpha', $meta['colorType'] );
127 public function testPngGreyscaleNoAlphaColour() {
128 $meta = PNGMetadataExtractor::getMetadata( self::FILE_PATH .
129 'greyscale-na-png.png' );
130 $this->assertEquals( 'greyscale', $meta['colorType'] );
134 * T286273 -- tEXt chunk replaced by null bytes
136 public function testPngInvalidChunk() {
137 $meta = PNGMetadataExtractor::getMetadata( self::FILE_PATH .
138 'tEXt-invalid-masked.png' );
139 $this->assertEquals( 10, $meta['width'] );
140 $this->assertEquals( 10, $meta['height'] );
144 * T286273 -- oversize chunk
146 public function testPngOversizeChunk() {
147 // Write a temporary file consisting of a normal PNG plus an extra tEXt chunk.
148 // Try to hold the chunk in memory only once.
149 $path = $this->getNewTempFile();
150 copy( self::FILE_PATH . '1bit-png.png', $path );
151 $chunkTypeAndData = "tEXtkey\0value" . str_repeat( '.', 10000000 );
152 $crc = crc32( $chunkTypeAndData );
153 $chunkLength = strlen( $chunkTypeAndData ) - 4;
154 $file = fopen( $path, 'r+' );
155 fseek( $file, -12, SEEK_END );
156 $iend = fread( $file, 12 );
157 fseek( $file, -12, SEEK_END );
158 fwrite( $file, pack( 'N', $chunkLength ) );
159 fwrite( $file, $chunkTypeAndData );
160 fwrite( $file, pack( 'N', $crc ) );
161 fwrite( $file, $iend );
162 fclose( $file );
164 // Extract the metadata
165 $meta = PNGMetadataExtractor::getMetadata( $path );
166 $this->assertEquals( 50, $meta['width'] );
167 $this->assertEquals( 50, $meta['height'] );
169 // Verify that the big chunk didn't end up in the metadata
170 $this->assertLessThan( 100000, strlen( serialize( $meta ) ) );