Index: branches/wmf/1.16wmf4/extensions/PagedTiffHandler/tests/testImages/truncated.tiff |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: branches/wmf/1.16wmf4/extensions/PagedTiffHandler/tests/testImages/truncated.tiff |
___________________________________________________________________ |
Added: svn:mime-type |
1 | 1 | + application/octet-stream |
Index: branches/wmf/1.16wmf4/extensions/PagedTiffHandler/tests/PagedTiffHandlerTest.php |
— | — | @@ -3,7 +3,7 @@ |
4 | 4 | * To get this working you must |
5 | 5 | * - set a valid path to PEAR |
6 | 6 | * - check upload size in php.ini: Multipage.tiff needs at least 3M |
7 | | - * - Upload the image caspian.tif without PagedTiffHandler being active |
| 7 | + * - Upload the image truncated.tiff without PagedTiffHandler being active |
8 | 8 | * Caution: you need to allow tiff for upload: |
9 | 9 | * $wgFileExtensions[] = 'tiff'; |
10 | 10 | * $wgFileExtensions[] = 'tif'; |
— | — | @@ -26,76 +26,87 @@ |
27 | 27 | |
28 | 28 | private $handler; |
29 | 29 | private $image; |
30 | | - private $preCheckError; |
| 30 | + private $preCheckError = false; |
31 | 31 | |
| 32 | + function upload( $title, $path ) { |
| 33 | + echo "$title seems not to be present in the wiki. Trying to upload from $path.\n"; |
| 34 | + $image = wfLocalFile( $title ); |
| 35 | + $archive = $image->publish( $path ); |
| 36 | + $image->recordUpload( $archive->value, "Test file used for PagedTiffHandler unit test", "No license" ); |
| 37 | + if( WikiError::isError( $archive ) || !$archive->isGood() ) |
| 38 | + { |
| 39 | + echo "Something went wrong. Please manually upload $path\n"; |
| 40 | + return false; |
| 41 | + } else { |
| 42 | + echo "Upload was successful.\n"; |
| 43 | + return $image; |
| 44 | + } |
| 45 | + } |
| 46 | + |
32 | 47 | function setUp( $autoUpload = false ) { |
33 | 48 | global $wgTitle; |
34 | 49 | $wgTitle = Title::newFromText( 'PagedTiffHandler_UnitTest' ); |
35 | 50 | |
36 | 51 | $this->handler = new PagedTiffHandler(); |
| 52 | + |
37 | 53 | if ( !file_exists( dirname( __FILE__ ) . '/testImages' ) ) { |
38 | 54 | echo "testImages directory cannot be found.\n"; |
39 | 55 | $this->preCheckError = true; |
| 56 | + return false; |
40 | 57 | } |
41 | | - if ( !file_exists( dirname( __FILE__ ) . '/testImages/caspian.tif' ) ) { |
42 | | - echo "testImages/caspian.tif cannot be found.\n"; |
| 58 | + |
| 59 | + $this->multipage_path = dirname(__FILE__) . '/testImages/multipage.tiff'; |
| 60 | + $this->truncated_path = dirname(__FILE__) . '/testImages/truncated.tiff'; |
| 61 | + $this->test_path = dirname(__FILE__) . '/testImages/test.tif'; |
| 62 | + |
| 63 | + if ( !file_exists( $this->truncated_path ) ) { |
| 64 | + echo "{$this->truncated_path} cannot be found.\n"; |
43 | 65 | $this->preCheckError = true; |
| 66 | + return false; |
44 | 67 | } |
45 | | - if ( !file_exists( dirname( __FILE__ ) . '/testImages/multipage.tiff' ) ) { |
46 | | - echo "testImages/Multipage.tif cannot be found.\n"; |
| 68 | + |
| 69 | + if ( !file_exists( $this->multipage_path ) ) { |
| 70 | + echo "{$this->multipage_path} cannot be found.\n"; |
47 | 71 | $this->preCheckError = true; |
| 72 | + return false; |
48 | 73 | } |
49 | 74 | |
50 | | - $caspianTitle = Title::newFromText('Image:Caspian.tif'); |
51 | | - $this->image = wfFindFile($caspianTitle); |
52 | | - if (!$this->image) |
53 | | - { |
54 | | - if ($autoUpload) |
55 | | - { |
56 | | - echo "testImages/caspian.tif seems not to be present in the wiki. Trying to upload.\n"; |
57 | | - $this->image = wfLocalFile( $caspianTitle ); |
58 | | - $archive = $this->image->publish( dirname(__FILE__) . '/testImages/caspian.tif' ); |
59 | | - $this->image->recordUpload( $archive->value, "Test file used for PagedTiffHandler unit test", "No license" ); |
60 | | - if( WikiError::isError( $archive ) || !$archive->isGood() ) |
61 | | - { |
62 | | - echo "Something went wrong. Please manually upload testImages/caspian.tif\n"; |
63 | | - $this->preCheckError = true; |
64 | | - } |
65 | | - else |
66 | | - { |
67 | | - echo "Upload was successful.\n"; |
68 | | - } |
69 | | - } |
70 | | - else |
71 | | - { |
72 | | - echo "Please upload the image testImages/caspian.tif into the wiki\n"; |
| 75 | + if ( !file_exists( $this->test_path ) ) { |
| 76 | + echo "{$this->test_path} cannot be found.\n"; |
| 77 | + $this->preCheckError = true; |
| 78 | + return false; |
| 79 | + } |
| 80 | + |
| 81 | + $truncatedTitle = Title::newFromText('Image:Truncated.tiff'); |
| 82 | + $this->truncated_image = wfFindFile($truncatedTitle); |
| 83 | + if ( !$this->truncated_image && $autoUpload ) { |
| 84 | + $this->truncated_image = $this->upload( $truncatedTitle, $this->truncated_path ); |
| 85 | + |
| 86 | + if ( !$this->truncated_image ) { |
73 | 87 | $this->preCheckError = true; |
| 88 | + return false; |
74 | 89 | } |
75 | | - |
76 | 90 | } |
77 | 91 | |
78 | 92 | $multipageTitle = Title::newFromText( 'Image:Multipage.tiff' ); |
79 | | - $this->image = wfFindFile( $multipageTitle ); |
80 | | - if ( !$this->image ) { |
81 | | - if ( $autoUpload ) { |
82 | | - echo "testImages/multipage.tiff seems not to be present in the wiki. Trying to upload.\n"; |
83 | | - $this->image = wfLocalFile( $multipageTitle ); |
84 | | - $archive = $this->image->publish( dirname(__FILE__) . '/testImages/multipage.tiff' ); |
85 | | - $this->image->recordUpload( $archive->value, 'Test file used for PagedTiffHandler unit test', 'No license' ); |
86 | | - if( WikiError::isError( $archive ) || !$archive->isGood() ) { |
87 | | - echo "Something went wrong. Please manually upload testImages/multipage.tiff\n"; |
88 | | - $this->preCheckError = true; |
89 | | - } else { |
90 | | - echo "Upload was successful.\n"; |
91 | | - } |
92 | | - } else { |
93 | | - echo "Please upload the image testImages/multipage.tiff into the wiki\n"; |
| 93 | + $this->multipage_image = wfFindFile( $multipageTitle ); |
| 94 | + if ( !$this->multipage_image && $autoUpload ) { |
| 95 | + $this->multipage_image = $this->upload( $multipageTitle, $this->multipage_path ); |
| 96 | + |
| 97 | + if ( !$this->multipage_image ) { |
94 | 98 | $this->preCheckError = true; |
| 99 | + return false; |
95 | 100 | } |
96 | | - |
97 | 101 | } |
98 | 102 | |
99 | | - $this->path = dirname(__FILE__) . '/testImages/multipage.tiff'; |
| 103 | + // force re-reading of meta-data |
| 104 | + $truncated_tiff = $this->handler->getTiffImage( $this->truncated_image, $this->truncated_path ); |
| 105 | + $truncated_tiff->resetMetaData(); |
| 106 | + |
| 107 | + $multipage_tiff = $this->handler->getTiffImage( $this->multipage_image, $this->multipage_path ); |
| 108 | + $multipage_tiff->resetMetaData(); |
| 109 | + |
| 110 | + return !$this->preCheckError; |
100 | 111 | } |
101 | 112 | |
102 | 113 | function runTest() { |
— | — | @@ -104,6 +115,11 @@ |
105 | 116 | if ( $this->preCheckError ) { |
106 | 117 | return false; |
107 | 118 | } |
| 119 | + |
| 120 | + // ---- Metdata initialization |
| 121 | + $this->handler->getMetadata( $this->multipage_image, $this->multipage_path ); |
| 122 | + $this->handler->getMetadata( $this->truncated_image, $this->truncated_path ); |
| 123 | + |
108 | 124 | // ---- Parameter handling and lossy parameter |
109 | 125 | // validateParam |
110 | 126 | $this->assertTrue( $this->handler->validateParam( 'lossy', '0' ) ); |
— | — | @@ -112,18 +128,20 @@ |
113 | 129 | $this->assertTrue( $this->handler->validateParam( 'lossy', 'true' ) ); |
114 | 130 | $this->assertTrue( $this->handler->validateParam( 'lossy', 'lossy' ) ); |
115 | 131 | $this->assertTrue( $this->handler->validateParam( 'lossy', 'lossless' ) ); |
| 132 | + |
116 | 133 | // normaliseParams |
117 | 134 | // here, boxfit behavior is tested |
118 | 135 | $params = array( 'width' => '100', 'height' => '100', 'page' => '4' ); |
119 | | - $this->handler->normaliseParams( $this->image, $params ); |
| 136 | + $this->assertTrue( $this->handler->normaliseParams( $this->multipage_image, $params ) ); |
120 | 137 | $this->assertEquals( $params['height'], 75 ); |
121 | 138 | // lossy and lossless |
122 | 139 | $params = array('width'=>'100', 'height'=>'100', 'page'=>'1'); |
123 | | - $this->handler->normaliseParams($this->image, $params ); |
| 140 | + $this->handler->normaliseParams($this->multipage_image, $params ); |
124 | 141 | $this->assertEquals($params['lossy'], 'lossy'); |
125 | 142 | $params = array('width'=>'100', 'height'=>'100', 'page'=>'2'); |
126 | | - $this->handler->normaliseParams($this->image, $params ); |
| 143 | + $this->handler->normaliseParams($this->multipage_image, $params ); |
127 | 144 | $this->assertEquals($params['lossy'], 'lossless'); |
| 145 | + |
128 | 146 | // makeParamString |
129 | 147 | $this->assertEquals( |
130 | 148 | $this->handler->makeParamString( |
— | — | @@ -135,16 +153,18 @@ |
136 | 154 | ), |
137 | 155 | 'lossless-page4-100px' |
138 | 156 | ); |
| 157 | + |
139 | 158 | // ---- File upload checks and Thumbnail transformation |
140 | 159 | // check |
141 | 160 | // TODO: check other images |
142 | | - $this->assertTrue( $this->handler->check( 'multipage.tiff', $this->path, $error ) ); |
143 | | - $this->handler->check( 'Caspian.tif', dirname( __FILE__ ) . '/testImages/caspian.tif', $error ); |
| 161 | + $this->assertTrue( $this->handler->check( 'multipage.tiff', $this->multipage_path, $error ) ); |
| 162 | + $this->assertFalse( $this->handler->check( 'Truncated.tiff', $this->truncated_path, $error ) ); |
144 | 163 | $this->assertEquals( $error, 'tiff_bad_file' ); |
145 | 164 | // doTransform |
146 | | - $this->handler->doTransform( $this->image, dirname(__FILE__) . '/testImages/test.tif', 'test.tif', array( 'width' => 100, 'height' => 100 ) ); |
147 | | - $error = $this->handler->doTransform( wfFindFile( Title::newFromText( 'Image:Caspian.tif' ) ), dirname( __FILE__ ) . '/testImages/caspian.tif', 'Caspian.tif', array( 'width' => 100, 'height' => 100 ) ); |
| 165 | + $this->handler->doTransform( $this->multipage_image, $this->test_path, 'Test.tif', array( 'width' => 100, 'height' => 100 ) ); |
| 166 | + $error = $this->handler->doTransform( wfFindFile( Title::newFromText( 'Image:Truncated.tiff' ) ), $this->truncated_path, 'Truncated.tiff', array( 'width' => 100, 'height' => 100 ) ); |
148 | 167 | $this->assertEquals( $error->textMsg, wfMsg( 'thumbnail_error', wfMsg( 'tiff_bad_file' ) ) ); |
| 168 | + |
149 | 169 | // ---- Image information |
150 | 170 | // getThumbType |
151 | 171 | $type = $this->handler->getThumbType( '.tiff', 'image/tiff', array( 'lossy' => 'lossy' ) ); |
— | — | @@ -157,44 +177,52 @@ |
158 | 178 | |
159 | 179 | // getLongDesc |
160 | 180 | if ( $wgLanguageCode == 'de' ) { |
161 | | - $this->assertEquals( $this->handler->getLongDesc( $this->image ), wfMsg( 'tiff-file-info-size', '1.024', '768', '2,64 MB', 'image/tiff', '1' ) ); |
| 181 | + $this->assertEquals( $this->handler->getLongDesc( $this->multipage_image ), wfMsg( 'tiff-file-info-size', '1.024', '768', '2,64 MB', 'image/tiff', '1' ) ); |
162 | 182 | } else { |
163 | 183 | // English |
164 | | - $this->assertEquals( $this->handler->getLongDesc( $this->image ), wfMsg( 'tiff-file-info-size', '1,024', '768', '2.64 MB', 'image/tiff', '1' ) ); |
| 184 | + $this->assertEquals( $this->handler->getLongDesc( $this->multipage_image ), wfMsg( 'tiff-file-info-size', '1,024', '768', '2.64 MB', 'image/tiff', '1' ) ); |
165 | 185 | } |
| 186 | + |
166 | 187 | // pageCount |
167 | | - $this->assertEquals( $this->handler->pageCount( $this->image ), 7 ); |
| 188 | + $this->assertEquals( $this->handler->pageCount( $this->multipage_image ), 7 ); |
168 | 189 | // getPageDimensions |
169 | | - $this->assertEquals( $this->handler->getPageDimensions( $this->image, 0 ), array( 'width' => 1024, 'height' => 768 ) ); |
170 | | - $this->assertEquals( $this->handler->getPageDimensions( $this->image, 1 ), array( 'width' => 1024, 'height' => 768 ) ); |
171 | | - $this->assertEquals( $this->handler->getPageDimensions( $this->image, 2 ), array( 'width' => 640, 'height' => 564 ) ); |
172 | | - $this->assertEquals( $this->handler->getPageDimensions( $this->image, 3 ), array( 'width' => 1024, 'height' => 563 ) ); |
173 | | - $this->assertEquals( $this->handler->getPageDimensions( $this->image, 4 ), array( 'width' => 1024, 'height' => 768 ) ); |
174 | | - $this->assertEquals( $this->handler->getPageDimensions( $this->image, 5 ), array( 'width' => 1024, 'height' => 768 ) ); |
175 | | - $this->assertEquals( $this->handler->getPageDimensions( $this->image, 6 ), array( 'width' => 1024, 'height' => 768 ) ); |
176 | | - $this->assertEquals( $this->handler->getPageDimensions( $this->image, 7 ), array( 'width' => 768, 'height' => 1024 ) ); |
| 190 | + $this->assertEquals( $this->handler->getPageDimensions( $this->multipage_image, 0 ), array( 'width' => 1024, 'height' => 768 ) ); |
| 191 | + $this->assertEquals( $this->handler->getPageDimensions( $this->multipage_image, 1 ), array( 'width' => 1024, 'height' => 768 ) ); |
| 192 | + $this->assertEquals( $this->handler->getPageDimensions( $this->multipage_image, 2 ), array( 'width' => 640, 'height' => 564 ) ); |
| 193 | + $this->assertEquals( $this->handler->getPageDimensions( $this->multipage_image, 3 ), array( 'width' => 1024, 'height' => 563 ) ); |
| 194 | + $this->assertEquals( $this->handler->getPageDimensions( $this->multipage_image, 4 ), array( 'width' => 1024, 'height' => 768 ) ); |
| 195 | + $this->assertEquals( $this->handler->getPageDimensions( $this->multipage_image, 5 ), array( 'width' => 1024, 'height' => 768 ) ); |
| 196 | + $this->assertEquals( $this->handler->getPageDimensions( $this->multipage_image, 6 ), array( 'width' => 1024, 'height' => 768 ) ); |
| 197 | + $this->assertEquals( $this->handler->getPageDimensions( $this->multipage_image, 7 ), array( 'width' => 768, 'height' => 1024 ) ); |
177 | 198 | // return dimensions of last page if page number is too high |
178 | | - $this->assertEquals( $this->handler->getPageDimensions( $this->image, 8 ), array( 'width' => 768, 'height' => 1024 ) ); |
| 199 | + $this->assertEquals( $this->handler->getPageDimensions( $this->multipage_image, 8 ), array( 'width' => 768, 'height' => 1024 ) ); |
179 | 200 | // isMultiPage |
180 | | - $this->assertTrue( $this->handler->isMultiPage( $this->image ) ); |
| 201 | + $this->assertTrue( $this->handler->isMultiPage( $this->multipage_image ) ); |
181 | 202 | |
182 | 203 | // ---- Metadata handling |
183 | 204 | // getMetadata |
184 | | - $metadata = $this->handler->getMetadata( false, $this->path ); |
| 205 | + $metadata = $this->handler->getMetadata( false, $this->multipage_path ); |
185 | 206 | $this->assertTrue( strpos( $metadata, '"page_amount";i:7' ) !== false ); |
186 | 207 | // isMetadataValid |
187 | | - $this->assertTrue( $this->handler->isMetadataValid( $this->image, $metadata ) ); |
| 208 | + $this->assertTrue( $this->handler->isMetadataValid( $this->multipage_image, $metadata ) ); |
188 | 209 | // getMetaArray |
189 | | - $metaArray = $this->handler->getMetaArray( $this->image ); |
| 210 | + $metaArray = $this->handler->getMetaArray( $this->multipage_image ); |
190 | 211 | |
191 | 212 | $this->assertEquals( $metaArray['page_amount'], 7 ); |
192 | 213 | //this is also strtolower in PagedTiffHandler::getThumbExtension |
193 | 214 | $this->assertEquals( strtolower( $metaArray['page_data'][1]['alpha'] ), 'false' ); |
194 | 215 | $this->assertEquals( strtolower( $metaArray['page_data'][2]['alpha'] ), 'true' ); |
195 | | - $this->assertEquals( $metaArray['exif']['PhotometricInterpretation'], 2 ); //RGB |
| 216 | + |
| 217 | + $interp = $metaArray['exif']['PhotometricInterpretation']; |
| 218 | + $this->assertTrue( $interp == 2 || $interp == 'RGB' ); //RGB |
196 | 219 | // formatMetadata |
197 | | - $formattedMetadata = $this->handler->formatMetadata( $this->image ); |
198 | | - $this->assertEquals( $formattedMetadata['collapsed'][3]['value'], 'RGB' ); //XXX: brittle, index might change. |
| 220 | + $formattedMetadata = $this->handler->formatMetadata( $this->multipage_image ); |
| 221 | + |
| 222 | + foreach ( $formattedMetadata['collapsed'] as $k => $e ) { |
| 223 | + if ( $e['id'] == 'exif-photometricinterpretation' ) { |
| 224 | + $this->assertEquals( $e['value'], 'RGB' ); |
| 225 | + } |
| 226 | + } |
199 | 227 | } |
200 | 228 | |
201 | 229 | } |
Index: branches/wmf/1.16wmf4/extensions/PagedTiffHandler/PagedTiffHandler_body.php |
— | — | @@ -213,7 +213,9 @@ |
214 | 214 | $params['lossy'] = 'lossless'; |
215 | 215 | } |
216 | 216 | } else { |
217 | | - if ( ( strtolower( $data['page_data'][$params['page']]['alpha'] ) == 'true' ) ) { |
| 217 | + $page = $params['page']; |
| 218 | + |
| 219 | + if ( ( strtolower( $data['page_data'][$page]['alpha'] ) == 'true' ) ) { |
218 | 220 | $params['lossy'] = 'lossless'; |
219 | 221 | } else { |
220 | 222 | $params['lossy'] = 'lossy'; |
— | — | @@ -436,7 +438,15 @@ |
437 | 439 | * @return string |
438 | 440 | */ |
439 | 441 | function getMetadata( $image, $path ) { |
440 | | - return serialize( $this->getTiffImage( $image, $path )->retrieveMetaData() ); |
| 442 | + if ( !$image ) { |
| 443 | + return serialize( $this->getTiffImage( $image, $path )->retrieveMetaData() ); |
| 444 | + } else { |
| 445 | + if ( !isset( $image->tiffMetaArray ) ) { |
| 446 | + $image->tiffMetaArray = $this->getTiffImage( $image, $path )->retrieveMetaData(); |
| 447 | + } |
| 448 | + |
| 449 | + return serialize( $image->tiffMetaArray ); |
| 450 | + } |
441 | 451 | } |
442 | 452 | |
443 | 453 | /** |
— | — | @@ -480,7 +490,7 @@ |
481 | 491 | // don't try to re-render until the error is resolved! |
482 | 492 | return true; |
483 | 493 | } |
484 | | - if ( isset( $meta['page_amount'] ) && isset( $meta['page_data'] ) ) { |
| 494 | + if ( !empty( $meta['page_amount'] ) && !empty( $meta['page_data'] ) ) { |
485 | 495 | return true; |
486 | 496 | } |
487 | 497 | } |
Index: branches/wmf/1.16wmf4/extensions/PagedTiffHandler/PagedTiffHandler.i18n.php |
— | — | @@ -51,9 +51,11 @@ |
52 | 52 | 'tiff-file-info-size' => 'Information about the image dimensions etc. on image page. Extended by page information', |
53 | 53 | ); |
54 | 54 | |
55 | | -/** Message documentation (Message documentation) */ |
| 55 | +/** Message documentation (Message documentation) |
| 56 | + * @author The Evil IP address |
| 57 | + */ |
56 | 58 | $messages['qqq'] = array( |
57 | | - 'tiff-desc' => 'Short description of the extension, shown in [[Special:Version]]. Do not translate or change links.', |
| 59 | + 'tiff-desc' => '{{desc}}', |
58 | 60 | 'tiff_no_metadata' => 'Error message shown when no metadata extraction is not possible', |
59 | 61 | 'tiff_page_error' => 'Error message shown when page number is out of range', |
60 | 62 | 'tiff_too_many_embed_files' => 'Error message shown when the uploaded image contains too many embedded files.', |
— | — | @@ -335,6 +337,29 @@ |
336 | 338 | 'tiff-file-info-size' => '(pagina $5, $1 × $2 pixel, grandor del file: $3, typo MIME: $4)', |
337 | 339 | ); |
338 | 340 | |
| 341 | +/** Indonesian (Bahasa Indonesia) |
| 342 | + * @author Farras |
| 343 | + */ |
| 344 | +$messages['id'] = array( |
| 345 | + 'tiff-desc' => 'Pengatur untuk melihat berkas TIFF dalam mode gambar', |
| 346 | + 'tiff_no_metadata' => 'Tidak dapat memeroleh metadata dari TIFF', |
| 347 | + 'tiff_page_error' => 'Nomor halaman di luar batas', |
| 348 | + 'tiff_too_many_embed_files' => 'Gambar berisi terlalu banyak berkas tertanam.', |
| 349 | + 'tiff_sourcefile_too_large' => 'Resolusi berkas sumber terlalu besar. |
| 350 | +Miniatur tidak akan dibuat.', |
| 351 | + 'tiff_targetfile_too_large' => 'Resolusi berkas tujuan terlalu besar. |
| 352 | +Miniatur tidak akan dibuat.', |
| 353 | + 'tiff_file_too_large' => 'Berkas unggahan terlalu besar dan ditolak.', |
| 354 | + 'tiff_out_of_service' => 'Berkas unggahan tidak dapat diproses. |
| 355 | +ImageMagick tidak tersedia.', |
| 356 | + 'tiff_too_much_meta' => 'Metadata memakan banyak ruang.', |
| 357 | + 'tiff_error_cached' => 'Berkas hanya dapat ditampilkan ulang setelah jeda penembolokan.', |
| 358 | + 'tiff_size_error' => 'Ukuran berkas yang dilaporkan tidak sama dengan ukuran berkas aslinya.', |
| 359 | + 'tiff_script_detected' => 'Berkas unggahan berisi skrip.', |
| 360 | + 'tiff_bad_file' => 'Berkas unggahan berisi kesalahan.', |
| 361 | + 'tiff-file-info-size' => '(halaman $5, $1 × $2 piksel, ukuran berkas: $3, tipe MIME: $4)', |
| 362 | +); |
| 363 | + |
339 | 364 | /** Japanese (日本語) |
340 | 365 | * @author Aotake |
341 | 366 | * @author Naohiro19 |
Index: branches/wmf/1.16wmf4/extensions/PagedTiffHandler/PagedTiffHandler.php |
— | — | @@ -69,6 +69,18 @@ |
70 | 70 | '/^identify: .+?: unknown field with tag .+? encountered/' |
71 | 71 | ); |
72 | 72 | |
| 73 | +$wgTiffTiffinfoRejectMessages = array( |
| 74 | + '/.*: Cannot read TIFF header\.$/', |
| 75 | + '/.*: Not a TIFF or MDI file, bad magic number .+\.$/', |
| 76 | + '/.*: Error fetching data for field .+\.$/', |
| 77 | + '/TIFFReadDirectory: .*: Can not read TIFF directory count\.$/', |
| 78 | +); |
| 79 | + |
| 80 | +$wgTiffTiffinfoBypassMessages = array( |
| 81 | + '/^TIFFReadCustomDirectory: .+: unknown field with tag .+? encountered\./', |
| 82 | + '/^TIFFReadCustomDirectory: .+: wrong data type .*; tag ignored\./', |
| 83 | +); |
| 84 | + |
73 | 85 | // Use PHP-TiffReader |
74 | 86 | // This is still experimental |
75 | 87 | $wgTiffUseTiffReader = false; |
— | — | @@ -79,11 +91,15 @@ |
80 | 92 | $wgImageMagickIdentifyCommand = '/usr/bin/identify'; |
81 | 93 | // Path to exiv2 |
82 | 94 | $wgTiffExivCommand = '/usr/bin/exiv2'; |
83 | | -// Use exiv2? |
| 95 | +// Use exiv2? if false, MediaWiki's internal EXIF parser will be used |
84 | 96 | $wgTiffUseExiv = false; |
| 97 | +//path to tiffinfo |
| 98 | +$wgTiffTiffinfoCommand = '/usr/bin/tiffinfo'; |
| 99 | +// Use tiffinfo? if false, ImageMagick's identify command will be used |
| 100 | +$wgTiffUseTiffinfo = false; |
85 | 101 | // Path to vips |
86 | 102 | $wgTiffVipsCommand = '/usr/bin/vips'; |
87 | | -// Use vips |
| 103 | +// Use vips? if false, ImageMagick's convert command will be used |
88 | 104 | $wgTiffUseVips = false; |
89 | 105 | // Maximum number of embedded files in tiff image |
90 | 106 | $wgTiffMaxEmbedFiles = 10000; |
— | — | @@ -107,5 +123,7 @@ |
108 | 124 | $wgMediaHandlers['image/tiff'] = 'PagedTiffHandler'; |
109 | 125 | $wgHooks['UploadVerification'][] = 'PagedTiffHandler::check'; |
110 | 126 | $wgHooks['LanguageGetMagic'][] = 'PagedTiffHandler::addTiffLossyMagicWordLang'; |
| 127 | + |
111 | 128 | //$wgHooks['PagedTiffHandlerRenderCommand'][] = 'PagedTiffHandler::renderCommand'; |
112 | | -//$wgHooks['PagedTiffHandlerExivCommand'][] = 'PagedTiffImage::exivCommand'; |
| 129 | +//$wgHooks['PagedTiffHandlerTiffData'][] = 'PagedTiffImage::tiffData'; |
| 130 | +//$wgHooks['PagedTiffHandlerExifData'][] = 'PagedTiffImage::exifData'; |
Index: branches/wmf/1.16wmf4/extensions/PagedTiffHandler/PagedTiffHandler.image.php |
— | — | @@ -63,13 +63,17 @@ |
64 | 64 | public static function getPageSize( $data, $page ) { |
65 | 65 | if ( isset( $data['page_data'][$page] ) ) { |
66 | 66 | return array( |
67 | | - 'width' => $data['page_data'][$page]['width'], |
68 | | - 'height' => $data['page_data'][$page]['height'] |
| 67 | + 'width' => intval( $data['page_data'][$page]['width'] ), |
| 68 | + 'height' => intval( $data['page_data'][$page]['height'] ) |
69 | 69 | ); |
70 | 70 | } |
71 | 71 | return false; |
72 | 72 | } |
73 | 73 | |
| 74 | + public function resetMetaData() { |
| 75 | + $this->_meta = null; |
| 76 | + } |
| 77 | + |
74 | 78 | /** |
75 | 79 | * Reads metadata of the tiff file via shell command and returns an associative array. |
76 | 80 | * layout: |
— | — | @@ -81,13 +85,34 @@ |
82 | 86 | */ |
83 | 87 | public function retrieveMetaData() { |
84 | 88 | global $wgImageMagickIdentifyCommand, $wgTiffExivCommand, $wgTiffUseExiv; |
| 89 | + global $wgTiffUseTiffinfo, $wgTiffTiffinfoCommand; |
85 | 90 | |
86 | 91 | if ( $this->_meta === null ) { |
87 | | - if ( $wgImageMagickIdentifyCommand ) { |
| 92 | + wfProfileIn( 'PagedTiffImage::retrieveMetaData' ); |
88 | 93 | |
89 | | - wfProfileIn( 'PagedTiffImage::retrieveMetaData' ); |
90 | | - |
91 | | - // ImageMagick is used to get the basic metadata of individual pages |
| 94 | + //fetch base info: number of pages, size and alpha for each page. |
| 95 | + //run hooks first, then optionally tiffinfo or, per default, ImageMagic's identify command |
| 96 | + if ( !wfRunHooks( 'PagedTiffHandlerTiffData', array( $this->mFilename, &$this->_meta ) ) ) { |
| 97 | + wfDebug( __METHOD__ . ": hook PagedTiffHandlerTiffData overrides TIFF data extraction\n" ); |
| 98 | + } else if ( $wgTiffUseTiffinfo ) { |
| 99 | + // read TIFF directories using libtiff's tiffinfo, see |
| 100 | + // http://www.libtiff.org/man/tiffinfo.1.html |
| 101 | + $cmd = wfEscapeShellArg( $wgTiffTiffinfoCommand ) . |
| 102 | + ' ' . wfEscapeShellArg( $this->mFilename ) . ' 2>&1'; |
| 103 | + |
| 104 | + wfProfileIn( 'tiffinfo' ); |
| 105 | + wfDebug( __METHOD__ . ": $cmd\n" ); |
| 106 | + $dump = wfShellExec( $cmd, $retval ); |
| 107 | + wfProfileOut( 'tiffinfo' ); |
| 108 | + |
| 109 | + if ( $retval ) { |
| 110 | + $data['errors'][] = "tiffinfo command failed: $cmd"; |
| 111 | + wfDebug( __METHOD__ . ": tiffinfo command failed: $cmd\n" ); |
| 112 | + return $data; // fail. we *need* that info |
| 113 | + } |
| 114 | + |
| 115 | + $this->_meta = $this->parseTiffinfoOutput( $dump ); |
| 116 | + } else { |
92 | 117 | $cmd = wfEscapeShellArg( $wgImageMagickIdentifyCommand ) . |
93 | 118 | ' -format "[BEGIN]page=%p\nalpha=%A\nalpha2=%r\nheight=%h\nwidth=%w\ndepth=%z[END]" ' . |
94 | 119 | wfEscapeShellArg( $this->mFilename ) . ' 2>&1'; |
— | — | @@ -96,65 +121,179 @@ |
97 | 122 | wfDebug( __METHOD__ . ": $cmd\n" ); |
98 | 123 | $dump = wfShellExec( $cmd, $retval ); |
99 | 124 | wfProfileOut( 'identify' ); |
| 125 | + |
100 | 126 | if ( $retval ) { |
101 | 127 | $data['errors'][] = "identify command failed: $cmd"; |
102 | 128 | wfDebug( __METHOD__ . ": identify command failed: $cmd\n" ); |
103 | 129 | return $data; // fail. we *need* that info |
104 | 130 | } |
105 | | - $this->_meta = $this->convertDumpToArray( $dump ); |
106 | | - $this->_meta['exif'] = array(); |
107 | 131 | |
108 | | - if ( $wgTiffUseExiv ) { |
109 | | - // read EXIF, XMP, IPTC as name-tag => interpreted data |
110 | | - // -ignore unknown fields |
111 | | - // see exiv2-doc @link http://www.exiv2.org/sample.html |
112 | | - // NOTE: the linux version of exiv2 has a bug: it can only |
113 | | - // read one type of meta-data at a time, not all at once. |
114 | | - $cmd = wfEscapeShellArg( $wgTiffExivCommand ) . |
115 | | - ' -u -psix -Pnt ' . wfEscapeShellArg( $this->mFilename ); |
| 132 | + $this->_meta = $this->parseIdentifyOutput( $dump ); |
| 133 | + } |
116 | 134 | |
117 | | - wfRunHooks( 'PagedTiffHandlerExivCommand', array( &$cmd, $this->mFilename ) ); |
| 135 | + $this->_meta['exif'] = array(); |
118 | 136 | |
119 | | - wfProfileIn( 'exiv2' ); |
120 | | - wfDebug( __METHOD__ . ": $cmd\n" ); |
121 | | - $dump = wfShellExec( $cmd, $retval ); |
122 | | - wfProfileOut( 'exiv2' ); |
| 137 | + //fetch extended info: EXIF/IPTC/XMP |
| 138 | + //run hooks first, then optionally Exiv2 or, per default, the internal EXIF class |
| 139 | + if ( !empty( $this->_meta['errors'] ) ) { |
| 140 | + wfDebug( __METHOD__ . ": found errors, skipping EXIF extraction\n" ); |
| 141 | + } else if ( !wfRunHooks( 'PagedTiffHandlerExifData', array( $this->mFilename, &$this->_meta['exif'] ) ) ) { |
| 142 | + wfDebug( __METHOD__ . ": hook PagedTiffHandlerExifData overrides EXIF extraction\n" ); |
| 143 | + } else if ( $wgTiffUseExiv ) { |
| 144 | + // read EXIF, XMP, IPTC as name-tag => interpreted data |
| 145 | + // -ignore unknown fields |
| 146 | + // see exiv2-doc @link http://www.exiv2.org/sample.html |
| 147 | + // NOTE: the linux version of exiv2 has a bug: it can only |
| 148 | + // read one type of meta-data at a time, not all at once. |
| 149 | + $cmd = wfEscapeShellArg( $wgTiffExivCommand ) . |
| 150 | + ' -u -psix -Pnt ' . wfEscapeShellArg( $this->mFilename ) . ' 2>&1'; |
123 | 151 | |
124 | | - if ( $retval ) { |
125 | | - $data['errors'][] = "exiv command failed: $cmd"; |
126 | | - wfDebug( __METHOD__ . ": exiv command failed: $cmd\n" ); |
127 | | - // don't fail - we are missing info, just report |
128 | | - } |
| 152 | + wfProfileIn( 'exiv2' ); |
| 153 | + wfDebug( __METHOD__ . ": $cmd\n" ); |
| 154 | + $dump = wfShellExec( $cmd, $retval ); |
| 155 | + wfProfileOut( 'exiv2' ); |
129 | 156 | |
130 | | - $result = array(); |
131 | | - preg_match_all( '/(\w+)\s+(.+)/', $dump, $result, PREG_SET_ORDER ); |
| 157 | + if ( $retval ) { |
| 158 | + $data['errors'][] = "exiv command failed: $cmd"; |
| 159 | + wfDebug( __METHOD__ . ": exiv command failed: $cmd\n" ); |
| 160 | + // don't fail - we are missing info, just report |
| 161 | + } |
132 | 162 | |
133 | | - foreach ( $result as $data ) { |
134 | | - $this->_meta['exif'][$data[1]] = $data[2]; |
135 | | - } |
136 | | - } else { |
137 | | - wfDebug( __METHOD__ . ": using internal Exif( {$this->mFilename} )\n" ); |
138 | | - $exif = new Exif( $this->mFilename ); |
139 | | - $data = $exif->getFilteredData(); |
140 | | - if ( $data ) { |
141 | | - $data['MEDIAWIKI_EXIF_VERSION'] = Exif::version(); |
142 | | - $this->_meta['exif'] = $data; |
143 | | - } |
144 | | - } |
145 | | - wfProfileOut( 'PagedTiffImage::retrieveMetaData' ); |
| 163 | + $data = $this->parseExiv2Output( $dump ); |
| 164 | + |
| 165 | + $this->_meta['exif'] = $data; |
| 166 | + } else { |
| 167 | + wfDebug( __METHOD__ . ": using internal Exif( {$this->mFilename} )\n" ); |
| 168 | + $exif = new Exif( $this->mFilename ); |
| 169 | + $data = $exif->getFilteredData(); |
| 170 | + if ( $data ) { |
| 171 | + $data['MEDIAWIKI_EXIF_VERSION'] = Exif::version(); |
| 172 | + $this->_meta['exif'] = $data; |
| 173 | + } |
146 | 174 | } |
| 175 | + wfProfileOut( 'PagedTiffImage::retrieveMetaData' ); |
147 | 176 | } |
148 | 177 | unset( $this->_meta['exif']['Image'] ); |
149 | 178 | unset( $this->_meta['exif']['filename'] ); |
150 | 179 | unset( $this->_meta['exif']['Base filename'] ); |
| 180 | + unset( $this->_meta['exif']['XMLPacket'] ); |
| 181 | + unset( $this->_meta['exif']['ImageResources'] ); |
151 | 182 | return $this->_meta; |
152 | 183 | } |
153 | 184 | |
154 | 185 | /** |
155 | 186 | * helper function of retrieveMetaData(). |
| 187 | + * parses shell return from tiffinfo-command into an array. |
| 188 | + */ |
| 189 | + protected function parseTiffinfoOutput( $dump ) { |
| 190 | + global $wgTiffTiffinfoRejectMessages, $wgTiffTiffinfoBypassMessages; |
| 191 | + |
| 192 | + $dump = preg_replace( '/ Image Length:/', "\n Image Length:", $dump ); #HACK: width and length are given on a single line... |
| 193 | + $rows = preg_split('/[\r\n]+\s*/', $dump); |
| 194 | + |
| 195 | + $data = array(); |
| 196 | + $data['page_data'] = array(); |
| 197 | + |
| 198 | + $entry = array(); |
| 199 | + |
| 200 | + foreach ( $rows as $row ) { |
| 201 | + $row = trim( $row ); |
| 202 | + |
| 203 | + if ( preg_match('/^<|^$/', $row) ) { |
| 204 | + continue; |
| 205 | + } |
| 206 | + |
| 207 | + $error = false; |
| 208 | + |
| 209 | + foreach ( $wgTiffTiffinfoRejectMessages as $pattern ) { |
| 210 | + if ( preg_match( $pattern, trim( $row ) ) ) { |
| 211 | + $data['errors'][] = $row; |
| 212 | + $error = true; |
| 213 | + break; |
| 214 | + } |
| 215 | + } |
| 216 | + |
| 217 | + if ( $error ) continue; |
| 218 | + |
| 219 | + if ( preg_match('/^TIFF Directory at/', $row) ) { |
| 220 | + if ( isset( $entry['page'] ) ) { |
| 221 | + $entry['pixels'] = $entry['height'] * $entry['width']; |
| 222 | + $data['page_data'][$entry['page'] +1] = $entry; |
| 223 | + |
| 224 | + $entry = array(); |
| 225 | + $entry['alpha'] = 'false'; |
| 226 | + } |
| 227 | + } else if ( preg_match('#^(TIFF.*?Directory): (.*?/.*?): (.*)#i', $row, $m) ) { |
| 228 | + $bypass = false; |
| 229 | + $msg = $m[3]; |
| 230 | + |
| 231 | + foreach ( $wgTiffTiffinfoBypassMessages as $pattern ) { |
| 232 | + if ( preg_match( $pattern, trim( $row ) ) ) { |
| 233 | + $bypass = true; |
| 234 | + break; |
| 235 | + } |
| 236 | + } |
| 237 | + |
| 238 | + if ( !$bypass ) { |
| 239 | + $data['warnings'][] = $msg; |
| 240 | + break; |
| 241 | + } |
| 242 | + } else if ( preg_match('/^\s*(.*?)\s*:\s*(.*?)\s*$/', $row, $m) ) { |
| 243 | + $key = $m[1]; |
| 244 | + $value = $m[2]; |
| 245 | + |
| 246 | + if ( $key == 'Page Number' && preg_match('/(\d+)-(\d+)/', $value, $m) ) { |
| 247 | + $data['page_amount'] = (int)$m[2]; |
| 248 | + $entry['page'] = (int)$m[1]; |
| 249 | + } else if ( $key == 'Samples/Pixel' ) { |
| 250 | + if ($value == '4') $entry['alpha'] = 'true'; |
| 251 | + else $entry['alpha'] = 'false'; |
| 252 | + } else if ( $key == 'Extra samples' ) { |
| 253 | + if (preg_match('.*alpha.*', $value)) $entry['alpha'] = 'true'; |
| 254 | + } else if ( $key == 'Image Width' || $key == 'PixelXDimension' ) { |
| 255 | + $entry['width'] = (int)$value; |
| 256 | + } else if ( $key == 'Image Length' || $key == 'PixelYDimension' ) { |
| 257 | + $entry['height'] = (int)$value; |
| 258 | + } |
| 259 | + } else { |
| 260 | + // strange line |
| 261 | + } |
| 262 | + } |
| 263 | + |
| 264 | + if ( !empty( $entry['page'] ) ) { |
| 265 | + $entry['pixels'] = $entry['height'] * $entry['width']; |
| 266 | + $data['page_data'][$entry['page'] +1] = $entry; |
| 267 | + } |
| 268 | + |
| 269 | + if ( !isset( $data['page_amount'] ) ) { |
| 270 | + $data['page_amount'] = count( $data['page_data'] ); |
| 271 | + } |
| 272 | + |
| 273 | + return $data; |
| 274 | + } |
| 275 | + |
| 276 | + /** |
| 277 | + * helper function of retrieveMetaData(). |
| 278 | + * parses shell return from exiv2-command into an array. |
| 279 | + */ |
| 280 | + protected function parseExiv2Output( $dump ) { |
| 281 | + $result = array(); |
| 282 | + preg_match_all( '/^(\w+)\s+(.+)$/m', $dump, $result, PREG_SET_ORDER ); |
| 283 | + |
| 284 | + $data = array(); |
| 285 | + |
| 286 | + foreach ( $result as $row ) { |
| 287 | + $data[$row[1]] = $row[2]; |
| 288 | + } |
| 289 | + |
| 290 | + return $data; |
| 291 | + } |
| 292 | + |
| 293 | + /** |
| 294 | + * helper function of retrieveMetaData(). |
156 | 295 | * parses shell return from identify-command into an array. |
157 | 296 | */ |
158 | | - protected function convertDumpToArray( $dump ) { |
| 297 | + protected function parseIdentifyOutput( $dump ) { |
159 | 298 | global $wgTiffIdentifyRejectMessages, $wgTiffIdentifyBypassMessages; |
160 | 299 | |
161 | 300 | $data = array(); |
Property changes on: branches/wmf/1.16wmf4/extensions/PagedTiffHandler |
___________________________________________________________________ |
Added: svn:mergeinfo |
162 | 301 | Merged /branches/wmf-deployment/extensions/PagedTiffHandler:r60970 |
163 | 302 | Merged /trunk/extensions/PagedTiffHandler:r71187-71620 |
164 | 303 | Merged /trunk/phase3/extensions/PagedTiffHandler:r63545-63546,63549,63643,63764,63897-63901,64113,64509,65387,65391,65555,65590,65650,65816 |