r71187 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r71186‎ | r71187 | r71188 >
Date:02:12, 17 August 2010
Author:tstarling
Status:deferred
Tags:
Comment:
Copying PagedTiffHandler from trunk to 1.16wmf4.
Modified paths:
  • /branches/wmf/1.16wmf4/extensions/PagedTiffHandler (added) (history)

Diff [purge]

Index: branches/wmf/1.16wmf4/extensions/PagedTiffHandler/TiffReader.php
@@ -0,0 +1,351 @@
 2+<?php
 3+/**
 4+ * Description of TiffReader
 5+ *
 6+ * @author Sebastian Ulbricht <sebastian.ulbricht@gmx.de>
 7+ */
 8+
 9+ // This is still experimental
 10+class TiffReader {
 11+ protected $time = null;
 12+ protected $file = null;
 13+ protected $file_handle = null;
 14+ protected $order = null;
 15+ protected $the_answer = null;
 16+ protected $embed_files = 0;
 17+ protected $ifd_offsets = array();
 18+ protected $real_eof = 0;
 19+ protected $highest_addr = 0;
 20+
 21+ protected $unknown_fields = false;
 22+
 23+ protected $hex = null;
 24+ protected $short = null;
 25+ protected $long = null;
 26+
 27+ public function __construct( $file ) {
 28+ $this->time = microtime( true );
 29+ $this->file = $file;
 30+ // set file-pointer
 31+ $this->file_handle = fopen( $this->file, 'rb' );
 32+ // read the tiff-header
 33+ $this->order = ( fread( $this->file_handle, 2 ) == 'II' );
 34+ if ( $this->order ) {
 35+ $this->hex = 'h*';
 36+ $this->short = 'v*';
 37+ $this->long = 'V*';
 38+ } else {
 39+ $this->hex = 'H*';
 40+ $this->short = 'n*';
 41+ $this->long = 'N*';
 42+ }
 43+ $this->the_answer = unpack( $this->short, fread( $this->file_handle, 2 ) );
 44+ // set the offset of the first ifd
 45+ $offset = unpack( $this->long, fread( $this->file_handle, 4 ) );
 46+ $this->ifd_offsets[]['offset'] = $offset[1];
 47+ fseek( $this->file_handle, 0, SEEK_END );
 48+ $this->real_eof = ftell( $this->file_handle );
 49+ }
 50+
 51+ public function checkScriptAtEnd( $size = 1 ) {
 52+ $size = $size * 1024 * 1024;
 53+ if ( $size > $this->real_eof ) {
 54+ fseek( $this->file_handle, 0, SEEK_SET );
 55+ $chunk = fread( $this->file_handle, $this->real_eof );
 56+ } else {
 57+ fseek( $this->file_handle, ( $this->real_eof - $size ), SEEK_SET );
 58+ $chunk = fread( $this->file_handle, $size );
 59+ }
 60+ # check for HTML doctype
 61+ if ( preg_match( '/<!DOCTYPE *X?HTML/', $chunk ) ) {
 62+ return true;
 63+ }
 64+
 65+ $tags = array( '<a href',
 66+ '<body',
 67+ '<head',
 68+ '<html',
 69+ '<img',
 70+ '<pre',
 71+ '<script',
 72+ '<table',
 73+ '<title' );
 74+ foreach ( $tags as $tag ) {
 75+ if ( false !== strpos( $chunk, $tag ) ) {
 76+ return true;
 77+ }
 78+ }
 79+ # look for script-types
 80+ if ( preg_match( '!type\s*=\s*[\'"]?\s*(?:\w*/)?(?:ecma|java)!sim', $chunk ) ) {
 81+ return true;
 82+ }
 83+
 84+ # look for HTML-style script-urls
 85+ if ( preg_match( '!(?:href|src|data)\s*=\s*[\'"]?\s*(?:ecma|java)script:!sim', $chunk ) ) {
 86+ return true;
 87+ }
 88+
 89+ # look for CSS-style script-urls
 90+ if ( preg_match( '!url\s*\(\s*[\'"]?\s*(?:ecma|java)script:!sim', $chunk ) ) {
 91+ return true;
 92+ }
 93+ }
 94+
 95+ public function checkSize() {
 96+ $diff = $this->real_eof - $this->highest_addr;
 97+ if ( $diff ) {
 98+ if ( $diff < 0 ) {
 99+ return true;
 100+ }
 101+ fseek( $this->file_handle, $this->highest_addr, SEEK_SET );
 102+ $diffstr = fread( $this->file_handle, $diff );
 103+ if ( preg_match( '/^\0+$/', $diffstr ) ) {
 104+ return true;
 105+ }
 106+ return false;
 107+ }
 108+ return true;
 109+ }
 110+
 111+ public function isValidTiff() {
 112+ return $this->the_answer[1] == 42;
 113+ }
 114+
 115+ public function check( $debug = false ) {
 116+ $offset = $this->ifd_offsets[$this->embed_files]['offset'];
 117+ $rounds = 0;
 118+ // loop over all ifd
 119+ while ( $offset && $offset <= $this->real_eof ) {
 120+ // save the offset if it is the highest one
 121+ if ( $offset > $this->highest_addr ) {
 122+ $this->highest_addr = $offset;
 123+ }
 124+ // set file-pointer to address with given offset
 125+ fseek( $this->file_handle, $offset, SEEK_SET );
 126+ // read amount of ifd-entries
 127+ $entries = unpack( $this->short, fread( $this->file_handle, 2 ) );
 128+ if ( !is_array( $entries ) || !isset( $entries[1] ) ) {
 129+ $this->the_answer = 0;
 130+ return false;
 131+ }
 132+ $entries = $entries[1];
 133+
 134+ $address = $offset + 2 + ( $entries * 12 );
 135+ if ( $address > $this->highest_addr ) {
 136+ $this->highest_addr = $address;
 137+ }
 138+
 139+ // run through all entries of this ifd an read them out
 140+ for ( $i = 0; $i < $entries; $i++ ) {
 141+ $tmp = $this->readIFDEntry();
 142+ if ( !$tmp ) {
 143+ return false;
 144+ }
 145+ $this->ifd_offsets[$this->embed_files]['data'][$tmp['tag']] = $tmp;
 146+ }
 147+
 148+ // set the offset of the next ifd or null if this is the last one
 149+ $offset = unpack( $this->long, fread( $this->file_handle, 4 ) );
 150+ if ( !is_array( $offset ) || !isset( $offset[1] ) ) {
 151+ $this->the_answer = 0;
 152+ return false;
 153+ }
 154+ $offset = $offset[1];
 155+ if ( $offset ) {
 156+ $this->ifd_offsets[]['offset'] = $offset;
 157+ }
 158+ $this->embed_files++;
 159+ }
 160+ $this->calculateDataRange();
 161+
 162+ if ( $debug ) {
 163+ echo "<h2>TiffReader-Debug:</h2>\n";
 164+ echo '<b>File: </b>' . $this->file . "<br />\n";
 165+ if ( $this->order ) {
 166+ echo "<b>Byte-Order: </b>little Endian<br />\n";
 167+ } else {
 168+ echo "<b>Byte-Order: </b>big Endian<br />\n";
 169+ }
 170+ echo '<b>Valid Tiff: </b>';
 171+ if ( $this->the_answer[1] == 42 ) {
 172+ echo "yes<br />\n";
 173+ } else {
 174+ echo "no<br />\n";
 175+ }
 176+ echo '<b>Physicaly Size: </b>' . $this->real_eof . " bytes<br />\n";
 177+ echo '<b>Calculated Size: </b>' . $this->highest_addr . " bytes<br />\n";
 178+ echo '<b>Difference in Size: </b>' . ( $this->real_eof - $this->highest_addr ) . " bytes<br />\n";
 179+ echo '<b>Unknown Fields: </b>';
 180+ if ( $this->unknown_fields ) {
 181+ echo "yes<br />\n";
 182+ } else {
 183+ echo "no<br />\n";
 184+ }
 185+ echo "<b>Embed Files: </b>" . $this->embed_files . "<br />\n";
 186+ echo "<b>Runtime: </b>" . round( ( microtime( true ) - $this->time ), 6 ) . " seconds<br />\n";
 187+ }
 188+ }
 189+
 190+ protected function readIFDEntry() {
 191+ $tag = unpack( $this->short, fread( $this->file_handle, 2 ) );
 192+ $type = unpack( $this->short, fread( $this->file_handle, 2 ) );
 193+ $count = unpack( $this->long, fread( $this->file_handle, 4 ) );
 194+ $value = unpack( $this->long, fread( $this->file_handle, 4 ) );
 195+ if ( !is_array( $tag ) || !is_array( $type ) || !is_array( $count ) || !is_array( $value ) ||
 196+ !isset( $tag[1] ) || !isset( $type[1] ) || !isset( $count[1] ) || !isset( $value[1] ) ) {
 197+ $this->the_answer = 0;
 198+ return false;
 199+ }
 200+ return array(
 201+ 'tag' => $tag[1],
 202+ 'type' => $type[1],
 203+ 'count' => $count[1],
 204+ 'value' => $value[1]
 205+ );
 206+ }
 207+
 208+ protected function calculateDataRange() {
 209+ foreach ( $this->ifd_offsets as $number => $ifd ) {
 210+ foreach ( $ifd['data'] as $tag => $data ) {
 211+ // ignore all entries with local values
 212+ if ( ( $data['type'] == 1 && $data['count'] <= 4 ) ||
 213+ ( $data['type'] == 2 && $data['count'] <= 4 ) ||
 214+ ( $data['type'] == 3 && $data['count'] <= 2 ) ||
 215+ ( $data['type'] == 4 && $data['count'] <= 1 ) ||
 216+ ( $data['type'] == 6 && $data['count'] <= 4 ) ||
 217+ ( $data['type'] == 7 && $data['count'] <= 4 ) ||
 218+ ( $data['type'] == 8 && $data['count'] <= 2 ) ||
 219+ ( $data['type'] == 9 && $data['count'] <= 1 ) ) {
 220+ continue;
 221+ }
 222+ // set value size
 223+ switch( $data['type'] ) {
 224+ case 1:
 225+ case 2:
 226+ case 6:
 227+ case 7:
 228+ $size = 1;
 229+ break;
 230+ case 3:
 231+ case 8:
 232+ $size = 2;
 233+ break;
 234+ case 4:
 235+ case 9:
 236+ case 11:
 237+ $size = 4;
 238+ break;
 239+ case 5:
 240+ case 10;
 241+ case 12:
 242+ $size = 8;
 243+ break;
 244+ default:
 245+ $size = 4;
 246+ $this->unknown_fields = true;
 247+ break;
 248+ }
 249+ // calculate the range of memory, the data need
 250+ $size = $data['value'] + ( $size * $data['count'] );
 251+ if ( $size > $this->highest_addr ) {
 252+ $this->highest_addr = $size;
 253+ }
 254+ }
 255+ // check if more calculations needed
 256+ if ( $this->highest_addr == $this->real_eof ) {
 257+ break;
 258+ }
 259+ // check if image data have to calculate
 260+ if ( isset( $ifd['data'][273] ) && isset( $ifd['data'][279] ) ) {
 261+ // set file pointer to the offset for values from field 273
 262+ fseek( $this->file_handle, $ifd['data'][273]['value'], SEEK_SET );
 263+ // get all offsets of the ImageStripes
 264+ $stripes = array();
 265+ if ( $ifd['data'][273]['type'] == 3 ) {
 266+ for ( $i = 0; $i < $ifd['data'][273]['count']; $i++ ) {
 267+ $stripes[] = unpack( $this->short, fread( $this->file_handle, 2 ) );
 268+ }
 269+ } else {
 270+ for ( $i = 0; $i < $ifd['data'][273]['count']; $i++ ) {
 271+ $stripes[] = unpack( $this->long, fread( $this->file_handle, 4 ) );
 272+ }
 273+ }
 274+
 275+ // set file pointer to the offset for values from field 279
 276+ fseek( $this->file_handle, $ifd['data'][279]['value'], SEEK_SET );
 277+ // get all offsets of the StripeByteCounts
 278+ $stripebytes = array();
 279+ if ( $ifd['data'][279]['type'] == 3 ) {
 280+ for ( $i = 0; $i < $ifd['data'][279]['count']; $i++ ) {
 281+ $stripebytes[] = unpack( $this->short, fread( $this->file_handle, 2 ) );
 282+ }
 283+ } else {
 284+ for ( $i = 0; $i < $ifd['data'][279]['count']; $i++ ) {
 285+ $stripebytes[] = unpack( $this->long, fread( $this->file_handle, 4 ) );
 286+ }
 287+ }
 288+ // calculate the memory range of the image stripes
 289+ for ( $i = 0; $i < count( $stripes ); $i++ ) {
 290+ $size = $stripes[$i][1] + $stripebytes[$i][1];
 291+ if ( $size > $this->highest_addr ) {
 292+ $this->highest_addr = $size;
 293+ }
 294+ }
 295+ }
 296+ if ( isset( $ifd['data'][324] ) && isset( $ifd['data'][325] ) ) {
 297+ // set file pointer to the offset for values from field 324
 298+ fseek( $this->file_handle, $ifd['data'][324]['value'], SEEK_SET );
 299+ // get all offsets of the ImageTiles
 300+ $tiles = array();
 301+ for ( $i = 0; $i < $ifd['data'][324]['count']; $i++ ) {
 302+ $tiles[] = unpack( $this->long, fread( $this->file_handle, 4 ) );
 303+ }
 304+
 305+ // set file pointer to the offset for values from field 325
 306+ fseek( $this->file_handle, $ifd['data'][325]['value'], SEEK_SET );
 307+ // get all offsets of the TileByteCounts
 308+ $tilebytes = array();
 309+ if ( $ifd['data'][325]['type'] == 3 ) {
 310+ for ( $i = 0; $i < $ifd['data'][325]['count']; $i++ ) {
 311+ $tilebytes[] = unpack( $this->short, fread( $this->file_handle, 2 ) );
 312+ }
 313+ } else {
 314+ for ( $i = 0; $i < $ifd['data'][325]['count']; $i++ ) {
 315+ $tilebytes[] = unpack( $this->long, fread( $this->file_handle, 4 ) );
 316+ }
 317+ }
 318+ // calculate the memory range of the image tiles
 319+ for ( $i = 0; $i < count( $tiles ); $i++ ) {
 320+ $size = $tiles[$i][1] + $tilebytes[$i][1];
 321+ if ( $size > $this->highest_addr ) {
 322+ $this->highest_addr = $size;
 323+ }
 324+ }
 325+ }
 326+ if ( isset( $ifd['data'][288] ) && isset( $ifd['data'][289] ) ) {
 327+ // set file pointer to the offset for values from field 288
 328+ fseek( $this->file_handle, $ifd['data'][288]['value'], SEEK_SET );
 329+ // get all offsets of the ImageTiles
 330+ $free = array();
 331+ for ( $i = 0; $i < $ifd['data'][288]['count']; $i++ ) {
 332+ $free[] = unpack( $this->long, fread( $this->file_handle, 4 ) );
 333+ }
 334+
 335+ // set file pointer to the offset for values from field 289
 336+ fseek( $this->file_handle, $ifd['data'][289]['value'], SEEK_SET );
 337+ // get all offsets of the TileByteCounts
 338+ $freebytes = array();
 339+ for ( $i = 0; $i < $ifd['data'][289]['count']; $i++ ) {
 340+ $freebytes[] = unpack( $this->long, fread( $this->file_handle, 4 ) );
 341+ }
 342+ // calculate the memory range of the image tiles
 343+ for ( $i = 0; $i < count( $tiles ); $i++ ) {
 344+ $size = $free[$i][1] + $freebytes[$i][1];
 345+ if ( $size > $this->highest_addr ) {
 346+ $this->highest_addr = $size;
 347+ }
 348+ }
 349+ }
 350+ }
 351+ }
 352+}
\ No newline at end of file
Property changes on: branches/wmf/1.16wmf4/extensions/PagedTiffHandler/TiffReader.php
___________________________________________________________________
Added: svn:eol-style
1353 + native
Index: branches/wmf/1.16wmf4/extensions/PagedTiffHandler/selenium/PagedTiffHandler_tests.php
@@ -0,0 +1,376 @@
 2+<?php
 3+/**
 4+ * To get this working you must
 5+ * - set a valid path to PEAR
 6+ * - check upload size in php.ini: Multipage.tiff needs at least 3M
 7+ * - Either upload multipage.tiff when PagedTiffHandler is active or set $wgSeleniumTiffTestUploads = true.
 8+ * - - if $wgSeleniumTiffTestsUploads = true, please remember to obtain all missing test images. See
 9+ * - - testImages/SOURCES.txt for further information
 10+ * - set the locale to English
 11+ */
 12+
 13+if ( !defined( 'MEDIAWIKI' ) || !defined( 'SELENIUMTEST' ) ) {
 14+ echo 'This script cannot be run standalone';
 15+ exit( 1 );
 16+}
 17+
 18+$wgSeleniumTiffTestUploads = false;
 19+$wgSeleniumTiffTestCheckPrerequistes = true;
 20+
 21+class SeleniumCheckPrerequisites extends SeleniumTestCase {
 22+ public $name = 'Check prerequisites';
 23+ private $prerequisiteError = null;
 24+
 25+ public function runTest() {
 26+ global $wgSeleniumTestsWikiUrl;
 27+ // check whether Multipage.tiff is already uploaded
 28+ $this->open( $wgSeleniumTestsWikiUrl . '/index.php?title=Image:Multipage.tiff' );
 29+
 30+ $source = $this->getAttribute( "//div[@id='bodyContent']//ul@id" );
 31+ if ( $source != 'filetoc' ) {
 32+ $this->prerequisiteError = 'Image:Multipage.tiff must exist.';
 33+ }
 34+
 35+ // Check for language
 36+ $this->open($wgSeleniumTestsWikiUrl . '/api.php?action=query&meta=userinfo&uiprop=options&format=xml');
 37+
 38+ $lang = $this->getAttribute( "//options/@language" );
 39+ if ( $lang != 'en' ) {
 40+ $this->prerequisiteError = 'interface language must be set to English (en), but was '.$lang.'.';
 41+ }
 42+ }
 43+
 44+ public function tearDown() {
 45+ if ( $this->prerequisiteError ) {
 46+ $this->selenium->stop();
 47+ die( 'failed: ' . $this->prerequisiteError . "\n" );
 48+ }
 49+ }
 50+}
 51+
 52+
 53+class SeleniumUploadTiffTest extends SeleniumTestCase {
 54+ public function uploadFile( $filename ) {
 55+ global $wgSeleniumTestsWikiUrl;
 56+ $this->open( $wgSeleniumTestsWikiUrl . '/index.php?title=Special:Upload' );
 57+ $this->type( 'wpUploadFile', dirname( __FILE__ ) . "\\testImages\\" . $filename );
 58+ $this->check( 'wpIgnoreWarning' );
 59+ $this->click( 'wpUpload' );
 60+ $this->waitForPageToLoad( 30000 );
 61+ }
 62+
 63+ public function assertUploaded( $filename ) {
 64+ $this->assertSeleniumHTMLContains( '//h1[@class="firstHeading"]', ucfirst( $filename ) );
 65+ }
 66+
 67+ public function assertErrorMsg( $msg ) {
 68+ $this->assertSeleniumHTMLContains( '//div[@id="bodyContent"]//span[@class="error"]', $msg );
 69+ }
 70+
 71+}
 72+
 73+class SeleniumUploadWorkingTiffTest extends SeleniumUploadTiffTest {
 74+ public $name = 'Upload working Tiff: ';
 75+ private $filename;
 76+
 77+ public function __construct( $filename ) {
 78+ parent::__construct();
 79+ $this->filename = $filename;
 80+ $this->name .= $filename;
 81+ }
 82+
 83+ public function runTest() {
 84+ $this->uploadFile( $this->filename );
 85+ $this->assertUploaded( str_replace( '_', ' ', $this->filename ) );
 86+ }
 87+}
 88+
 89+class SeleniumUploadBrokenTiffTest extends SeleniumUploadTiffTest {
 90+ public $name = 'Upload broken Tiff: ';
 91+ private $filename;
 92+ private $errorMsg;
 93+
 94+ public function __construct( $filename, $errorMsg ) {
 95+ parent::__construct();
 96+ $this->filename = $filename;
 97+ $this->name .= $filename;
 98+ $this->errorMsg = $errorMsg;
 99+ }
 100+
 101+ public function runTest() {
 102+ $this->uploadFile( $this->filename );
 103+ $this->assertErrorMsg( $this->errorMsg );
 104+ }
 105+}
 106+
 107+class SeleniumDeleteTiffTest extends SeleniumTestCase {
 108+ public $name = 'Delete Tiff: ';
 109+ private $filename;
 110+
 111+ public function __construct( $filename ) {
 112+ parent::__construct();
 113+ $this->filename = $filename;
 114+ $this->name .= $filename;
 115+ }
 116+
 117+ public function runTest() {
 118+ global $wgSeleniumTestsWikiUrl;
 119+ $this->open( $wgSeleniumTestsWikiUrl . '/index.php?title=Image:' . ucfirst( $this->filename ) . '&action=delete' );
 120+ $this->type( 'wpReason', 'Remove test file' );
 121+ $this->click( 'mw-filedelete-submit' );
 122+ $this->waitForPageToLoad( 10000 );
 123+
 124+ // Todo: This message is localized
 125+ $this->assertSeleniumHTMLContains( '//div[@id="bodyContent"]/p', ucfirst( $this->filename ) . '.*has been deleted.' );
 126+ }
 127+
 128+}
 129+
 130+class SeleniumEmbedTiffTest extends SeleniumTestCase { //PHPUnit_Extensions_SeleniumTestCase
 131+
 132+ public function tearDown() {
 133+ global $wgSeleniumTestsWikiUrl;
 134+ parent::tearDown();
 135+ // Clear EmbedTiffTest page for future tests
 136+ $this->open( $wgSeleniumTestsWikiUrl . '/index.php?title=EmbedTiffTest&action=edit' );
 137+ $this->type( 'wpTextbox1', '' );
 138+ $this->click( 'wpSave' );
 139+ }
 140+
 141+ public function preparePage( $text ) {
 142+ global $wgSeleniumTestsWikiUrl;
 143+ $this->open( $wgSeleniumTestsWikiUrl . '/index.php?title=EmbedTiffTest&action=edit' );
 144+ $this->type( 'wpTextbox1', $text );
 145+ $this->click( 'wpSave' );
 146+ $this->waitForPageToLoad( 10000 );
 147+ }
 148+
 149+}
 150+
 151+class SeleniumTiffPageTest extends SeleniumTestCase {
 152+ public function tearDown() {
 153+ parent::tearDown();
 154+ // Clear EmbedTiffTest page for future tests
 155+ $this->open( $wgSeleniumTestsWikiUrl . '/index.php?title=Image:' . $this->image . '&action=edit' );
 156+ $this->type( 'wpTextbox1', '' );
 157+ $this->click( 'wpSave' );
 158+ }
 159+
 160+ public function prepareImagePage( $image, $text ) {
 161+ global $wgSeleniumTestsWikiUrl;
 162+ $this->image = $image;
 163+ $this->open( $wgSeleniumTestsWikiUrl . '/index.php?title=Image:' . $image . '&action=edit' );
 164+ $this->type( 'wpTextbox1', $text );
 165+ $this->click( 'wpSave' );
 166+ $this->waitForPageToLoad( 10000 );
 167+
 168+ }
 169+}
 170+
 171+class SeleniumDisplayInCategoryTest extends SeleniumTiffPageTest {
 172+ public $name = 'Display in category';
 173+
 174+ public function runTest() {
 175+ $this->prepareImagePage( 'Multipage.tiff', "[[Category:Wiki]]\n" );
 176+
 177+ global $wgSeleniumTestsWikiUrl;
 178+ $this->open( $wgSeleniumTestsWikiUrl . '/index.php?title=Category:Wiki' );
 179+
 180+ // Ergebnis chekcen
 181+ $source = $this->getAttribute( "//div[@class='gallerybox']//a[@class='image']//img@src" );
 182+ $correct = strstr( $source, "-page1-" );
 183+ $this->assertEquals( $correct, true );
 184+ }
 185+}
 186+
 187+class SeleniumDisplayInGalleryTest extends SeleniumEmbedTiffTest {
 188+ public $name = 'Display in gallery';
 189+
 190+ public function runTest() {
 191+ $this->preparePage( "<gallery>\nImage:Multipage.tiff\n</gallery>\n" );
 192+
 193+ //global $wgSeleniumTestsWikiUrl;
 194+ //$this->open( $wgSeleniumTestsWikiUrl . '/index.php?title=GalleryTest' );
 195+
 196+ // Ergebnis chekcen
 197+ //$source = $this->getAttribute( "//div[@class='gallerybox']//a[@title='Multipage.tiff']//img@src" );
 198+ $source = $this->getAttribute( "//div[@class='gallerybox']//a[@class='image']//img@src" );
 199+ $correct = strstr( $source, "-page1-" );
 200+ $this->assertEquals( $correct, true );
 201+
 202+ }
 203+}
 204+
 205+class SeleniumEmbedTiffInclusionTest extends SeleniumEmbedTiffTest {
 206+ public $name = 'Include Tiff Images';
 207+
 208+ public function runTest() {
 209+ $this->preparePage( "[[Image:Multipage.tiff]]\n" );
 210+
 211+ $this->assertSeleniumAttributeEquals( "//div[@id='bodyContent']//img@height", '768' );
 212+ $this->assertSeleniumAttributeEquals( "//div[@id='bodyContent']//img@width", '1024' );
 213+ }
 214+}
 215+
 216+class SeleniumEmbedTiffThumbRatioTest extends SeleniumEmbedTiffTest {
 217+ public $name = "Include Tiff Thumbnail Aspect Ratio";
 218+
 219+ public function runTest() {
 220+ $this->preparePage( "[[Image:Multipage.tiff|200px]]\n" );
 221+ //$this->selenium->type( 'wpTextbox1', "[[Image:Pc260001.tif|thumb]]\n" );
 222+
 223+ $this->assertSeleniumAttributeEquals( "//div[@id='bodyContent']//img@height", '150' );
 224+ $this->assertSeleniumAttributeEquals( "//div[@id='bodyContent']//img@width", '200' );
 225+ }
 226+}
 227+
 228+class SeleniumEmbedTiffBoxFitTest extends SeleniumEmbedTiffTest {
 229+ public $name = 'Include Tiff Box Fit';
 230+
 231+ public function runTest() {
 232+ $this->preparePage( "[[Image:Multipage.tiff|200x75px]]\n" );
 233+
 234+ $this->assertSeleniumAttributeEquals( "//div[@id='bodyContent']//img@height", '75' );
 235+ $this->assertSeleniumAttributeEquals( "//div[@id='bodyContent']//img@width", '100' );
 236+ }
 237+}
 238+
 239+
 240+class SeleniumEmbedTiffPage2InclusionTest extends SeleniumEmbedTiffTest {
 241+ public $name = 'Include Tiff Images: Page 2';
 242+
 243+ public function runTest() {
 244+ $this->preparePage( "[[Image:Multipage.tiff|page=2]]\n" );
 245+ //$this->selenium->type( 'wpTextbox1', "[[Image:Pc260001.tif|thumb]]\n" );
 246+
 247+ $this->assertSeleniumAttributeEquals( "//div[@id='bodyContent']//img@height", '564' );
 248+ $this->assertSeleniumAttributeEquals( "//div[@id='bodyContent']//img@width", '640' );
 249+ }
 250+}
 251+
 252+class SeleniumEmbedTiffPage2ThumbRatioTest extends SeleniumEmbedTiffTest {
 253+ public $name = 'Include Tiff Thumbnail Aspect Ratio: Page 2';
 254+
 255+ public function runTest() {
 256+ $this->preparePage( "[[Image:Multipage.tiff|320px|page=2]]\n" );
 257+
 258+ $this->assertSeleniumAttributeEquals( "//div[@id='bodyContent']//img@height", '282' );
 259+ $this->assertSeleniumAttributeEquals( "//div[@id='bodyContent']//img@width", '320' );
 260+ }
 261+}
 262+
 263+class SeleniumEmbedTiffPage2BoxFitTest extends SeleniumEmbedTiffTest {
 264+ public $name = 'Include Tiff Box Fit: Page 2';
 265+
 266+ public function runTest() {
 267+ $this->preparePage( "[[Image:Multipage.tiff|200x108px|page=2]]\n" );
 268+
 269+ $this->assertSeleniumAttributeEquals( "//div[@id='bodyContent']//img@height", '108' );
 270+ $this->assertSeleniumAttributeEquals( "//div[@id='bodyContent']//img@width", '123' );
 271+ }
 272+}
 273+
 274+class SeleniumEmbedTiffNegativePageParameterTest extends SeleniumEmbedTiffTest {
 275+ public $name = 'Include Tiff: negative page parameter';
 276+
 277+ public function runTest() {
 278+ $this->preparePage( "[[Image:Multipage.tiff|page=-1]]\n" );
 279+
 280+ $source = $this->getAttribute( "//div[@id='bodyContent']//img@src" );
 281+ $correct = strstr( $source, "-page1-" );
 282+ $this->assertEquals( $correct, true );
 283+ }
 284+}
 285+
 286+class SeleniumEmbedTiffPageParameterTooHighTest extends SeleniumEmbedTiffTest {
 287+ public $name = 'Include Tiff: too high page parameter';
 288+
 289+ public function runTest() {
 290+ $this->preparePage( "[[Image:Multipage.tiff|page=8]]\n" );
 291+
 292+ $source = $this->getAttribute( "//div[@id='bodyContent']//img@src" );
 293+ $correct = strstr( $source, "-page7-" );
 294+ $this->assertEquals( $correct, true );
 295+ }
 296+}
 297+
 298+// actually run tests
 299+// create test suite
 300+$wgSeleniumTestSuites['PagedTiffHandler'] = new SeleniumTestSuite( 'Paged TIFF Images' );
 301+// add tests
 302+if ( $wgSeleniumTiffTestCheckPrerequistes ) {
 303+ $wgSeleniumTestSuites['PagedTiffHandler']->addTest( new SeleniumCheckPrerequisites() );
 304+}
 305+
 306+if ( $wgSeleniumTiffTestUploads ) {
 307+ $wgSeleniumTestSuites['PagedTiffHandler']->addTest( new SeleniumUploadBrokenTiffTest( 'caspian.tif', 'The uploaded file contains errors.' ) );
 308+ $wgSeleniumTestSuites['PagedTiffHandler']->addTest( new SeleniumUploadWorkingTiffTest( 'cramps.tif' ) );
 309+ $wgSeleniumTestSuites['PagedTiffHandler']->addTest( new SeleniumUploadWorkingTiffTest( 'cramps-tile.tif' ) );
 310+ $wgSeleniumTestSuites['PagedTiffHandler']->addTest( new SeleniumUploadWorkingTiffTest( 'dscf0013.tif' ) );
 311+ $wgSeleniumTestSuites['PagedTiffHandler']->addTest( new SeleniumUploadWorkingTiffTest( 'fax2d.tif' ) );
 312+ $wgSeleniumTestSuites['PagedTiffHandler']->addTest( new SeleniumUploadWorkingTiffTest( 'g3test.tif' ) );
 313+ $wgSeleniumTestSuites['PagedTiffHandler']->addTest( new SeleniumUploadWorkingTiffTest( 'Jello.tif' ) );
 314+ $wgSeleniumTestSuites['PagedTiffHandler']->addTest( new SeleniumUploadBrokenTiffTest( 'jim___ah.tif', 'The reported file size does not match the actual file size.' ) );
 315+ $wgSeleniumTestSuites['PagedTiffHandler']->addTest( new SeleniumUploadWorkingTiffTest( 'jim___cg.tif' ) );
 316+ $wgSeleniumTestSuites['PagedTiffHandler']->addTest( new SeleniumUploadBrokenTiffTest( 'jim___dg.tif', 'The reported file size does not match the actual file size.' ) );
 317+ $wgSeleniumTestSuites['PagedTiffHandler']->addTest( new SeleniumUploadBrokenTiffTest( 'jim___gg.tif', 'The reported file size does not match the actual file size.' ) );
 318+ $wgSeleniumTestSuites['PagedTiffHandler']->addTest( new SeleniumUploadWorkingTiffTest( 'ladoga.tif' ) );
 319+ $wgSeleniumTestSuites['PagedTiffHandler']->addTest( new SeleniumUploadWorkingTiffTest( 'off_l16.tif' ) );
 320+ $wgSeleniumTestSuites['PagedTiffHandler']->addTest( new SeleniumUploadWorkingTiffTest( 'off_luv24.tif' ) );
 321+ $wgSeleniumTestSuites['PagedTiffHandler']->addTest( new SeleniumUploadWorkingTiffTest( 'off_luv24.tif' ) );
 322+ $wgSeleniumTestSuites['PagedTiffHandler']->addTest( new SeleniumUploadWorkingTiffTest( 'oxford.tif' ) );
 323+ $wgSeleniumTestSuites['PagedTiffHandler']->addTest( new SeleniumUploadWorkingTiffTest( 'pc260001.tif' ) );
 324+ $wgSeleniumTestSuites['PagedTiffHandler']->addTest( new SeleniumUploadBrokenTiffTest( 'quad-jpeg.tif', 'The uploaded file could not be processed. ImageMagick is not available.' ) );
 325+ $wgSeleniumTestSuites['PagedTiffHandler']->addTest( new SeleniumUploadWorkingTiffTest( 'quad-lzw.tif' ) );
 326+ $wgSeleniumTestSuites['PagedTiffHandler']->addTest( new SeleniumUploadWorkingTiffTest( 'quad-tile.tif' ) );
 327+ $wgSeleniumTestSuites['PagedTiffHandler']->addTest( new SeleniumUploadBrokenTiffTest( 'smallliz.tif', 'The uploaded file could not be processed. ImageMagick is not available.' ) );
 328+ $wgSeleniumTestSuites['PagedTiffHandler']->addTest( new SeleniumUploadWorkingTiffTest( 'strike.tif' ) );
 329+ $wgSeleniumTestSuites['PagedTiffHandler']->addTest( new SeleniumUploadBrokenTiffTest( 'text.tif', 'The uploaded file contains errors.' ) );
 330+ $wgSeleniumTestSuites['PagedTiffHandler']->addTest( new SeleniumUploadWorkingTiffTest( 'ycbcr-cat.tif' ) );
 331+ $wgSeleniumTestSuites['PagedTiffHandler']->addTest( new SeleniumUploadBrokenTiffTest( 'zackthecat.tif', 'The uploaded file could not be processed. ImageMagick is not available.' ) );
 332+ $wgSeleniumTestSuites['PagedTiffHandler']->addTest( new SeleniumUploadWorkingTiffTest( 'multipage.tiff' ) );
 333+}
 334+//$wgSeleniumTestSuites['PagedTiffHandler']->addTest( new SeleniumUploadWorkingTiffTest( 'multipage.tiff' ) );
 335+
 336+$wgSeleniumTestSuites['PagedTiffHandler']->addTest( new SeleniumEmbedTiffInclusionTest() );
 337+$wgSeleniumTestSuites['PagedTiffHandler']->addTest( new SeleniumEmbedTiffThumbRatioTest() );
 338+$wgSeleniumTestSuites['PagedTiffHandler']->addTest( new SeleniumEmbedTiffBoxFitTest() );
 339+
 340+$wgSeleniumTestSuites['PagedTiffHandler']->addTest( new SeleniumEmbedTiffPage2InclusionTest() );
 341+$wgSeleniumTestSuites['PagedTiffHandler']->addTest( new SeleniumEmbedTiffPage2ThumbRatioTest() );
 342+$wgSeleniumTestSuites['PagedTiffHandler']->addTest( new SeleniumEmbedTiffPage2BoxFitTest() );
 343+
 344+$wgSeleniumTestSuites['PagedTiffHandler']->addTest( new SeleniumEmbedTiffNegativePageParameterTest() );
 345+$wgSeleniumTestSuites['PagedTiffHandler']->addTest( new SeleniumEmbedTiffPageParameterTooHighTest() );
 346+
 347+$wgSeleniumTestSuites['PagedTiffHandler']->addTest( new SeleniumDisplayInCategoryTest() );
 348+$wgSeleniumTestSuites['PagedTiffHandler']->addTest( new SeleniumDisplayInGalleryTest() );
 349+
 350+if ( $wgSeleniumTiffTestUploads ) {
 351+ $wgSeleniumTestSuites['PagedTiffHandler']->addTest( new SeleniumDeleteTiffTest( 'cramps.tif' ) );
 352+ $wgSeleniumTestSuites['PagedTiffHandler']->addTest( new SeleniumDeleteTiffTest( 'cramps-tile.tif' ) );
 353+ $wgSeleniumTestSuites['PagedTiffHandler']->addTest( new SeleniumDeleteTiffTest( 'dscf0013.tif' ) );
 354+ $wgSeleniumTestSuites['PagedTiffHandler']->addTest( new SeleniumDeleteTiffTest( 'fax2d.tif' ) );
 355+ $wgSeleniumTestSuites['PagedTiffHandler']->addTest( new SeleniumDeleteTiffTest( 'g3test.tif' ) );
 356+ $wgSeleniumTestSuites['PagedTiffHandler']->addTest( new SeleniumDeleteTiffTest( 'Jello.tif' ) );
 357+ //$wgSeleniumTestSuites['PagedTiffHandler']->addTest( new SeleniumDeleteTiffTest( 'jim___ah.tif' ) );
 358+ $wgSeleniumTestSuites['PagedTiffHandler']->addTest( new SeleniumDeleteTiffTest( 'jim___cg.tif' ) );
 359+ //$wgSeleniumTestSuites['PagedTiffHandler']->addTest( new SeleniumDeleteTiffTest( 'jim___dg.tif' ) );
 360+ //$wgSeleniumTestSuites['PagedTiffHandler']->addTest( new SeleniumDeleteTiffTest( 'jim___gg.tif' ) );
 361+ $wgSeleniumTestSuites['PagedTiffHandler']->addTest( new SeleniumDeleteTiffTest( 'ladoga.tif' ) );
 362+ $wgSeleniumTestSuites['PagedTiffHandler']->addTest( new SeleniumDeleteTiffTest( 'off_l16.tif' ) );
 363+ $wgSeleniumTestSuites['PagedTiffHandler']->addTest( new SeleniumDeleteTiffTest( 'off_luv24.tif' ) );
 364+ $wgSeleniumTestSuites['PagedTiffHandler']->addTest( new SeleniumDeleteTiffTest( 'off_luv24.tif' ) );
 365+ $wgSeleniumTestSuites['PagedTiffHandler']->addTest( new SeleniumDeleteTiffTest( 'oxford.tif' ) );
 366+ $wgSeleniumTestSuites['PagedTiffHandler']->addTest( new SeleniumDeleteTiffTest( 'pc260001.tif' ) );
 367+ //$wgSeleniumTestSuites['PagedTiffHandler']->addTest( new SeleniumDeleteTiffTest( 'quad-jpeg.tif' ) );
 368+ $wgSeleniumTestSuites['PagedTiffHandler']->addTest( new SeleniumDeleteTiffTest( 'quad-lzw.tif' ) );
 369+ $wgSeleniumTestSuites['PagedTiffHandler']->addTest( new SeleniumDeleteTiffTest( 'quad-tile.tif' ) );
 370+ //$wgSeleniumTestSuites['PagedTiffHandler']->addTest( new SeleniumDeleteTiffTest( 'smallliz.tif' ) );
 371+ $wgSeleniumTestSuites['PagedTiffHandler']->addTest( new SeleniumDeleteTiffTest( 'strike.tif' ) );
 372+ //$wgSeleniumTestSuites['PagedTiffHandler']->addTest( new SeleniumDeleteTiffTest( 'text.tif' ) );
 373+ $wgSeleniumTestSuites['PagedTiffHandler']->addTest( new SeleniumDeleteTiffTest( 'ycbcr-cat.tif' ) );
 374+ //$wgSeleniumTestSuites['PagedTiffHandler']->addTest( new SeleniumDeleteTiffTest( 'zackthecat.tif' ) );
 375+ $wgSeleniumTestSuites['PagedTiffHandler']->addTest( new SeleniumDeleteTiffTest( 'multipage.tiff' ) );
 376+}
 377+
Property changes on: branches/wmf/1.16wmf4/extensions/PagedTiffHandler/selenium/PagedTiffHandler_tests.php
___________________________________________________________________
Added: svn:keywords
1378 + LastChangedDate LastChangedBy Revision Id
Added: svn:eol-style
2379 + native
Index: branches/wmf/1.16wmf4/extensions/PagedTiffHandler/selenium/testImages/caspian.tif
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes on: branches/wmf/1.16wmf4/extensions/PagedTiffHandler/selenium/testImages/caspian.tif
___________________________________________________________________
Added: svn:mime-type
3380 + application/octet-stream
Index: branches/wmf/1.16wmf4/extensions/PagedTiffHandler/selenium/testImages/SOURCES.txt
@@ -0,0 +1,21 @@
 2+multipage.tiff created by ImageMagick 6.5.0-0 2009-03-09 Q16 OpenMP http://www.imagemagick.org
 3+Command: convert.exe * -adjoin multipage.tiff
 4+
 5+Bridge.jpg http://commons.wikimedia.org/wiki/File:Regensburg_Steinerne_Bruecke.jpg
 6+Caffeine.png http://commons.wikimedia.org/wiki/File:Caffeine-3D-vdW.png
 7+Mars.jpg http://commons.wikimedia.org/wiki/File:MarsTopoMap-PIA02031_modest_cropped_monochrome.jpg
 8+
 9+Pogona.jpg To the extent possible under law, Marc Reymann has waived all copyright
 10+Snake1.jpg and related or neighboring rights to these four pictures.
 11+Snake2.jpg This work is published from Germany.
 12+Venice.jpg
 13+
 14+----------
 15+
 16+caspian.tif
 17+pc260001.tif taken from libtiff test images. Obviously they are under no license. you can obtain the
 18+ whole set of test images from http://www.libtiff.org/images.html
 19+
 20+----------
 21+
 22+For upload tests pls. get the whole set of test images from http://www.libtiff.org/images.html and copy the images into this directory.
\ No newline at end of file
Property changes on: branches/wmf/1.16wmf4/extensions/PagedTiffHandler/selenium/testImages/SOURCES.txt
___________________________________________________________________
Added: svn:eol-style
123 + native
Index: branches/wmf/1.16wmf4/extensions/PagedTiffHandler/selenium/testImages/pc260001.tif
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes on: branches/wmf/1.16wmf4/extensions/PagedTiffHandler/selenium/testImages/pc260001.tif
___________________________________________________________________
Added: svn:mime-type
224 + application/octet-stream
Index: branches/wmf/1.16wmf4/extensions/PagedTiffHandler/selenium/testImages/multipage.tiff
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes on: branches/wmf/1.16wmf4/extensions/PagedTiffHandler/selenium/testImages/multipage.tiff
___________________________________________________________________
Added: svn:mime-type
325 + application/octet-stream
Index: branches/wmf/1.16wmf4/extensions/PagedTiffHandler/selenium/PagedTiffHandlerTestSuite.php
@@ -0,0 +1,162 @@
 2+<?php
 3+/**
 4+ * To get this working you must
 5+ * - set a valid path to PEAR
 6+ * - check upload size in php.ini: Multipage.tiff needs at least 3M
 7+ * - Either upload multipage.tiff when PagedTiffHandler is active or
 8+ * - - set $egSeleniumTiffTestUploads = true.
 9+ * - if $wgSeleniumTiffTestsUploads = true, please remember to obtain
 10+ * - - all missing test images. See
 11+ * - - testImages/SOURCES.txt for further information
 12+ * - set the locale to English
 13+ */
 14+
 15+require_once(dirname( __FILE__ ) . '/PagedTiffHandlerTestCases.php');
 16+
 17+class PagedTiffHandlerSeleniumTestSuite extends SeleniumTestSuite {
 18+
 19+ public $egSeleniumTiffTestUploads = false;
 20+ public $egSeleniumTiffTestCheckPrerequistes = true;
 21+
 22+ public function __construct( $name = 'PagedTiffHandler Test Suite') {
 23+ parent::__construct( $name );
 24+ }
 25+
 26+ public function addTests() {
 27+ if ( $this->egSeleniumTiffTestCheckPrerequistes ) {
 28+ parent::addTest( new SeleniumCheckPrerequisites() );
 29+ }
 30+
 31+ if ( $this->egSeleniumTiffTestUploads ) {
 32+ parent::addTest( new SeleniumUploadBrokenTiffTest(
 33+ 'caspian.tif',
 34+ 'The uploaded file contains errors.' ) );
 35+ parent::addTest( new SeleniumUploadWorkingTiffTest(
 36+ 'cramps.tif' ) );
 37+ parent::addTest( new SeleniumUploadWorkingTiffTest(
 38+ 'cramps-tile.tif' ) );
 39+ parent::addTest( new SeleniumUploadWorkingTiffTest(
 40+ 'dscf0013.tif' ) );
 41+ parent::addTest( new SeleniumUploadWorkingTiffTest(
 42+ 'fax2d.tif' ) );
 43+ parent::addTest( new SeleniumUploadWorkingTiffTest(
 44+ 'g3test.tif' ) );
 45+ parent::addTest( new SeleniumUploadWorkingTiffTest(
 46+ 'Jello.tif' ) );
 47+ parent::addTest( new SeleniumUploadBrokenTiffTest(
 48+ 'jim___ah.tif',
 49+ 'The reported file size does not match' .
 50+ ' the actual file size.' ) );
 51+ parent::addTest( new SeleniumUploadWorkingTiffTest(
 52+ 'jim___cg.tif' ) );
 53+ parent::addTest( new SeleniumUploadBrokenTiffTest(
 54+ 'jim___dg.tif', 'The reported file size does' .
 55+ ' not match the actual file size.' ) );
 56+ parent::addTest( new SeleniumUploadBrokenTiffTest(
 57+ 'jim___gg.tif', 'The reported file size does' .
 58+ ' not match the actual file size.' ) );
 59+ parent::addTest( new SeleniumUploadWorkingTiffTest(
 60+ 'ladoga.tif' ) );
 61+ parent::addTest( new SeleniumUploadWorkingTiffTest(
 62+ 'off_l16.tif' ) );
 63+ parent::addTest( new SeleniumUploadWorkingTiffTest(
 64+ 'off_luv24.tif' ) );
 65+ parent::addTest( new SeleniumUploadWorkingTiffTest(
 66+ 'off_luv24.tif' ) );
 67+ parent::addTest( new SeleniumUploadWorkingTiffTest(
 68+ 'oxford.tif' ) );
 69+ parent::addTest( new SeleniumUploadWorkingTiffTest(
 70+ 'pc260001.tif' ) );
 71+ parent::addTest( new SeleniumUploadBrokenTiffTest(
 72+ 'quad-jpeg.tif', 'The uploaded file could not' .
 73+ ' be processed. ImageMagick is not available.' ) );
 74+ parent::addTest( new SeleniumUploadWorkingTiffTest(
 75+ 'quad-lzw.tif' ) );
 76+ parent::addTest( new SeleniumUploadWorkingTiffTest(
 77+ 'quad-tile.tif' ) );
 78+ parent::addTest( new SeleniumUploadBrokenTiffTest(
 79+ 'smallliz.tif', 'The uploaded file could not' .
 80+ ' be processed. ImageMagick is not available.' ) );
 81+ parent::addTest( new SeleniumUploadWorkingTiffTest(
 82+ 'strike.tif' ) );
 83+ parent::addTest( new SeleniumUploadBrokenTiffTest(
 84+ 'text.tif', 'The uploaded file contains errors.' ) );
 85+ parent::addTest( new SeleniumUploadWorkingTiffTest(
 86+ 'ycbcr-cat.tif' ) );
 87+ parent::addTest( new SeleniumUploadBrokenTiffTest(
 88+ 'zackthecat.tif', 'The uploaded file could not' .
 89+ ' be processed. ImageMagick is not available.' ) );
 90+ parent::addTest( new SeleniumUploadWorkingTiffTest(
 91+ 'multipage.tiff' ) );
 92+ }
 93+ //parent::addTest( new SeleniumUploadWorkingTiffTest( 'multipage.tiff' ) );
 94+
 95+ parent::addTest( new SeleniumEmbedTiffInclusionTest() );
 96+ parent::addTest( new SeleniumEmbedTiffThumbRatioTest() );
 97+ parent::addTest( new SeleniumEmbedTiffBoxFitTest() );
 98+
 99+ parent::addTest( new SeleniumEmbedTiffPage2InclusionTest() );
 100+ parent::addTest( new SeleniumEmbedTiffPage2ThumbRatioTest() );
 101+ parent::addTest( new SeleniumEmbedTiffPage2BoxFitTest() );
 102+
 103+ parent::addTest( new SeleniumEmbedTiffNegativePageParameterTest() );
 104+ parent::addTest( new SeleniumEmbedTiffPageParameterTooHighTest() );
 105+
 106+ parent::addTest( new SeleniumDisplayInCategoryTest() );
 107+ parent::addTest( new SeleniumDisplayInGalleryTest() );
 108+
 109+ if ( $this->egSeleniumTiffTestUploads ) {
 110+ parent::addTest( new SeleniumDeleteTiffTest(
 111+ 'cramps.tif' ) );
 112+ parent::addTest( new SeleniumDeleteTiffTest(
 113+ 'cramps-tile.tif' ) );
 114+ parent::addTest( new SeleniumDeleteTiffTest(
 115+ 'dscf0013.tif' ) );
 116+ parent::addTest( new SeleniumDeleteTiffTest(
 117+ 'fax2d.tif' ) );
 118+ parent::addTest( new SeleniumDeleteTiffTest(
 119+ 'g3test.tif' ) );
 120+ parent::addTest( new SeleniumDeleteTiffTest(
 121+ 'Jello.tif' ) );
 122+ //parent::addTest( new SeleniumDeleteTiffTest(
 123+ //'jim___ah.tif' ) );
 124+ parent::addTest( new SeleniumDeleteTiffTest(
 125+ 'jim___cg.tif' ) );
 126+ //parent::addTest( new SeleniumDeleteTiffTest(
 127+ //'jim___dg.tif' ) );
 128+ //parent::addTest( new SeleniumDeleteTiffTest(
 129+ //'jim___gg.tif' ) );
 130+ parent::addTest( new SeleniumDeleteTiffTest(
 131+ 'ladoga.tif' ) );
 132+ parent::addTest( new SeleniumDeleteTiffTest(
 133+ 'off_l16.tif' ) );
 134+ parent::addTest( new SeleniumDeleteTiffTest(
 135+ 'off_luv24.tif' ) );
 136+ parent::addTest( new SeleniumDeleteTiffTest(
 137+ 'off_luv24.tif' ) );
 138+ parent::addTest( new SeleniumDeleteTiffTest(
 139+ 'oxford.tif' ) );
 140+ parent::addTest( new SeleniumDeleteTiffTest(
 141+ 'pc260001.tif' ) );
 142+ //parent::addTest( new SeleniumDeleteTiffTest(
 143+ //'quad-jpeg.tif' ) );
 144+ parent::addTest( new SeleniumDeleteTiffTest(
 145+ 'quad-lzw.tif' ) );
 146+ parent::addTest( new SeleniumDeleteTiffTest(
 147+ 'quad-tile.tif' ) );
 148+ //parent::addTest( new SeleniumDeleteTiffTest(
 149+ //'smallliz.tif' ) );
 150+ parent::addTest( new SeleniumDeleteTiffTest(
 151+ 'strike.tif' ) );
 152+ //parent::addTest( new SeleniumDeleteTiffTest(
 153+ //'text.tif' ) );
 154+ parent::addTest( new SeleniumDeleteTiffTest(
 155+ 'ycbcr-cat.tif' ) );
 156+ //parent::addTest( new SeleniumDeleteTiffTest(
 157+ //'zackthecat.tif' ) );
 158+ parent::addTest( new SeleniumDeleteTiffTest(
 159+ 'multipage.tiff' ) );
 160+ }
 161+ }
 162+}
 163+
Property changes on: branches/wmf/1.16wmf4/extensions/PagedTiffHandler/selenium/PagedTiffHandlerTestSuite.php
___________________________________________________________________
Added: svn:keywords
1164 + LastChangedDate LastChangedBy Revision Id
Added: svn:eol-style
2165 + native
Index: branches/wmf/1.16wmf4/extensions/PagedTiffHandler/selenium/PagedTiffHandlerTestCases.php
@@ -0,0 +1,307 @@
 2+<?php
 3+
 4+class SeleniumCheckPrerequisites extends SeleniumTestCase {
 5+ public $name = 'Check prerequisites';
 6+ private $prerequisiteError = null;
 7+ public function runTest() {
 8+
 9+ // check whether Multipage.tiff is already uploaded
 10+ $this->open( Selenium::getBaseUrl() .
 11+ '/index.php?title=Image:Multipage.tiff' );
 12+
 13+ $source = $this->getAttribute( "//div[@id='bodyContent']//ul@id" );
 14+ if ( $source != 'filetoc' ) {
 15+ $this->prerequisiteError = 'Image:Multipage.tiff must exist.';
 16+ }
 17+
 18+ // Check for language
 19+ $this->open( Selenium::getBaseUrl() .
 20+ '/api.php?action=query&meta=userinfo&uiprop=options&format=xml');
 21+
 22+ $lang = $this->getAttribute( "//options/@language" );
 23+ if ( $lang != 'en' ) {
 24+ $this->prerequisiteError =
 25+ 'interface language must be set to' .
 26+ ' English (en), but was '.$lang.'.';
 27+ }
 28+ }
 29+
 30+ public function tearDown() {
 31+ if ( $this->prerequisiteError ) {
 32+ $this->selenium->stop();
 33+ die( 'failed: ' . $this->prerequisiteError . "\n" );
 34+ }
 35+ }
 36+}
 37+
 38+class SeleniumUploadTiffTest extends SeleniumTestCase {
 39+ public function uploadFile( $filename ) {
 40+
 41+ $this->open( Selenium::getBaseUrl() .
 42+ '/index.php?title=Special:Upload' );
 43+ $this->type( 'wpUploadFile', dirname( __FILE__ ) .
 44+ "\\testImages\\" . $filename );
 45+ $this->check( 'wpIgnoreWarning' );
 46+ $this->click( 'wpUpload' );
 47+ $this->waitForPageToLoad( 30000 );
 48+ }
 49+
 50+ public function assertUploaded( $filename ) {
 51+ $this->assertSeleniumHTMLContains(
 52+ '//h1[@class="firstHeading"]', ucfirst( $filename ) );
 53+ }
 54+
 55+ public function assertErrorMsg( $msg ) {
 56+ $this->assertSeleniumHTMLContains(
 57+ '//div[@id="bodyContent"]//span[@class="error"]', $msg );
 58+ }
 59+
 60+}
 61+
 62+class SeleniumUploadWorkingTiffTest extends SeleniumUploadTiffTest {
 63+ public $name = 'Upload working Tiff: ';
 64+ private $filename;
 65+
 66+ public function __construct( $filename ) {
 67+ parent::__construct();
 68+ $this->filename = $filename;
 69+ $this->name .= $filename;
 70+ }
 71+
 72+ public function runTest() {
 73+ $this->uploadFile( $this->filename );
 74+ $this->assertUploaded( str_replace( '_', ' ', $this->filename ) );
 75+ }
 76+}
 77+
 78+class SeleniumUploadBrokenTiffTest extends SeleniumUploadTiffTest {
 79+ public $name = 'Upload broken Tiff: ';
 80+ private $filename;
 81+ private $errorMsg;
 82+
 83+ public function __construct( $filename, $errorMsg ) {
 84+ parent::__construct();
 85+ $this->filename = $filename;
 86+ $this->name .= $filename;
 87+ $this->errorMsg = $errorMsg;
 88+ }
 89+
 90+ public function runTest() {
 91+ $this->uploadFile( $this->filename );
 92+ $this->assertErrorMsg( $this->errorMsg );
 93+ }
 94+}
 95+
 96+class SeleniumDeleteTiffTest extends SeleniumTestCase {
 97+ public $name = 'Delete Tiff: ';
 98+ private $filename;
 99+
 100+ public function __construct( $filename ) {
 101+ parent::__construct();
 102+ $this->filename = $filename;
 103+ $this->name .= $filename;
 104+ }
 105+
 106+ public function runTest() {
 107+
 108+ $this->open( Selenium::getBaseUrl() . '/index.php?title=Image:'
 109+ . ucfirst( $this->filename ) . '&action=delete' );
 110+ $this->type( 'wpReason', 'Remove test file' );
 111+ $this->click( 'mw-filedelete-submit' );
 112+ $this->waitForPageToLoad( 10000 );
 113+
 114+ // Todo: This message is localized
 115+ $this->assertSeleniumHTMLContains( '//div[@id="bodyContent"]/p',
 116+ ucfirst( $this->filename ) . '.*has been deleted.' );
 117+ }
 118+
 119+}
 120+
 121+class SeleniumEmbedTiffTest extends SeleniumTestCase { //PHPUnit_Extensions_SeleniumTestCase
 122+
 123+ public function tearDown() {
 124+
 125+ parent::tearDown();
 126+ // Clear EmbedTiffTest page for future tests
 127+ $this->open( Selenium::getBaseUrl() .
 128+ '/index.php?title=EmbedTiffTest&action=edit' );
 129+ $this->type( 'wpTextbox1', '' );
 130+ $this->click( 'wpSave' );
 131+ }
 132+
 133+ public function preparePage( $text ) {
 134+
 135+ $this->open( Selenium::getBaseUrl() .
 136+ '/index.php?title=EmbedTiffTest&action=edit' );
 137+ $this->type( 'wpTextbox1', $text );
 138+ $this->click( 'wpSave' );
 139+ $this->waitForPageToLoad( 10000 );
 140+ }
 141+
 142+}
 143+
 144+class SeleniumTiffPageTest extends SeleniumTestCase {
 145+ public function tearDown() {
 146+ parent::tearDown();
 147+ // Clear EmbedTiffTest page for future tests
 148+ $this->open( Selenium::getBaseUrl() . '/index.php?title=Image:'
 149+ . $this->image . '&action=edit' );
 150+ $this->type( 'wpTextbox1', '' );
 151+ $this->click( 'wpSave' );
 152+ }
 153+
 154+ public function prepareImagePage( $image, $text ) {
 155+
 156+ $this->image = $image;
 157+ $this->open( Selenium::getBaseUrl() . '/index.php?title=Image:'
 158+ . $image . '&action=edit' );
 159+ $this->type( 'wpTextbox1', $text );
 160+ $this->click( 'wpSave' );
 161+ $this->waitForPageToLoad( 10000 );
 162+
 163+ }
 164+}
 165+
 166+class SeleniumDisplayInCategoryTest extends SeleniumTiffPageTest {
 167+ public $name = 'Display in category';
 168+
 169+ public function runTest() {
 170+ $this->prepareImagePage( 'Multipage.tiff',
 171+ "[[Category:Wiki]]\n" );
 172+
 173+
 174+ $this->open( Selenium::getBaseUrl() . '/index.php?title=Category:Wiki' );
 175+
 176+ // Ergebnis chekcen
 177+ $source = $this->getAttribute(
 178+ "//div[@class='gallerybox']//a[@class='image']//img@src" );
 179+ $correct = strstr( $source, "-page1-" );
 180+ $this->assertEquals( $correct, true );
 181+ }
 182+}
 183+
 184+class SeleniumDisplayInGalleryTest extends SeleniumEmbedTiffTest {
 185+ public $name = 'Display in gallery';
 186+
 187+ public function runTest() {
 188+ $this->preparePage( "<gallery>\nImage:Multipage.tiff\n</gallery>\n" );
 189+
 190+ //
 191+ //$this->open( Selenium::getBaseUrl() . '/index.php?title=GalleryTest' );
 192+
 193+ // Ergebnis chekcen
 194+ //$source = $this->getAttribute(
 195+ //"//div[@class='gallerybox']//a[@title='Multipage.tiff']//img@src" );
 196+ $source = $this->getAttribute(
 197+ "//div[@class='gallerybox']//a[@class='image']//img@src" );
 198+ $correct = strstr( $source, "-page1-" );
 199+ $this->assertEquals( $correct, true );
 200+
 201+ }
 202+}
 203+
 204+class SeleniumEmbedTiffInclusionTest extends SeleniumEmbedTiffTest {
 205+ public $name = 'Include Tiff Images';
 206+
 207+ public function runTest() {
 208+ $this->preparePage( "[[Image:Multipage.tiff]]\n" );
 209+
 210+ $this->assertSeleniumAttributeEquals(
 211+ "//div[@id='bodyContent']//img@height", '768' );
 212+ $this->assertSeleniumAttributeEquals(
 213+ "//div[@id='bodyContent']//img@width", '1024' );
 214+ }
 215+}
 216+
 217+class SeleniumEmbedTiffThumbRatioTest extends SeleniumEmbedTiffTest {
 218+ public $name = "Include Tiff Thumbnail Aspect Ratio";
 219+
 220+ public function runTest() {
 221+ $this->preparePage( "[[Image:Multipage.tiff|200px]]\n" );
 222+ //$this->selenium->type( 'wpTextbox1',
 223+ // "[[Image:Pc260001.tif|thumb]]\n" );
 224+
 225+ $this->assertSeleniumAttributeEquals(
 226+ "//div[@id='bodyContent']//img@height", '150' );
 227+ $this->assertSeleniumAttributeEquals(
 228+ "//div[@id='bodyContent']//img@width", '200' );
 229+ }
 230+}
 231+
 232+class SeleniumEmbedTiffBoxFitTest extends SeleniumEmbedTiffTest {
 233+ public $name = 'Include Tiff Box Fit';
 234+
 235+ public function runTest() {
 236+ $this->preparePage( "[[Image:Multipage.tiff|200x75px]]\n" );
 237+
 238+ $this->assertSeleniumAttributeEquals(
 239+ "//div[@id='bodyContent']//img@height", '75' );
 240+ $this->assertSeleniumAttributeEquals(
 241+ "//div[@id='bodyContent']//img@width", '100' );
 242+ }
 243+}
 244+
 245+class SeleniumEmbedTiffPage2InclusionTest extends SeleniumEmbedTiffTest {
 246+ public $name = 'Include Tiff Images: Page 2';
 247+
 248+ public function runTest() {
 249+ $this->preparePage( "[[Image:Multipage.tiff|page=2]]\n" );
 250+ //$this->selenium->type( 'wpTextbox1', "[[Image:Pc260001.tif|thumb]]\n" );
 251+
 252+ $this->assertSeleniumAttributeEquals(
 253+ "//div[@id='bodyContent']//img@height", '564' );
 254+ $this->assertSeleniumAttributeEquals(
 255+ "//div[@id='bodyContent']//img@width", '640' );
 256+ }
 257+}
 258+
 259+class SeleniumEmbedTiffPage2ThumbRatioTest extends SeleniumEmbedTiffTest {
 260+ public $name = 'Include Tiff Thumbnail Aspect Ratio: Page 2';
 261+
 262+ public function runTest() {
 263+ $this->preparePage( "[[Image:Multipage.tiff|320px|page=2]]\n" );
 264+
 265+ $this->assertSeleniumAttributeEquals(
 266+ "//div[@id='bodyContent']//img@height", '282' );
 267+ $this->assertSeleniumAttributeEquals(
 268+ "//div[@id='bodyContent']//img@width", '320' );
 269+ }
 270+}
 271+
 272+class SeleniumEmbedTiffPage2BoxFitTest extends SeleniumEmbedTiffTest {
 273+ public $name = 'Include Tiff Box Fit: Page 2';
 274+
 275+ public function runTest() {
 276+ $this->preparePage( "[[Image:Multipage.tiff|200x108px|page=2]]\n" );
 277+
 278+ $this->assertSeleniumAttributeEquals(
 279+ "//div[@id='bodyContent']//img@height", '108' );
 280+ $this->assertSeleniumAttributeEquals(
 281+ "//div[@id='bodyContent']//img@width", '123' );
 282+ }
 283+}
 284+
 285+class SeleniumEmbedTiffNegativePageParameterTest extends SeleniumEmbedTiffTest {
 286+ public $name = 'Include Tiff: negative page parameter';
 287+
 288+ public function runTest() {
 289+ $this->preparePage( "[[Image:Multipage.tiff|page=-1]]\n" );
 290+
 291+ $source = $this->getAttribute( "//div[@id='bodyContent']//img@src" );
 292+ $correct = strstr( $source, "-page1-" );
 293+ $this->assertEquals( $correct, true );
 294+ }
 295+}
 296+
 297+class SeleniumEmbedTiffPageParameterTooHighTest extends SeleniumEmbedTiffTest {
 298+ public $name = 'Include Tiff: too high page parameter';
 299+
 300+ public function runTest() {
 301+ $this->preparePage( "[[Image:Multipage.tiff|page=8]]\n" );
 302+
 303+ $source = $this->getAttribute( "//div[@id='bodyContent']//img@src" );
 304+ $correct = strstr( $source, "-page7-" );
 305+ $this->assertEquals( $correct, true );
 306+ }
 307+}
 308+
Property changes on: branches/wmf/1.16wmf4/extensions/PagedTiffHandler/selenium/PagedTiffHandlerTestCases.php
___________________________________________________________________
Added: svn:keywords
1309 + LastChangedDate LastChangedBy Revision Id
Added: svn:eol-style
2310 + native
Index: branches/wmf/1.16wmf4/extensions/PagedTiffHandler/tests/testImages/caspian.tif
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/caspian.tif
___________________________________________________________________
Added: svn:mime-type
3311 + application/octet-stream
Index: branches/wmf/1.16wmf4/extensions/PagedTiffHandler/tests/testImages/SOURCES.txt
@@ -0,0 +1,16 @@
 2+multipage.tiff created by ImageMagick 6.5.0-0 2009-03-09 Q16 OpenMP http://www.imagemagick.org
 3+Command: convert.exe * -adjoin multipage.tiff
 4+
 5+Bridge.jpg http://commons.wikimedia.org/wiki/File:Regensburg_Steinerne_Bruecke.jpg
 6+Caffeine.png http://commons.wikimedia.org/wiki/File:Caffeine-3D-vdW.png
 7+Mars.jpg http://commons.wikimedia.org/wiki/File:MarsTopoMap-PIA02031_modest_cropped_monochrome.jpg
 8+
 9+Pogona.jpg To the extent possible under law, Marc Reymann has waived all copyright
 10+Snake1.jpg and related or neighboring rights to these four pictures.
 11+Snake2.jpg This work is published from Germany.
 12+Venice.jpg
 13+
 14+----------
 15+
 16+caspian.tif taken from libtiff test images. Obviously they are under no license. you can obtain the
 17+ whole set of test images from http://www.libtiff.org/images.html
\ No newline at end of file
Property changes on: branches/wmf/1.16wmf4/extensions/PagedTiffHandler/tests/testImages/SOURCES.txt
___________________________________________________________________
Added: svn:eol-style
118 + native
Index: branches/wmf/1.16wmf4/extensions/PagedTiffHandler/tests/testImages/multipage.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/multipage.tiff
___________________________________________________________________
Added: svn:mime-type
219 + application/octet-stream
Index: branches/wmf/1.16wmf4/extensions/PagedTiffHandler/tests/PagedTiffHandlerTest.php
@@ -0,0 +1,207 @@
 2+<?php
 3+/**
 4+ * To get this working you must
 5+ * - set a valid path to PEAR
 6+ * - check upload size in php.ini: Multipage.tiff needs at least 3M
 7+ * - Upload the image caspian.tif without PagedTiffHandler being active
 8+ * Caution: you need to allow tiff for upload:
 9+ * $wgFileExtensions[] = 'tiff';
 10+ * $wgFileExtensions[] = 'tif';
 11+ * - Upload multipage.tiff when PagedTiffHandler is active
 12+ */
 13+
 14+if ( getenv( 'MW_INSTALL_PATH' ) ) {
 15+ $IP = getenv( 'MW_INSTALL_PATH' );
 16+} else {
 17+ $IP = dirname( __FILE__ ) . '/../../..';
 18+}
 19+require_once( "$IP/maintenance/commandLine.inc" );
 20+
 21+// requires PHPUnit 3.4
 22+require_once 'PHPUnit/Framework.php';
 23+
 24+error_reporting( E_ALL );
 25+
 26+class PagedTiffHandlerTest extends PHPUnit_Framework_TestCase {
 27+
 28+ private $handler;
 29+ private $image;
 30+ private $preCheckError;
 31+
 32+ function setUp( $autoUpload = false ) {
 33+ global $wgTitle;
 34+ $wgTitle = Title::newFromText( 'PagedTiffHandler_UnitTest' );
 35+
 36+ $this->handler = new PagedTiffHandler();
 37+ if ( !file_exists( dirname( __FILE__ ) . '/testImages' ) ) {
 38+ echo "testImages directory cannot be found.\n";
 39+ $this->preCheckError = true;
 40+ }
 41+ if ( !file_exists( dirname( __FILE__ ) . '/testImages/caspian.tif' ) ) {
 42+ echo "testImages/caspian.tif cannot be found.\n";
 43+ $this->preCheckError = true;
 44+ }
 45+ if ( !file_exists( dirname( __FILE__ ) . '/testImages/multipage.tiff' ) ) {
 46+ echo "testImages/Multipage.tif cannot be found.\n";
 47+ $this->preCheckError = true;
 48+ }
 49+
 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";
 73+ $this->preCheckError = true;
 74+ }
 75+
 76+ }
 77+
 78+ $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";
 94+ $this->preCheckError = true;
 95+ }
 96+
 97+ }
 98+
 99+ $this->path = dirname(__FILE__) . '/testImages/multipage.tiff';
 100+ }
 101+
 102+ function runTest() {
 103+ global $wgLanguageCode;
 104+ // do not execute test if preconditions check returned false;
 105+ if ( $this->preCheckError ) {
 106+ return false;
 107+ }
 108+ // ---- Parameter handling and lossy parameter
 109+ // validateParam
 110+ $this->assertTrue( $this->handler->validateParam( 'lossy', '0' ) );
 111+ $this->assertTrue( $this->handler->validateParam( 'lossy', '1' ) );
 112+ $this->assertTrue( $this->handler->validateParam( 'lossy', 'false' ) );
 113+ $this->assertTrue( $this->handler->validateParam( 'lossy', 'true' ) );
 114+ $this->assertTrue( $this->handler->validateParam( 'lossy', 'lossy' ) );
 115+ $this->assertTrue( $this->handler->validateParam( 'lossy', 'lossless' ) );
 116+ // normaliseParams
 117+ // here, boxfit behavior is tested
 118+ $params = array( 'width' => '100', 'height' => '100', 'page' => '4' );
 119+ $this->handler->normaliseParams( $this->image, $params );
 120+ $this->assertEquals( $params['height'], 75 );
 121+ // lossy and lossless
 122+ $params = array('width'=>'100', 'height'=>'100', 'page'=>'1');
 123+ $this->handler->normaliseParams($this->image, $params );
 124+ $this->assertEquals($params['lossy'], 'lossy');
 125+ $params = array('width'=>'100', 'height'=>'100', 'page'=>'2');
 126+ $this->handler->normaliseParams($this->image, $params );
 127+ $this->assertEquals($params['lossy'], 'lossless');
 128+ // makeParamString
 129+ $this->assertEquals(
 130+ $this->handler->makeParamString(
 131+ array(
 132+ 'width' => '100',
 133+ 'page' => '4',
 134+ 'lossy' => 'lossless'
 135+ )
 136+ ),
 137+ 'lossless-page4-100px'
 138+ );
 139+ // ---- File upload checks and Thumbnail transformation
 140+ // check
 141+ // 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 );
 144+ $this->assertEquals( $error, 'tiff_bad_file' );
 145+ // 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 ) );
 148+ $this->assertEquals( $error->textMsg, wfMsg( 'thumbnail_error', wfMsg( 'tiff_bad_file' ) ) );
 149+ // ---- Image information
 150+ // getThumbType
 151+ $type = $this->handler->getThumbType( '.tiff', 'image/tiff', array( 'lossy' => 'lossy' ) );
 152+ $this->assertEquals( $type[0], 'jpg' );
 153+ $this->assertEquals( $type[1], 'image/jpeg' );
 154+
 155+ $type = $this->handler->getThumbType( '.tiff', 'image/tiff', array( 'lossy' => 'lossless' ) );
 156+ $this->assertEquals( $type[0], 'png' );
 157+ $this->assertEquals( $type[1], 'image/png' );
 158+
 159+ // getLongDesc
 160+ 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' ) );
 162+ } else {
 163+ // English
 164+ $this->assertEquals( $this->handler->getLongDesc( $this->image ), wfMsg( 'tiff-file-info-size', '1,024', '768', '2.64 MB', 'image/tiff', '1' ) );
 165+ }
 166+ // pageCount
 167+ $this->assertEquals( $this->handler->pageCount( $this->image ), 7 );
 168+ // 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 ) );
 177+ // 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 ) );
 179+ // isMultiPage
 180+ $this->assertTrue( $this->handler->isMultiPage( $this->image ) );
 181+
 182+ // ---- Metadata handling
 183+ // getMetadata
 184+ $metadata = $this->handler->getMetadata( false, $this->path );
 185+ $this->assertTrue( strpos( $metadata, '"page_amount";i:7' ) !== false );
 186+ // isMetadataValid
 187+ $this->assertTrue( $this->handler->isMetadataValid( $this->image, $metadata ) );
 188+ // getMetaArray
 189+ $metaArray = $this->handler->getMetaArray( $this->image );
 190+
 191+ $this->assertEquals( $metaArray['page_amount'], 7 );
 192+ //this is also strtolower in PagedTiffHandler::getThumbExtension
 193+ $this->assertEquals( strtolower( $metaArray['page_data'][1]['alpha'] ), 'false' );
 194+ $this->assertEquals( strtolower( $metaArray['page_data'][2]['alpha'] ), 'true' );
 195+ $this->assertEquals( $metaArray['exif']['PhotometricInterpretation'], 2 ); //RGB
 196+ // formatMetadata
 197+ $formattedMetadata = $this->handler->formatMetadata( $this->image );
 198+ $this->assertEquals( $formattedMetadata['collapsed'][3]['value'], 'RGB' ); //XXX: brittle, index might change.
 199+ }
 200+
 201+}
 202+$wgShowExceptionDetails = true;
 203+
 204+$t = new PagedTiffHandlerTest();
 205+$t->setUp( true );
 206+$t->runTest();
 207+
 208+echo "OK.\n";
\ No newline at end of file
Property changes on: branches/wmf/1.16wmf4/extensions/PagedTiffHandler/tests/PagedTiffHandlerTest.php
___________________________________________________________________
Added: svn:keywords
1209 + LastChangedDate LastChangedBy Revision Id
Added: svn:eol-style
2210 + native
Index: branches/wmf/1.16wmf4/extensions/PagedTiffHandler/PagedTiffHandler_body.php
@@ -0,0 +1,645 @@
 2+<?php
 3+/**
 4+ * Copyright © Wikimedia Deutschland, 2009
 5+ * Authors Hallo Welt! Medienwerkstatt GmbH
 6+ * Authors Sebastian Ulbricht, Daniel Lynge, Marc Reymann, Markus Glaser
 7+ *
 8+ * This program is free software; you can redistribute it and/or modify
 9+ * it under the terms of the GNU General Public License as published by
 10+ * the Free Software Foundation; either version 2 of the License, or
 11+ * (at your option) any later version.
 12+ *
 13+ * This program is distributed in the hope that it will be useful,
 14+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
 15+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 16+ * GNU General Public License for more details.
 17+ *
 18+ * You should have received a copy of the GNU General Public License along
 19+ * with this program; if not, write to the Free Software Foundation, Inc.,
 20+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 21+ * http://www.gnu.org/copyleft/gpl.html
 22+ */
 23+
 24+class PagedTiffHandler extends ImageHandler {
 25+ /**
 26+ * Add the "lossy"-parameter to image link.
 27+ * Usage:
 28+ * lossy=true|false
 29+ * lossy=1|0
 30+ * lossy=lossy|lossless
 31+ * E.g. [[Image:Test.tif|lossy=1]]
 32+ */
 33+ static function addTiffLossyMagicWordLang( &$magicWords, $langCode ) {
 34+ $magicWords['img_lossy'] = array( 0, "lossy=$1" );
 35+ return true;
 36+ }
 37+
 38+ function isEnabled() {
 39+ return true;
 40+ }
 41+
 42+ function mustRender( $img ) {
 43+ return true;
 44+ }
 45+
 46+ function isMultiPage( $img ) {
 47+ if ( !$img ) {
 48+ return true;
 49+ }
 50+ $meta = unserialize( $img->metadata );
 51+ return $meta['page_amount'] > 1;
 52+ }
 53+
 54+ /**
 55+ * Various checks against the uploaded file
 56+ * - maximum upload size
 57+ * - maximum number of embedded files
 58+ * - maximum size of metadata
 59+ * - identify-errors
 60+ * - identify-warnings
 61+ * - check for running-identify-service
 62+ */
 63+ static function check( $saveName, $tempName, &$error ) {
 64+ global $wgTiffMaxEmbedFiles, $wgTiffMaxMetaSize, $wgMaxUploadSize,
 65+ $wgTiffRejectOnError, $wgTiffRejectOnWarning, $wgTiffUseTiffReader,
 66+ $wgTiffReaderPath, $wgTiffReaderCheckEofForJS;
 67+ wfLoadExtensionMessages( 'PagedTiffHandler' );
 68+ if ( $wgTiffUseTiffReader ) {
 69+ $tr = new TiffReader( $tempName );
 70+ $tr->check();
 71+ if ( !$tr->isValidTiff() ) {
 72+ $error = 'tiff_bad_file';
 73+ wfDebug( __METHOD__ . ": $error ($saveName)\n" );
 74+ return false;
 75+ }
 76+ if ( $tr->checkScriptAtEnd( $wgTiffReaderCheckEofForJS ) ) {
 77+ $error = 'tiff_script_detected';
 78+ wfDebug( __METHOD__ . ": $error ($saveName)\n" );
 79+ return false;
 80+ }
 81+ if ( !$tr->checkSize() ) {
 82+ $error = 'tiff_size_error';
 83+ wfDebug( __METHOD__ . ": $error ($saveName)\n" );
 84+ return false;
 85+ }
 86+ }
 87+ $meta = self::getTiffImage( false, $tempName )->retrieveMetaData();
 88+ if ( !$meta && $meta != - 1 ) {
 89+ $error = 'tiff_out_of_service';
 90+ wfDebug( __METHOD__ . ": $error ($saveName)\n" );
 91+ return false;
 92+ }
 93+ if ( $meta == - 1 ) {
 94+ $error = 'tiff_error_cached';
 95+ wfDebug( __METHOD__ . ": $error ($saveName)\n" );
 96+ }
 97+ return self::extCheck( $meta, $error, $saveName );
 98+ }
 99+
 100+ static function extCheck( $meta, &$error, $saveName = '' ) {
 101+ global $wgTiffMaxEmbedFiles, $wgTiffMaxMetaSize;
 102+
 103+ $errors = PagedTiffHandler::getMetadataErrors( $meta );
 104+ if ( $errors ) {
 105+ $error = 'tiff_bad_file';
 106+
 107+ // NOTE: in future, it will become possible to pass parameters
 108+ // $error = array( 'tiff_bad_file' , PagedTiffHandler::joinMessages( $errors ) );
 109+ // does that work now? ^DK
 110+
 111+ wfDebug( __METHOD__ . ": $error ($saveName) " . PagedTiffHandler::joinMessages( $errors, false ) . "\n" );
 112+ return false;
 113+ }
 114+ if ( ( strlen( serialize( $meta ) ) + 1 ) > $wgTiffMaxMetaSize ) {
 115+ $error = 'tiff_too_much_meta';
 116+ wfDebug( __METHOD__ . ": $error ($saveName)\n" );
 117+ return false;
 118+ }
 119+ if ( $wgTiffMaxEmbedFiles && $meta['page_amount'] > $wgTiffMaxEmbedFiles ) {
 120+ $error = 'tiff_too_much_embed_files';
 121+ wfDebug( __METHOD__ . ": $error ($saveName)\n" );
 122+ return false;
 123+ }
 124+ return true;
 125+ }
 126+
 127+ /**
 128+ * Maps MagicWord-IDs to parameters.
 129+ * In this case, width, page, and lossy.
 130+ */
 131+ function getParamMap() {
 132+ return array(
 133+ 'img_width' => 'width',
 134+ 'img_page' => 'page',
 135+ 'img_lossy' => 'lossy',
 136+ );
 137+ }
 138+
 139+
 140+ /**
 141+ * Checks whether parameters are valid and have valid values.
 142+ * Check for lossy was added.
 143+ */
 144+ function validateParam( $name, $value ) {
 145+ if ( in_array( $name, array( 'width', 'height', 'page', 'lossy' ) ) ) {
 146+ if ( $name == 'lossy' ) {
 147+ return in_array( $value, array( 1, 0, '1', '0', 'true', 'false', 'lossy', 'lossless' ) );
 148+ } elseif ( $value <= 0 || $value > 65535 ) { // ImageMagick overflows for values > 65536
 149+ return false;
 150+ } else {
 151+ return true;
 152+ }
 153+ } else {
 154+ return false;
 155+ }
 156+ }
 157+
 158+ /**
 159+ * Creates parameter string for file name.
 160+ * Page number was added.
 161+ */
 162+ function makeParamString( $params ) {
 163+ if ( !isset( $params['width'] ) || !isset( $params['lossy'] ) || !isset( $params['page'] )) {
 164+ return false;
 165+ }
 166+
 167+ return "{$params['lossy']}-page{$params['page']}-{$params['width']}px";
 168+ }
 169+
 170+ /**
 171+ * Parses parameter string into an array.
 172+ */
 173+ function parseParamString( $str ) {
 174+ $m = false;
 175+ if ( preg_match( '/^(\w+)-page(\d+)-(\d+)px$/', $str, $m ) ) {
 176+ return array( 'width' => $m[3], 'page' => $m[2], 'lossy' => $m[1] );
 177+ } else {
 178+ return false;
 179+ }
 180+ }
 181+
 182+ /**
 183+ * The function is used to specify which parameters to File::transform() should be
 184+ * passed through to thumb.php, in the case where the configuration specifies
 185+ * thumb.php is to be used (e.g. $wgThumbnailScriptPath !== false). You should
 186+ * pass through the same parameters as in makeParamString().
 187+ */
 188+ function getScriptParams( $params ) {
 189+ return array(
 190+ 'width' => $params['width'],
 191+ 'page' => $params['page'],
 192+ 'lossy' => $params['lossy'],
 193+ );
 194+ }
 195+
 196+ /**
 197+ * Prepares param array and sets standard values.
 198+ * Adds normalisation for parameter "lossy".
 199+ */
 200+ function normaliseParams( $image, &$params ) {
 201+ if ( !parent::normaliseParams( $image, $params ) ) {
 202+ return false;
 203+ }
 204+
 205+ $data = $this->getMetaArray( $image );
 206+ if ( !$data ) {
 207+ return false;
 208+ }
 209+
 210+ if ( isset( $params['lossy'] ) ) {
 211+ if ( in_array( $params['lossy'], array( 1, '1', 'true', 'lossy' ) ) ) {
 212+ $params['lossy'] = 'lossy';
 213+ } else {
 214+ $params['lossy'] = 'lossless';
 215+ }
 216+ } else {
 217+ if ( ( strtolower( $data['page_data'][$params['page']]['alpha'] ) == 'true' ) ) {
 218+ $params['lossy'] = 'lossless';
 219+ } else {
 220+ $params['lossy'] = 'lossy';
 221+ }
 222+ }
 223+
 224+ return true;
 225+ }
 226+
 227+ static function getMetadataErrors( $metadata ) {
 228+ if ( is_string( $metadata ) ) {
 229+ $metadata = unserialize( $metadata );
 230+ }
 231+
 232+ if ( !$metadata ) {
 233+ return true;
 234+ } else if ( isset( $metadata[ 'errors' ] ) ) {
 235+ return $metadata[ 'errors' ];
 236+ } else {
 237+ return false;
 238+ }
 239+ }
 240+
 241+ static function joinMessages( $errors_raw, $to_html = true ) {
 242+ if ( is_array( $errors_raw ) ) {
 243+ if ( !$errors_raw ) {
 244+ return false;
 245+ }
 246+
 247+ $errors = array();
 248+ foreach ( $errors_raw as $error ) {
 249+ if ( $error === false || $error === null || $error === 0 || $error === '' )
 250+ continue;
 251+
 252+ $error = trim( $error );
 253+
 254+ if ( $error === '' )
 255+ continue;
 256+
 257+ if ( $to_html )
 258+ $error = htmlspecialchars( $error );
 259+
 260+ $errors[] = $error;
 261+ }
 262+
 263+ if ( $to_html ) {
 264+ return trim( join( '<br />', $errors ) );
 265+ } else {
 266+ return trim( join( ";\n", $errors ) );
 267+ }
 268+ }
 269+
 270+ return $errors_raw;
 271+ }
 272+
 273+ /**
 274+ * Checks whether a thumbnail with the requested file type and resolution exists,
 275+ * creates it if necessary, unless self::TRANSFORM_LATER is set in $flags.
 276+ * Supports extra parameters for multipage files and thumbnail type (lossless vs. lossy)
 277+ */
 278+ function doTransform( $image, $dstPath, $dstUrl, $params, $flags = 0 ) {
 279+ global $wgImageMagickConvertCommand, $wgMaxImageAreaForVips,
 280+ $wgTiffUseVips, $wgTiffVipsCommand, $wgMaxImageArea;
 281+
 282+ $meta = $this->getMetaArray( $image );
 283+ $errors = PagedTiffHandler::getMetadataErrors( $meta );
 284+
 285+ if ( $errors ) {
 286+ $errors = PagedTiffHandler::joinMessages( $errors );
 287+ if ( is_string( $errors ) ) {
 288+ // TODO: original error as param // TESTME
 289+ return $this->doThumbError( $params, 'tiff_bad_file' );
 290+ } else {
 291+ return $this->doThumbError( $params, 'tiff_no_metadata' );
 292+ }
 293+ }
 294+
 295+ if ( !$this->normaliseParams( $image, $params ) )
 296+ return new TransformParameterError( $params );
 297+
 298+ // Get params and force width, height and page to be integers
 299+ $width = intval( $params['width'] );
 300+ $height = intval( $params['height'] );
 301+ $srcPath = $image->getPath();
 302+ $page = intval( $params['page'] );
 303+
 304+ if ( $flags & self::TRANSFORM_LATER ) {
 305+ // pretend the thumbnail exists, let it be created by a 404-handler
 306+ return new ThumbnailImage( $image, $dstUrl, $width, $height, $dstPath, $page );
 307+ }
 308+
 309+ if ( !self::extCheck( $meta, $error, $dstPath ) ) {
 310+ return $this->doThumbError( $params, $error );
 311+ }
 312+
 313+ if ( is_file( $dstPath ) ) {
 314+ return new ThumbnailImage( $image, $dstUrl, $width,
 315+ $height, $dstPath, $page );
 316+ }
 317+
 318+ if ( !wfMkdirParents( dirname( $dstPath ) ) )
 319+ return $this->doThumbError( $params, 'thumbnail_dest_directory' );
 320+
 321+ if ( $wgTiffUseVips ) {
 322+ $pagesize = PagedTiffImage::getPageSize($meta, $page);
 323+ if ( !$pagesize ) {
 324+ return $this->doThumbError( $params, 'tiff_no_metadata' );
 325+ }
 326+ if ( isset( $meta['page_data'][$page]['pixels'] )
 327+ && $meta['page_data'][$page]['pixels'] > $wgMaxImageAreaForVips )
 328+ return $this->doThumbError( $params, 'tiff_sourcefile_too_large' );
 329+
 330+ if ( ( $width * $height ) > $wgMaxImageAreaForVips )
 331+ return $this->doThumbError( $params, 'tiff_targetfile_too_large' );
 332+
 333+ // Shrink factors must be > 1.
 334+ if ( ( $pagesize['width'] > $width ) && ( $pagesize['height'] > $height ) ) {
 335+ $xfac = $pagesize['width'] / $width;
 336+ $yfac = $pagesize['height'] / $height;
 337+ // tested in Linux and Windows
 338+ $cmd = wfEscapeShellArg( $wgTiffVipsCommand );
 339+ $cmd .= ' im_shrink "' . wfEscapeShellArg( $srcPath ) . ':' . ( $page - 1 ) . '" ';
 340+ $cmd .= wfEscapeShellArg( $dstPath );
 341+ $cmd .= " {$xfac} {$yfac} 2>&1";
 342+ } else {
 343+ // tested in Linux and Windows
 344+ $cmd = wfEscapeShellArg( $wgTiffVipsCommand );
 345+ $cmd .= ' im_resize_linear "' . wfEscapeShellArg( $srcPath ) . ':' . ( $page - 1 ) . '" ';
 346+ $cmd .= wfEscapeShellArg( $dstPath );
 347+ $cmd .= " {$width} {$height} 2>&1";
 348+ }
 349+ } else {
 350+ if ( ( $width * $height ) > $wgMaxImageArea )
 351+ return $this->doThumbError( $params, 'tiff_targetfile_too_large' );
 352+ if ( isset( $meta['page_data'][$page]['pixels'] )
 353+ && $meta['page_data'][$page]['pixels'] > $wgMaxImageArea )
 354+ return $this->doThumbError( $params, 'tiff_sourcefile_too_large' );
 355+ $cmd = wfEscapeShellArg( $wgImageMagickConvertCommand );
 356+ $cmd .= " " . wfEscapeShellArg( $srcPath ) . "[" . ( $page - 1 ) . "]";
 357+ $cmd .= " -depth 8 -resize {$width} ";
 358+ $cmd .= wfEscapeShellArg( $dstPath );
 359+ }
 360+
 361+ wfRunHooks( 'PagedTiffHandlerRenderCommand', array( &$cmd, $srcPath, $dstPath, $page, $width, $height ) );
 362+
 363+ wfProfileIn( 'PagedTiffHandler' );
 364+ wfDebug( __METHOD__ . ": $cmd\n" );
 365+ $err = wfShellExec( $cmd, $retval );
 366+ wfProfileOut( 'PagedTiffHandler' );
 367+
 368+ $removed = $this->removeBadFile( $dstPath, $retval );
 369+
 370+ if ( $retval != 0 || $removed ) {
 371+ wfDebugLog( 'thumbnail', "thumbnail failed on " . wfHostname() .
 372+ "; error $retval \"$err\" from \"$cmd\"" );
 373+ return new MediaTransformError( 'thumbnail_error', $width, $height, $err );
 374+ } else {
 375+ return new ThumbnailImage( $image, $dstUrl, $width, $height, $dstPath, $page );
 376+ }
 377+ }
 378+
 379+ /**
 380+ * Get the thumbnail extension and MIME type for a given source MIME type
 381+ * @return array thumbnail extension and MIME type
 382+ */
 383+ function getThumbType( $ext, $mime, $params=null ) {
 384+ if ( $params[ 'lossy' ] == 'lossy' ) {
 385+ return array( 'jpg', 'image/jpeg' );
 386+ } else {
 387+ return array( 'png', 'image/png' );
 388+ }
 389+ }
 390+
 391+ /**
 392+ * Returns the number of available pages/embedded files
 393+ */
 394+ function pageCount( $image ) {
 395+ $data = $this->getMetaArray( $image );
 396+ if ( !$data ) {
 397+ return false;
 398+ }
 399+ return intval( $data['page_amount'] );
 400+ }
 401+
 402+ /**
 403+ * Returns a new error message.
 404+ */
 405+ protected function doThumbError( $params, $msg ) {
 406+ global $wgUser, $wgThumbLimits;
 407+
 408+ if ( empty( $params['width'] ) ) {
 409+ // no usable width/height in the parameter array
 410+ // only happens if we don't have image meta-data, and no
 411+ // size was specified by the user.
 412+ // we need to pick *some* size, and the preferred
 413+ // thumbnail size seems sane.
 414+ $sz = $wgUser->getOption( 'thumbsize' );
 415+ $width = $wgThumbLimits[ $sz ];
 416+ $height = $width; // we don't have a height or aspect ratio. make it square.
 417+ } else {
 418+ $width = intval( $params['width'] );
 419+
 420+ if ( !empty( $params['height'] ) ) {
 421+ $height = intval( $params['height'] );
 422+ } else {
 423+ $height = $width; // we don't have a height or aspect ratio. make it square.
 424+ }
 425+ }
 426+
 427+ wfLoadExtensionMessages( 'PagedTiffHandler' );
 428+ return new MediaTransformError( 'thumbnail_error',
 429+ $width, $height, wfMsg( $msg ) );
 430+ }
 431+
 432+ /**
 433+ * Get handler-specific metadata which will be saved in the img_metadata field.
 434+ *
 435+ * @param $image Image: the image object, or false if there isn't one
 436+ * @param $path String: path to the image?
 437+ * @return string
 438+ */
 439+ function getMetadata( $image, $path ) {
 440+ return serialize( $this->getTiffImage( $image, $path )->retrieveMetaData() );
 441+ }
 442+
 443+ /**
 444+ * Creates detail information that is being displayed on image page.
 445+ */
 446+ function getLongDesc( $image ) {
 447+ global $wgLang, $wgRequest;
 448+ $page = $wgRequest->getText( 'page', 1 );
 449+ if ( !isset( $page ) || $page < 1 ) {
 450+ $page = 1;
 451+ }
 452+ if ( $page > $this->pageCount( $image ) ) {
 453+ $page = $this->pageCount( $image );
 454+ }
 455+ $metadata = $this->getMetaArray( $image );
 456+ if ( $metadata ) {
 457+ wfLoadExtensionMessages( 'PagedTiffHandler' );
 458+ return wfMsgExt(
 459+ 'tiff-file-info-size',
 460+ 'parseinline',
 461+ $wgLang->formatNum( $metadata['page_data'][$page]['width'] ),
 462+ $wgLang->formatNum( $metadata['page_data'][$page]['height'] ),
 463+ $wgLang->formatSize( $image->getSize() ),
 464+ $image->getMimeType(),
 465+ $page
 466+ );
 467+ }
 468+ return true;
 469+ }
 470+
 471+ /**
 472+ * Check if the metadata string is valid for this handler.
 473+ * If it returns false, Image will reload the metadata from the file and update the database
 474+ */
 475+ function isMetadataValid( $image, $metadata ) {
 476+
 477+ if ( !empty( $metadata ) && $metadata != serialize( array() ) ) {
 478+ $meta = unserialize( $metadata );
 479+ if ( isset( $meta['errors'] ) ) {
 480+ // metadata contains an error message, but it's valid.
 481+ // don't try to re-render until the error is resolved!
 482+ return true;
 483+ }
 484+ if ( isset( $meta['page_amount'] ) && isset( $meta['page_data'] ) ) {
 485+ return true;
 486+ }
 487+ }
 488+ return false;
 489+ }
 490+
 491+ /**
 492+ * Get a list of EXIF metadata items which should be displayed when
 493+ * the metadata table is collapsed.
 494+ *
 495+ * @return array of strings
 496+ * @access private
 497+ */
 498+ function visibleMetadataFields() {
 499+ $fields = array();
 500+ $lines = explode( "\n", wfMsg( 'metadata-fields' ) );
 501+ foreach ( $lines as $line ) {
 502+ $matches = array();
 503+ if ( preg_match( '/^\\*\s*(.*?)\s*$/', $line, $matches ) ) {
 504+ $fields[] = $matches[1];
 505+ }
 506+ }
 507+ $fields = array_map( 'strtolower', $fields );
 508+ return $fields;
 509+ }
 510+
 511+ /**
 512+ * Get an array structure that looks like this:
 513+ *
 514+ * array(
 515+ * 'visible' => array(
 516+ * 'Human-readable name' => 'Human readable value',
 517+ * ...
 518+ * ),
 519+ * 'collapsed' => array(
 520+ * 'Human-readable name' => 'Human readable value',
 521+ * ...
 522+ * )
 523+ * )
 524+ * The UI will format this into a table where the visible fields are always
 525+ * visible, and the collapsed fields are optionally visible.
 526+ *
 527+ * The function should return false if there is no metadata to display.
 528+ */
 529+
 530+ function formatMetadata( $image ) {
 531+ $result = array(
 532+ 'visible' => array(),
 533+ 'collapsed' => array()
 534+ );
 535+ $metadata = $image->getMetadata();
 536+ if ( !$metadata ) {
 537+ return false;
 538+ }
 539+ $exif = unserialize( $metadata );
 540+ $exif = $exif['exif'];
 541+ if ( !$exif ) {
 542+ return false;
 543+ }
 544+ unset( $exif['MEDIAWIKI_EXIF_VERSION'] );
 545+ $format = new FormatExif( $exif );
 546+
 547+ $formatted = $format->getFormattedData();
 548+ // Sort fields into visible and collapsed
 549+ $visibleFields = $this->visibleMetadataFields();
 550+ foreach ( $formatted as $name => $value ) {
 551+ $tag = strtolower( $name );
 552+ self::addMeta( $result,
 553+ in_array( $tag, $visibleFields ) ? 'visible' : 'collapsed',
 554+ 'exif',
 555+ $tag,
 556+ htmlspecialchars( $value )
 557+ );
 558+ }
 559+ $meta = unserialize( $metadata );
 560+ $errors_raw = PagedTiffHandler::getMetadataErrors( $meta );
 561+ if ( $errors_raw ) {
 562+ $errors = PagedTiffHandler::joinMessages( $errors_raw );
 563+ self::addMeta( $result,
 564+ 'collapsed',
 565+ 'metadata',
 566+ 'error',
 567+ $errors
 568+ );
 569+ // XXX: need translation for <metadata-error>
 570+ }
 571+ if ( !empty( $meta['warnings'] ) ) {
 572+ $warnings = PagedTiffHandler::joinMessages( $meta['warnings'] );
 573+ self::addMeta( $result,
 574+ 'collapsed',
 575+ 'metadata',
 576+ 'warning',
 577+ $warnings
 578+ );
 579+ // XXX: need translation for <metadata-warning>
 580+ }
 581+ return $result;
 582+ }
 583+
 584+ /**
 585+ * Returns a PagedTiffImage or creates a new one if it doesn't exist.
 586+ * @param $image Image: The image object, or false if there isn't one
 587+ * @param $path String: path to the image?
 588+ */
 589+ static function getTiffImage( $image, $path ) {
 590+ // If no Image object is passed, a TiffImage is created based on $path .
 591+ // If there is an Image object, we check whether there's already a TiffImage
 592+ // instance in there; if not, a new instance is created and stored in the Image object
 593+ if ( !$image ) {
 594+ $tiffimg = new PagedTiffImage( $path );
 595+ } elseif ( !isset( $image->tiffImage ) ) {
 596+ $tiffimg = $image->tiffImage = new PagedTiffImage( $path );
 597+ } else {
 598+ $tiffimg = $image->tiffImage;
 599+ }
 600+
 601+ return $tiffimg;
 602+ }
 603+
 604+ /**
 605+ * Returns an Array with the Image metadata.
 606+ */
 607+ function getMetaArray( $image ) {
 608+ if ( isset( $image->tiffMetaArray ) ) {
 609+ return $image->tiffMetaArray;
 610+ }
 611+
 612+ $metadata = $image->getMetadata();
 613+
 614+ if ( !$this->isMetadataValid( $image, $metadata ) ) {
 615+ wfDebug( "Tiff metadata is invalid or missing, should have been fixed in upgradeRow\n" );
 616+ return false;
 617+ }
 618+
 619+ wfProfileIn( __METHOD__ );
 620+ wfSuppressWarnings();
 621+ $image->tiffMetaArray = unserialize( $metadata );
 622+ wfRestoreWarnings();
 623+ wfProfileOut( __METHOD__ );
 624+
 625+ return $image->tiffMetaArray;
 626+ }
 627+
 628+ /**
 629+ * Get an associative array of page dimensions
 630+ * Currently "width" and "height" are understood, but this might be
 631+ * expanded in the future.
 632+ * Returns false if unknown or if the document is not multi-page.
 633+ */
 634+ function getPageDimensions( $image, $page ) {
 635+ // makeImageLink2 (Linker.php) sets $page to false if no page parameter
 636+ // is set in wiki code
 637+ if ( !$page ) {
 638+ $page = 1;
 639+ }
 640+ if ( $page > $this->pageCount( $image ) ) {
 641+ $page = $this->pageCount( $image );
 642+ }
 643+ $data = $this->getMetaArray( $image );
 644+ return PagedTiffImage::getPageSize( $data, $page );
 645+ }
 646+}
Property changes on: branches/wmf/1.16wmf4/extensions/PagedTiffHandler/PagedTiffHandler_body.php
___________________________________________________________________
Added: svn:eol-style
1647 + native
Index: branches/wmf/1.16wmf4/extensions/PagedTiffHandler/PagedTiffHandler.i18n.php
@@ -0,0 +1,592 @@
 2+<?php
 3+/**
 4+ * Internationalisation file for extension PagedTiffHandler.
 5+ *
 6+ * @file
 7+ * @ingroup Extensions
 8+ */
 9+
 10+$messages = array();
 11+
 12+/** English (English)
 13+ * @author Hallo Welt! - Medienwerkstatt GmbH
 14+ */
 15+$messages['en'] = array(
 16+ 'tiff-desc' => 'Handler for viewing TIFF files in image mode',
 17+ 'tiff_no_metadata' => 'Cannot get metadata from TIFF',
 18+ 'tiff_page_error' => 'Page number not in range',
 19+ 'tiff_too_many_embed_files' => 'The image contains too many embedded files.',
 20+ 'tiff_sourcefile_too_large' => 'The resolution of the source file is too large.
 21+No thumbnail will be generated.',
 22+ 'tiff_targetfile_too_large' => 'The resolution of the target file is too large.
 23+No thumbnail will be generated.',
 24+ 'tiff_file_too_large' => 'The uploaded file is too large and was rejected.',
 25+ 'tiff_out_of_service' => 'The uploaded file could not be processed.
 26+ImageMagick is not available.',
 27+ 'tiff_too_much_meta' => 'Metadata uses too much space.',
 28+ 'tiff_error_cached' => 'This file can only be rerendered after the caching interval.',
 29+ 'tiff_size_error' => 'The reported file size does not match the actual file size.',
 30+ 'tiff_script_detected' => 'The uploaded file contains scripts.',
 31+ 'tiff_bad_file' => 'The uploaded file contains errors.',
 32+ 'tiff-file-info-size' => '(page $5, $1 × $2 pixel, file size: $3, MIME type: $4)',
 33+ );
 34+
 35+/** Message documentation (Message documentation)
 36+ * @author Hallo Welt! - Medienwerkstatt GmbH
 37+ */
 38+$messages['qqq'] = array(
 39+ 'tiff-desc' => 'Short description of the extension, shown in [[Special:Version]]. Do not translate or change links.',
 40+ 'tiff_no_metadata' => 'Error message shown when no metadata extraction is not possible',
 41+ 'tiff_page_error' => 'Error message shown when page number is out of range',
 42+ 'tiff_too_many_embed_files' => 'Error message shown when the uploaded image contains too many embedded files.',
 43+ 'tiff_sourcefile_too_large' => 'Error message shown when the resolution of the source file is too large.',
 44+ 'tiff_targetfile_too_large' => 'Error message shown when the resolution of the target file is too large.',
 45+ 'tiff_file_too_large' => 'Error message shown when the uploaded file is too large.',
 46+ 'tiff_out_of_service' => 'Error message shown when the uploaded file could not be processed by external renderer (ImageMagick).',
 47+ 'tiff_too_much_meta' => 'Error message shown when the metadata uses too much space.',
 48+ 'tiff_error_cached' => 'Error message shown when a error occurres and it is cached.',
 49+ 'tiff_size_error' => 'Error message shown when the reported file size does not match the actual file size.',
 50+ 'tiff_script_detected' => 'Error message shown when the uploaded file contains scripts.',
 51+ 'tiff_bad_file' => 'Error message shown when the uploaded file contains errors.',
 52+ 'tiff-file-info-size' => 'Information about the image dimensions etc. on image page. Extended by page information',
 53+);
 54+
 55+/** Message documentation (Message documentation) */
 56+$messages['qqq'] = array(
 57+ 'tiff-desc' => 'Short description of the extension, shown in [[Special:Version]]. Do not translate or change links.',
 58+ 'tiff_no_metadata' => 'Error message shown when no metadata extraction is not possible',
 59+ 'tiff_page_error' => 'Error message shown when page number is out of range',
 60+ 'tiff_too_many_embed_files' => 'Error message shown when the uploaded image contains too many embedded files.',
 61+ 'tiff_sourcefile_too_large' => 'Error message shown when the resolution of the source file is too large.',
 62+ 'tiff_targetfile_too_large' => 'Error message shown when the resolution of the target file is too large.',
 63+ 'tiff_file_too_large' => 'Error message shown when the uploaded file is too large.',
 64+ 'tiff_out_of_service' => 'Error message shown when the uploaded file could not be processed by external renderer (ImageMagick).',
 65+ 'tiff_too_much_meta' => 'Error message shown when the metadata uses too much space.',
 66+ 'tiff_error_cached' => 'Error message shown when a error occurres and it is cached.',
 67+ 'tiff_size_error' => 'Error message shown when the reported file size does not match the actual file size.',
 68+ 'tiff_script_detected' => 'Error message shown when the uploaded file contains scripts.',
 69+ 'tiff_bad_file' => 'Error message shown when the uploaded file contains errors.',
 70+ 'tiff-file-info-size' => 'Information about the image dimensions etc. on image page. Extended by page information',
 71+);
 72+
 73+/** Afrikaans (Afrikaans)
 74+ * @author Naudefj
 75+ */
 76+$messages['af'] = array(
 77+ 'tiff-desc' => 'Hanteerder vir die besigtiging van TIFF-lêers in die beeld-modus',
 78+ 'tiff_no_metadata' => 'Kan nie metadata vanuit TIFF kry nie',
 79+ 'tiff_page_error' => 'Bladsynommer kom nie in dokument voor nie',
 80+ 'tiff_too_many_embed_files' => 'Die beeld bevat te veel ingebedde lêers.',
 81+ 'tiff_sourcefile_too_large' => 'Die resolusie van die bronlêer is te groot. Geen duimnael sal gegenereer word nie.',
 82+ 'tiff_file_too_large' => 'Die opgelaaide lêer is te groot en is verwerp.',
 83+ 'tiff_out_of_service' => 'Die opgelaaide lêer kon nie verwerk word nie. ImageMagick is nie beskikbaar is nie.',
 84+ 'tiff_too_much_meta' => 'Metadata gebruik te veel spasie.',
 85+ 'tiff_error_cached' => 'Hierdie lêer kan slegs na die die kas-interval gerendeer word.',
 86+ 'tiff_size_error' => 'Die gerapporteerde lêergrootte stem nie met die lêer se werklike grootte ooreen nie.',
 87+ 'tiff_script_detected' => 'Die opgelaaide lêer bevat skrips.',
 88+ 'tiff_bad_file' => 'Die opgelaaide lêer bevat foute.',
 89+ 'tiff-file-info-size' => '(bladsy $5, $1 × $2 spikkels, lêergrootte: $3, MIME-tipe: $4)',
 90+);
 91+
 92+/** Belarusian (Taraškievica orthography) (Беларуская (тарашкевіца))
 93+ * @author EugeneZelenko
 94+ * @author Jim-by
 95+ * @author Wizardist
 96+ */
 97+$messages['be-tarask'] = array(
 98+ 'tiff-desc' => 'Апрацоўшчык для прагляду TIFF-файлаў у выглядзе выяваў',
 99+ 'tiff_no_metadata' => 'Немагчыма атрымаць мэта-зьвесткі з TIFF-файла',
 100+ 'tiff_page_error' => 'Нумар старонкі паза дыяпазонам',
 101+ 'tiff_too_many_embed_files' => 'Выява ўтрымлівае зашмат убудаваных файлаў.',
 102+ 'tiff_sourcefile_too_large' => 'Разрозьненьне крынічнага файла занадта вялікае. Мініятуры стварацца ня будуць.',
 103+ 'tiff_targetfile_too_large' => 'Разрозьненьне файла занадта вялікае. Выява для папярэдняга прагляду ня будзе створаная.',
 104+ 'tiff_file_too_large' => 'Памер загружанага файла — занадта вялікі, файл быў адхілены.',
 105+ 'tiff_out_of_service' => 'Загружаны файл ня можа быць апрацаваны. ImageMagick недаступная.',
 106+ 'tiff_too_much_meta' => 'Мэта-зьвесткі займаюць зашмат месца.',
 107+ 'tiff_error_cached' => 'Гэты файл можа быць паўторна згенэраваны толькі пасьля інтэрвалу для кэшаваньня.',
 108+ 'tiff_size_error' => 'Пададзены памер файла не супадае з фактычным памерам файла.',
 109+ 'tiff_script_detected' => 'Загружаны файл утрымлівае скрыпты.',
 110+ 'tiff_bad_file' => 'Загружаны файл утрымлівае памылкі.',
 111+ 'tiff-file-info-size' => '(старонка $5, $1 × $2 піксэляў, памер файла: $3, тып MIME: $4)',
 112+);
 113+
 114+/** Breton (Brezhoneg)
 115+ * @author Fohanno
 116+ * @author Fulup
 117+ * @author Y-M D
 118+ */
 119+$messages['br'] = array(
 120+ 'tiff-desc' => 'Maveg evit gwelet ar restroù TIFF e mod skeudenn',
 121+ 'tiff_no_metadata' => "Ne c'haller ket tapout metaroadennoù eus TIFF",
 122+ 'tiff_page_error' => "N'emañ ket niverenn ar bajenn er skeuliad",
 123+ 'tiff_too_many_embed_files' => 'Re a restroù enklozet zo er skeudenn.',
 124+ 'tiff_sourcefile_too_large' => 'Re vras eo spister ar rest mammenn. Ne vo ket krouet a skeudennig.',
 125+ 'tiff_targetfile_too_large' => 'Re vras eo spister ar rest sibl. Ne vo ket krouet a skeudennig.',
 126+ 'tiff_file_too_large' => 'Re vras eo ar restr karget ha distaolet eo bet.',
 127+ 'tiff_out_of_service' => "N'eus ket bet gellet tretiñ ar restr pellgarget. Dizimplijadus eo ImageMagick.",
 128+ 'tiff_too_much_meta' => "Ar metaroadennoù a implij re a lec'h.",
 129+ 'tiff_error_cached' => "N'hall ar restr-mañ bezañ adderaouekaet nemet goude termen ar grubuilh.",
 130+ 'tiff_size_error' => 'Ne glot ket ment ar restr meneget gant ment gwir ar restr.',
 131+ 'tiff_script_detected' => 'Skriptoù zo er restr karget.',
 132+ 'tiff_bad_file' => 'Fazioù zo er restr karget.',
 133+ 'tiff-file-info-size' => '(pajenn $5, $1 × $2 piksel, ment ar restr : $3, seurt MIME : $4)',
 134+);
 135+
 136+/** German (Deutsch)
 137+ * @author Als-Holder
 138+ * @author Hallo Welt! - Medienwerkstatt GmbH
 139+ */
 140+$messages['de'] = array(
 141+ 'tiff-desc' => 'Schnittstelle für die Ansicht von TIFF-Dateien im Bilder-Modus',
 142+ 'tiff_no_metadata' => 'Keine Metadaten im TIFF vorhanden.',
 143+ 'tiff_page_error' => 'Seitenzahl außerhalb des Dokumentes.',
 144+ 'tiff_too_many_embed_files' => 'Die Datei enthält zu viele eingebettete Dateien.',
 145+ 'tiff_sourcefile_too_large' => 'Die Quelldatei hat eine zu hohe Auflösung. Es wird kein Thumbnail generiert.',
 146+ 'tiff_targetfile_too_large' => 'Die Zieldatei hat eine zu hohe Auflösung. Es wird kein Thumbnail generiert.',
 147+ 'tiff_file_too_large' => 'Die hochgeladene Datei ist zu groß und wurde abgewiesen.',
 148+ 'tiff_out_of_service' => 'Die hochgeladene Datei konnte nicht verarbeitet werden. ImageMagick ist nicht verfügbar.',
 149+ 'tiff_too_much_meta' => 'Die Metadaten benötigen zu viel Speicherplatz.',
 150+ 'tiff_error_cached' => 'Diese Datei kann erst nach Ablauf der Caching-Periode neu gerendert werden.',
 151+ 'tiff_size_error' => 'Die errechnete Größe der Datei stimmt nicht mit der tatsächlichen überein.',
 152+ 'tiff_script_detected' => 'Die hochgeladene Datei enthält Skripte.',
 153+ 'tiff_bad_file' => 'Die hochgeladene Datei ist fehlerhaft.',
 154+ 'tiff-file-info-size' => '(Seite $5, $1 × $2 Pixel, Dateigröße: $3, MIME-Typ: $4)',
 155+);
 156+
 157+/** Lower Sorbian (Dolnoserbski)
 158+ * @author Michawiki
 159+ */
 160+$messages['dsb'] = array(
 161+ 'tiff-desc' => 'Rěd za woglědowanje TIFF-datajow we wobrazowem modusu',
 162+ 'tiff_no_metadata' => 'Njedaju se žedne metadaty z TIFF ekstrahěrowaś',
 163+ 'tiff_page_error' => 'Bokowa licba njejo we wobcerku',
 164+ 'tiff_too_many_embed_files' => 'Wobraz wopśimujo pśewjele zasajźonych datajow.',
 165+ 'tiff_sourcefile_too_large' => 'Rozeznaśe žrědłoweje dataje jo pśewjelike. Miniaturny wobraz se njenapórajo.',
 166+ 'tiff_targetfile_too_large' => 'Rozeznaśe celoweje dataje jo pśewjelike. Miniaturny wobraz so njenapórajo.',
 167+ 'tiff_file_too_large' => 'Nagrata dataja jo pśewjelika a jo se wótpokazała.',
 168+ 'tiff_out_of_service' => 'Nagrata dataja njedajo se pśeźěłaś. ImageMagick njestoj k dispoziciji.',
 169+ 'tiff_too_much_meta' => 'Metadaty wužywa pśewjele ruma.',
 170+ 'tiff_error_cached' => 'Toś ta dataja dajo se akle pó puferowańskem interwalu znowego wuceriś.',
 171+ 'tiff_size_error' => 'K wěsći dana datajowa wjelikosć njewótpowědujo wopšawdnej datajowej wjelikosći.',
 172+ 'tiff_script_detected' => 'Nagrata dataja wopśimujo skripty.',
 173+ 'tiff_bad_file' => 'Nagrata dataja wopśimujo zmólki.',
 174+ 'tiff-file-info-size' => '(bok $5, $1 × $2 pikselow, datajowa wjelikosć: $3, typ MIME: $4)',
 175+);
 176+
 177+/** Greek (Ελληνικά)
 178+ * @author Dada
 179+ */
 180+$messages['el'] = array(
 181+ 'tiff_no_metadata' => 'Αδύνατη η ανάκτηση μεταδεδομένων από το TIFF',
 182+ 'tiff_page_error' => 'Αριθμός σελίδας εκτός ορίου',
 183+ 'tiff_file_too_large' => 'Το μεταφορτωμένο αρχείο είναι πολύ μεγάλο και απορρίφθηκε.',
 184+);
 185+
 186+/** Spanish (Español)
 187+ * @author Pertile
 188+ * @author Translationista
 189+ */
 190+$messages['es'] = array(
 191+ 'tiff-desc' => 'Controlador para ver archivos TIFF en modo de imagen',
 192+ 'tiff_no_metadata' => 'No se pudo obtener los metadatos de TIFF',
 193+ 'tiff_page_error' => 'Número de página fuera de rango',
 194+ 'tiff_too_many_embed_files' => 'La imagen contiene demasiados archivos incrustados.',
 195+ 'tiff_sourcefile_too_large' => 'La resolución del archivo fuente es muy grande. No se generará miniaturas.',
 196+ 'tiff_targetfile_too_large' => 'La resolución del archivo destino es muy grande. No se generará ninguna miniatura.',
 197+ 'tiff_file_too_large' => 'El archivo subido es muy grande y ha sido rechazado.',
 198+ 'tiff_out_of_service' => 'El archivo subido no pudo ser procesado. ImageMagick no está disponible.',
 199+ 'tiff_too_much_meta' => 'Los metadatos utilizan demasiado espacio.',
 200+ 'tiff_error_cached' => 'Este archivo sólo puede ser reprocesado tras el intervalo de cacheo.',
 201+ 'tiff_size_error' => 'El tamaño del archivo reportado no coincide con el tamaño real del archivo.',
 202+ 'tiff_script_detected' => 'El archivo cargado contiene scripts.',
 203+ 'tiff_bad_file' => 'El archivo cargado contiene errores.',
 204+ 'tiff-file-info-size' => '(Página $5, $1 × $2 píxeles, tamaño de archivo: $3, tipo de MIME: $4)',
 205+);
 206+
 207+/** Finnish (Suomi)
 208+ * @author Centerlink
 209+ * @author Crt
 210+ */
 211+$messages['fi'] = array(
 212+ 'tiff_no_metadata' => 'Metatietojen hakeminen TIFF-tiedostosta epäonnistui',
 213+ 'tiff_too_many_embed_files' => 'Kuvassa on liian monta upotettua tiedostoa.',
 214+ 'tiff_file_too_large' => 'Palvelimelle kopioitu tiedosto on liian suuri ja torjuttiin.',
 215+ 'tiff_out_of_service' => 'Palvelimelle kopioitua tiedostoa ei voitu käsitellä. ImageMagick ei ollut käytettävissä.',
 216+ 'tiff_too_much_meta' => 'Metatiedot vievät liikaa tilaa.',
 217+ 'tiff_script_detected' => 'Palvelimelle kopioitu tiedosto sisältää skriptejä.',
 218+ 'tiff_bad_file' => 'Palvelimelle kopioitu tiedosto sisältää virheitä.',
 219+);
 220+
 221+/** French (Français)
 222+ * @author IAlex
 223+ * @author Jagwar
 224+ * @author Jean-Frédéric
 225+ * @author Urhixidur
 226+ */
 227+$messages['fr'] = array(
 228+ 'tiff-desc' => 'Gestionnaire pour visionner les fichiers TIFF en mode image',
 229+ 'tiff_no_metadata' => "Impossible d'obtenir les métadonnées depuis TIFF",
 230+ 'tiff_page_error' => 'Le numéro de page n’est pas dans la plage.',
 231+ 'tiff_too_many_embed_files' => "L'image contient trop de fichiers embarqués.",
 232+ 'tiff_sourcefile_too_large' => 'La résolution du fichier source est trop élevée. Aucune miniature ne sera générée.',
 233+ 'tiff_targetfile_too_large' => 'La résolution de l’image cible est trop importante. Aucun aperçu ne sera généré.',
 234+ 'tiff_file_too_large' => 'Le fichier téléversé est trop grand et a été rejeté.',
 235+ 'tiff_out_of_service' => "Le fichier téléversé n'a pas pu être traité. ImageMagick n'est pas disponible.",
 236+ 'tiff_too_much_meta' => "Les métadonnées utilisent trop d'espace.",
 237+ 'tiff_error_cached' => "Ce fichier ne peut être régénéré qu'après l'expiration du cache.",
 238+ 'tiff_size_error' => 'La taille de fichier indiquée ne correspond pas à la taille réelle du fichier.',
 239+ 'tiff_script_detected' => 'Le fichier téléchargé contient des scripts.',
 240+ 'tiff_bad_file' => 'Le fichier téléchargé contient des erreurs.',
 241+ 'tiff-file-info-size' => '(page $5, $1 × $2 pixels, taille du fichier : $3, Type MIME : $4)',
 242+);
 243+
 244+/** Galician (Galego)
 245+ * @author Toliño
 246+ */
 247+$messages['gl'] = array(
 248+ 'tiff-desc' => 'Manipulador para ver ficheiros TIFF no modo de imaxe',
 249+ 'tiff_no_metadata' => 'Non se puideron obter os metadatos do TIFF',
 250+ 'tiff_page_error' => 'O número da páxina non está no rango',
 251+ 'tiff_too_many_embed_files' => 'A imaxe contén moitos ficheiros incorporados.',
 252+ 'tiff_sourcefile_too_large' => 'A resolución do ficheiro de orixe é moi grande. Non se xerará ningunha miniatura.',
 253+ 'tiff_targetfile_too_large' => 'A resolución do ficheiro de destino é moi grande. Non se xerará ningunha miniatura.',
 254+ 'tiff_file_too_large' => 'O ficheiro cargado é moi grande e foi rexeitado.',
 255+ 'tiff_out_of_service' => 'O ficheiro cargado non se puido procesar. ImageMagick non está dispoñible.',
 256+ 'tiff_too_much_meta' => 'Os metadatos empregan moito espazo.',
 257+ 'tiff_error_cached' => 'O ficheiro só se pode renderizar despois do intervalo da caché.',
 258+ 'tiff_size_error' => 'O tamaño do ficheiro do que se informou non se corresponde co tamaño real do ficheiro.',
 259+ 'tiff_script_detected' => 'O ficheiro cargado contén escrituras.',
 260+ 'tiff_bad_file' => 'O ficheiro cargado contén erros.',
 261+ 'tiff-file-info-size' => '(páxina $5, $1 × $2 píxeles, tamaño do ficheiro: $3, tipo MIME: $4)',
 262+);
 263+
 264+/** Swiss German (Alemannisch)
 265+ * @author Als-Holder
 266+ */
 267+$messages['gsw'] = array(
 268+ 'tiff-desc' => 'Funktion zum Aaluege vu TIFF-Dateie im Bildmodus',
 269+ 'tiff_no_metadata' => 'Cha d Metadate vum TIFF nit läse',
 270+ 'tiff_page_error' => 'Sytenummere lyt nit im Beryych',
 271+ 'tiff_too_many_embed_files' => 'Im Bild het s zvil yybundeni Dateie',
 272+ 'tiff_sourcefile_too_large' => 'D Uflesig vu dr Quälldatei isch z hoch. S wird kei Vorschaubild generiert.',
 273+ 'tiff_targetfile_too_large' => 'D Uflesig vu dr Ziildatei isch z hoch. S wird kei Miniaturbild generiert.',
 274+ 'tiff_file_too_large' => 'D Datei, wu uffeglade woren isch, isch z groß un isch abgwise wore.',
 275+ 'tiff_out_of_service' => 'D Datei, wu uffeglade woren isch, het nit chenne verarbeitet wäre. ImageMagick isch nit verfiegbar.',
 276+ 'tiff_too_much_meta' => 'D Metadate bruch zvil Spycherplatz.',
 277+ 'tiff_error_cached' => 'Die Datei cha erscht no Ablauf vu dr Caching-Periode nej grenderet wäre.',
 278+ 'tiff_size_error' => 'Di brichtet Greßi vu dr Datei stimmt nit zue dr tatsächlige.',
 279+ 'tiff_script_detected' => 'In dr Datei, wu uffeglade woren isch, het s Skript din.',
 280+ 'tiff_bad_file' => 'D Datei, wu uffeglade woren isch, isch fählerhaft.',
 281+ 'tiff-file-info-size' => '(Syte $5, $1 × $2 Pixel, Dateigreßi: $3, MIME-Typ: $4)',
 282+);
 283+
 284+/** Upper Sorbian (Hornjoserbsce)
 285+ * @author Michawiki
 286+ */
 287+$messages['hsb'] = array(
 288+ 'tiff-desc' => 'Rozšěrjenje za wobhladowanje TIFF-datajow we wobrazowym modusu',
 289+ 'tiff_no_metadata' => 'Z TIFF njedadźa so metadaty wućahać.',
 290+ 'tiff_page_error' => 'Čisło strony we wobłuku njeje',
 291+ 'tiff_too_many_embed_files' => 'Wobraz wobsahuje přewjele zapřijatych datajow.',
 292+ 'tiff_sourcefile_too_large' => 'Rozeznaće žórłoweje dataje je přewulke. Přehladowy wobraz njebudźe so płodźić.',
 293+ 'tiff_targetfile_too_large' => 'Rozeznaće ciloweje dataje je přewulke. Přehledowy wobrazk njeje so wutworił.',
 294+ 'tiff_file_too_large' => 'Nahrata dataja je přewulka a bu wotpokazana.',
 295+ 'tiff_out_of_service' => 'Nahrata dataja njeda so předźěłać. ImageMagick njesteji k dispoziciji.',
 296+ 'tiff_too_much_meta' => 'Metadaty wužiwaja přewjele ruma.',
 297+ 'tiff_error_cached' => 'Tuta dataja da so hakle po pufrowanskim interwalu znowa rysować.',
 298+ 'tiff_size_error' => 'Zdźělena wulkosć dataje njewotpowěduje woprawdźitej wulkosći dataje.',
 299+ 'tiff_script_detected' => 'Nahrata dataja wobsahuje skripty.',
 300+ 'tiff_bad_file' => 'Nahrata dataja wobsahuje zmylki.',
 301+ 'tiff-file-info-size' => '(strona $5, $1 × $2 pikselow, wulkosć dataje: $3, MIME-typ: $4)',
 302+);
 303+
 304+/** Hungarian (Magyar)
 305+ * @author Glanthor Reviol
 306+ */
 307+$messages['hu'] = array(
 308+ 'tiff_no_metadata' => 'Nem sikerült lekérni a TIFF metaadatait',
 309+ 'tiff_page_error' => 'Az oldalszám a tartományon kívül esik',
 310+ 'tiff_too_many_embed_files' => 'A kép túl sok beágyazott fájlt tartalmaz.',
 311+ 'tiff_targetfile_too_large' => 'A célfájl felbontása túl nagy. Nem fog bélyegkép készülni hozzá.',
 312+ 'tiff_file_too_large' => 'A feltöltött fájl túl nagy, vissza lett utasítva.',
 313+ 'tiff_too_much_meta' => 'A metaadatok túl sok helyet foglalnak.',
 314+ 'tiff_script_detected' => 'A feltöltött fájl parancsfájlokat tartalmaz.',
 315+ 'tiff_bad_file' => 'A feltöltött fájl hibákat tartalmaz.',
 316+ 'tiff-file-info-size' => '($5 oldal, $1 × $2 képpont, fájlméret: $3, MIME-típus: $4)',
 317+);
 318+
 319+/** Interlingua (Interlingua)
 320+ * @author McDutchie
 321+ */
 322+$messages['ia'] = array(
 323+ 'tiff-desc' => 'Gestor pro visualisar files TIFF in modo de imagine',
 324+ 'tiff_no_metadata' => 'Non pote obtener metadatos ab TIFF',
 325+ 'tiff_page_error' => 'Numero de pagina foras del intervallo',
 326+ 'tiff_too_many_embed_files' => 'Le imagine contine troppo de files incastrate.',
 327+ 'tiff_sourcefile_too_large' => 'Le resolution del file de fonte es troppo alte. Nulle miniatura essera generate.',
 328+ 'tiff_targetfile_too_large' => 'Le resolution del file de destination es troppo alte. Nulle miniatura essera generate.',
 329+ 'tiff_file_too_large' => 'Le file incargate es troppo grande e ha essite rejectate.',
 330+ 'tiff_out_of_service' => 'Le file incargate non poteva esser processate. ImageMagick non es disponibile.',
 331+ 'tiff_too_much_meta' => 'Le metadatos usa troppo de spatio.',
 332+ 'tiff_error_cached' => 'Iste file pote solmente esser re-rendite post le expiration de su copia in cache.',
 333+ 'tiff_size_error' => 'Le grandor reportate del file non corresponde al grandor real del file.',
 334+ 'tiff_script_detected' => 'Le file incargate contine scripts.',
 335+ 'tiff_bad_file' => 'Le file incargate contine errores.',
 336+ 'tiff-file-info-size' => '(pagina $5, $1 × $2 pixel, grandor del file: $3, typo MIME: $4)',
 337+);
 338+
 339+/** Japanese (日本語)
 340+ * @author Aotake
 341+ * @author Naohiro19
 342+ * @author 青子守歌
 343+ */
 344+$messages['ja'] = array(
 345+ 'tiff-desc' => 'TIFFファイルの画像モードを表示するためのハンドラ',
 346+ 'tiff_no_metadata' => 'TIFFからのメタデータが取得できません',
 347+ 'tiff_page_error' => '範囲にないページ番号',
 348+ 'tiff_too_many_embed_files' => 'この画像には埋め込みファイルが多すぎます。',
 349+ 'tiff_sourcefile_too_large' => 'ソースファイルの解像度が大きすぎます。サムネイルは生成されません。',
 350+ 'tiff_targetfile_too_large' => 'ターゲットファイルの解像度が大きすぎます。サムネイルは生成されません。',
 351+ 'tiff_file_too_large' => 'アップロードされたファイルは容量が大きすぎるために拒否されました。',
 352+ 'tiff_out_of_service' => 'アップロードされたファイルを処理できませんでした。ImageMagick が利用できません。',
 353+ 'tiff_too_much_meta' => 'メタデータが使用する容量が大きすぎます。',
 354+ 'tiff_error_cached' => 'このファイルはキャッシュの有効期限が切れてからでなければレンダリングできません。',
 355+ 'tiff_size_error' => '報告されたファイルサイズが実際のサイズと一致しません。',
 356+ 'tiff_script_detected' => 'アップロードされたファイルに、スクリプトが含まれます。',
 357+ 'tiff_bad_file' => 'アップロードされたファイルに、エラーが含まれます。',
 358+ 'tiff-file-info-size' => '(ページ $5、$1 × $2ピクセル、ファイルサイズ:$3、MIME:$4)',
 359+);
 360+
 361+/** Luxembourgish (Lëtzebuergesch)
 362+ * @author Robby
 363+ */
 364+$messages['lb'] = array(
 365+ 'tiff_page_error' => "D'Nummer vun der Säit ass net am Beräich",
 366+ 'tiff_file_too_large' => 'Den eropgeluedene Fichier ass ze grouss a gouf net akzeptéiert.',
 367+ 'tiff_out_of_service' => 'Den eropgeluedene Fichier konnt net verschafft ginn. ImageMagick ass net disponibel.',
 368+ 'tiff_too_much_meta' => "D'Metadate benotzen zevill Späicherplaz.",
 369+ 'tiff_size_error' => "Déi berechent Gréisst vum Fichier ass net d'selwëscht wéi déi wierklech Gréisst vum Fichier.",
 370+ 'tiff_script_detected' => 'Am eropgeluedene Fichier si Skripten dran.',
 371+ 'tiff_bad_file' => 'Am eropgeluedene Fichier si Feeler.',
 372+ 'tiff-file-info-size' => '(Säit $5, $1 × $2 Pixel, Gréisst vum Fichier: $3, MIME-Typ: $4)',
 373+);
 374+
 375+/** Macedonian (Македонски)
 376+ * @author Bjankuloski06
 377+ */
 378+$messages['mk'] = array(
 379+ 'tiff-desc' => 'Ракувач за прегледување на TIFF податотеки во сликовен режим',
 380+ 'tiff_no_metadata' => 'Не можам да добијам метаподатоци од TIFF',
 381+ 'tiff_page_error' => 'Бројот на страница е надвор од опсег',
 382+ 'tiff_too_many_embed_files' => 'Сликата содржи премногу вградени податотеки.',
 383+ 'tiff_sourcefile_too_large' => 'Резолуцијата на изворната податотека е преголема. Минијатурата нема да биде создадена.',
 384+ 'tiff_targetfile_too_large' => 'Резолуцијата на целната податотека е преголема. Нема да биде направена минијатура.',
 385+ 'tiff_file_too_large' => 'Подигнатата податотека е преголема и затоа беше одбиена.',
 386+ 'tiff_out_of_service' => 'Подигнатата податотека не може да се обработи. ImageMagick не е достапен.',
 387+ 'tiff_too_much_meta' => 'Метаподатоците заземаат премногу простор.',
 388+ 'tiff_error_cached' => 'Оваа податотека може да се оформи само по кеширање на интервалот.',
 389+ 'tiff_size_error' => 'Пријавената големина на податотеката не се совпаѓа со фактичката.',
 390+ 'tiff_script_detected' => 'Подигнатата податотека содржи скрипти.',
 391+ 'tiff_bad_file' => 'Подигнатата податотека содржи грешки.',
 392+ 'tiff-file-info-size' => '(страница $5, $1 × $2 пиксели, големина на податотеката: $3, MIME-тип: $4)',
 393+);
 394+
 395+/** Dutch (Nederlands)
 396+ * @author Siebrand
 397+ */
 398+$messages['nl'] = array(
 399+ 'tiff-desc' => 'Uitbreiding voor het bekijken van TIFF-bestanden in beeldmodus',
 400+ 'tiff_no_metadata' => 'De metadata van het TIFF-bestand kan niet uitgelezen worden',
 401+ 'tiff_page_error' => 'Het paginanummer ligt niet binnen het bereik',
 402+ 'tiff_too_many_embed_files' => 'De afbeelding bevat te veel ingesloten bestanden.',
 403+ 'tiff_sourcefile_too_large' => 'De resolutie van het bronbestand is te groot.
 404+Er kan geen miniatuur worden aangemaakt.',
 405+ 'tiff_targetfile_too_large' => 'De resolutie van het doelbestand is te groot.
 406+Er wordt geen miniatuur aangemaakt.',
 407+ 'tiff_file_too_large' => 'Het geüploade bestand is te groot en kan niet verwerkt worden.',
 408+ 'tiff_out_of_service' => 'Het geüploade bestand kan niet worden verwerkt.
 409+ImageMagick is niet beschikbaar.',
 410+ 'tiff_too_much_meta' => 'De metadata gebruikt te veel ruimte.',
 411+ 'tiff_error_cached' => 'Dit bestand kan alleen worden verwerkt na de cachinginterval.',
 412+ 'tiff_size_error' => 'De gerapporteerde bestandsgrootte komt niet overeen met de werkelijke bestandsgrootte.',
 413+ 'tiff_script_detected' => 'Het geüploade bestand bevat scripts.',
 414+ 'tiff_bad_file' => 'Het geüploade bestand bevat fouten.',
 415+ 'tiff-file-info-size' => '(pagina $5, $1 × $2 pixels, bestandsgrootte: $3, MIME-type: $4)',
 416+);
 417+
 418+/** Norwegian (bokmål)‬ (‪Norsk (bokmål)‬)
 419+ * @author Nghtwlkr
 420+ */
 421+$messages['no'] = array(
 422+ 'tiff-desc' => 'Håndterer for visning av TIFF-filer i bildemodus',
 423+ 'tiff_no_metadata' => 'Kan ikke hente metadata fra TIFF',
 424+ 'tiff_page_error' => 'Sidenummer er utenfor sideintervallet',
 425+ 'tiff_too_many_embed_files' => 'Bildet inneholder for mange innebygde filer.',
 426+ 'tiff_sourcefile_too_large' => 'Oppløsningen til kildefilen er for stor. Miniatyrbilde vil ikke bli opprettet.',
 427+ 'tiff_targetfile_too_large' => 'Oppløsningen på målfilen er for stor. Inget miniatyrbilde vil bli generert.',
 428+ 'tiff_file_too_large' => 'Den opplastede filen var for stor og ble avvist.',
 429+ 'tiff_out_of_service' => 'Den opplastede filen kunne ikke behandles. ImageMagick er ikke tilgjengelig.',
 430+ 'tiff_too_much_meta' => 'Metadata bruker for mye plass.',
 431+ 'tiff_error_cached' => 'Filen kan bare gjengis på nytt etter hurtiglagerintervallet.',
 432+ 'tiff_size_error' => 'Den rapporterte filstørrelsen samsvarer ikke med den faktiske filstørrelsen.',
 433+ 'tiff_script_detected' => 'Den opplastede filen inneholder skript.',
 434+ 'tiff_bad_file' => 'Den opplastede filen inneholder feil.',
 435+ 'tiff-file-info-size' => '(side $5, $1 x $2 piksler, filstørrelse: $3, MIME-type: $4)',
 436+);
 437+
 438+/** Piedmontese (Piemontèis)
 439+ * @author Borichèt
 440+ * @author Dragonòt
 441+ */
 442+$messages['pms'] = array(
 443+ 'tiff-desc' => 'Gestor për vëdde archivi TIFF an manera figure',
 444+ 'tiff_no_metadata' => 'As riess nen a pijé ij metadat dal TIFF',
 445+ 'tiff_page_error' => "Nùmer ëd pàgina pa ant l'antërval",
 446+ 'tiff_too_many_embed_files' => 'La figura a conten andrinta tròpi archivi.',
 447+ 'tiff_sourcefile_too_large' => "L'arzolussion dl'archivi sorgiss a l'é tròp gròssa. Gnun-e figurin-e a saran generà.",
 448+ 'tiff_targetfile_too_large' => "L'arzolussion ëd l'archivi ëd destinassion a l'é tròp gròssa. Gnun-e figurin-e a saran generà.",
 449+ 'tiff_file_too_large' => "L'archivi carià a l'é tròp gròss e a l'é stàit arfudà.",
 450+ 'tiff_out_of_service' => "L'archivi carià a l'ha pa podù esse processà. ImageMagick a l'é nen disponìbil.",
 451+ 'tiff_too_much_meta' => 'Ij Metadat a deuvro tròp dë spassi.',
 452+ 'tiff_error_cached' => "Cost archivi-sì a peul mach esse rendù apress l'antërval ëd memorisassion local.",
 453+ 'tiff_size_error' => "La dimension diciairà dl'archivi a l'é pa l'istessa ëd soa dimension vera.",
 454+ 'tiff_script_detected' => "L'archivi carià a conten ëd senari.",
 455+ 'tiff_bad_file' => "L'archivi carià a conten d'eror.",
 456+ 'tiff-file-info-size' => "(pàgina $5, $1 x $2 pontin, dimension dl'archivi: $3, sòrt MIME: $4)",
 457+);
 458+
 459+/** Portuguese (Português)
 460+ * @author Hamilton Abreu
 461+ */
 462+$messages['pt'] = array(
 463+ 'tiff-desc' => 'Permite o visionamento de ficheiros TIFF em modo de imagem',
 464+ 'tiff_no_metadata' => 'Não foi possível extrair metadados do TIFF',
 465+ 'tiff_page_error' => 'Número de página fora do intervalo',
 466+ 'tiff_too_many_embed_files' => 'A imagem tem demasiados ficheiros embutidos.',
 467+ 'tiff_sourcefile_too_large' => "A resolução do ficheiro de origem é demasiado grande. Não será gerada uma miniatura ''(thumbnail)''.",
 468+ 'tiff_targetfile_too_large' => "A resolução do ficheiro de destino é demasiado grande. Não será gerada uma miniatura ''(thumbnail)''.",
 469+ 'tiff_file_too_large' => 'O ficheiro transferido é demasiado grande e foi rejeitado.',
 470+ 'tiff_out_of_service' => 'Não foi possível processar o ficheiro transferido. O ImageMagick não está disponível.',
 471+ 'tiff_too_much_meta' => 'Os metadados usam demasiado espaço.',
 472+ 'tiff_error_cached' => 'Só será possível voltar a renderizar o ficheiro após o intervalo de caching, porque o erro foi colocado na cache.',
 473+ 'tiff_size_error' => 'O tamanho reportado do ficheiro não corresponde ao tamanho real.',
 474+ 'tiff_script_detected' => "O ficheiro transferido tem ''scripts''.",
 475+ 'tiff_bad_file' => 'O ficheiro transferido tem erros.',
 476+ 'tiff-file-info-size' => '(página $5, $1 × $2 pixels, tamanho do ficheiro: $3, tipo MIME: $4)',
 477+);
 478+
 479+/** Brazilian Portuguese (Português do Brasil)
 480+ * @author 555
 481+ * @author Luckas Blade
 482+ */
 483+$messages['pt-br'] = array(
 484+ 'tiff-desc' => 'Permite visualizar arquivos TIFF como imagens',
 485+ 'tiff_no_metadata' => 'Não foi possível obter os metadados do TIFF',
 486+ 'tiff_page_error' => 'Número de página fora do intervalo',
 487+ 'tiff_too_many_embed_files' => 'A imagem possui arquivos embutidos demais.',
 488+ 'tiff_sourcefile_too_large' => 'A resolução do arquivo original é muito grande.
 489+Não serão geradas miniaturas.',
 490+ 'tiff_targetfile_too_large' => 'A resolução do arquivo de destino é muito grande.
 491+Não serão geradas miniaturas.',
 492+ 'tiff_file_too_large' => 'O arquivo enviado foi recusado por ser muito grande.',
 493+ 'tiff_out_of_service' => 'O arquivo enviado não pôde ser processado.
 494+ImageMagick não está disponível.',
 495+ 'tiff_too_much_meta' => 'Os metadados ocupam muito espaço.',
 496+ 'tiff_error_cached' => 'Este arquivo só poderá ser renderizado no próximo intervalo de cache.',
 497+ 'tiff_size_error' => 'O tamanho reportado do arquivo não confere com o tamanho real.',
 498+ 'tiff_script_detected' => 'O arquivo enviado contém scripts.',
 499+ 'tiff_bad_file' => 'O arquivo enviado contém erros.',
 500+ 'tiff-file-info-size' => '(página $5, $1 × $2 pixeis, tamanho do arquivo: $3, tipo MIME: $4)',
 501+);
 502+
 503+/** Russian (Русский)
 504+ * @author Александр Сигачёв
 505+ */
 506+$messages['ru'] = array(
 507+ 'tiff-desc' => 'Обработчик для просмотра TIFF-файлов в виде изображений',
 508+ 'tiff_no_metadata' => 'Невозможно получить метаданные из TIFF',
 509+ 'tiff_page_error' => 'Номер страницы вне диапазона',
 510+ 'tiff_too_many_embed_files' => 'Изображение содержит слишком много встроенных файлов.',
 511+ 'tiff_sourcefile_too_large' => 'Разрешение исходного файла слишком велико. Миниатюры создаваться не будут.',
 512+ 'tiff_targetfile_too_large' => 'Разрешение целевого файла слишком велико. Миниатюра не будет создана.',
 513+ 'tiff_file_too_large' => 'Размер загружаемого файла слишком велик, файл отклонён.',
 514+ 'tiff_out_of_service' => 'Загруженный файл не может быть обработан. ImageMagick недоступен.',
 515+ 'tiff_too_much_meta' => 'Метаданные занимают слишком много места.',
 516+ 'tiff_error_cached' => 'Этот файл может быть повторно перерисован только после кэширующего промежутка.',
 517+ 'tiff_size_error' => 'Указанный размер файла не совпадает с фактическим размером файла.',
 518+ 'tiff_script_detected' => 'Загруженный файл содержит сценарии.',
 519+ 'tiff_bad_file' => 'Загруженный файл содержит ошибки.',
 520+ 'tiff-file-info-size' => '(страница $5, $1 × $2 пикселов, размер файла: $3, MIME-тип: $4)',
 521+);
 522+
 523+/** Serbian Cyrillic ekavian (Српски (ћирилица))
 524+ * @author Михајло Анђелковић
 525+ */
 526+$messages['sr-ec'] = array(
 527+ 'tiff_no_metadata' => 'Не могу се преузети метаподаци из TIFF-а',
 528+ 'tiff_page_error' => 'Број стране није у опсегу',
 529+ 'tiff_too_many_embed_files' => 'Слика садржи превише уметнутих фајлова.',
 530+ 'tiff_file_too_large' => 'Послати фајл је превелик и одбачен је.',
 531+ 'tiff_out_of_service' => 'Послати фајл није могао бити обраћен. ImageMagick није доступан.',
 532+ 'tiff_too_much_meta' => 'Метаподаци користе превише простора.',
 533+ 'tiff_error_cached' => 'Овај фајл може бити рендерован само након кеширања.',
 534+ 'tiff_size_error' => 'Пријављена величина фајла не одговара његовој стварној величини.',
 535+ 'tiff_script_detected' => 'Послати фајл садржи скрипте.',
 536+ 'tiff_bad_file' => 'Послати фајл садржи грешке.',
 537+);
 538+
 539+/** Serbian Latin ekavian (Srpski (latinica)) */
 540+$messages['sr-el'] = array(
 541+ 'tiff_no_metadata' => 'Ne mogu se preuzeti metapodaci iz TIFF-a',
 542+ 'tiff_page_error' => 'Broj strane nije u opsegu',
 543+ 'tiff_too_many_embed_files' => 'Slika sadrži previše umetnutih fajlova.',
 544+ 'tiff_file_too_large' => 'Poslati fajl je prevelik i odbačen je.',
 545+ 'tiff_out_of_service' => 'Poslati fajl nije mogao biti obraćen. ImageMagick nije dostupan.',
 546+ 'tiff_too_much_meta' => 'Metapodaci koriste previše prostora.',
 547+ 'tiff_error_cached' => 'Ovaj fajl može biti renderovan samo nakon keširanja.',
 548+ 'tiff_size_error' => 'Prijavljena veličina fajla ne odgovara njegovoj stvarnoj veličini.',
 549+ 'tiff_script_detected' => 'Poslati fajl sadrži skripte.',
 550+ 'tiff_bad_file' => 'Poslati fajl sadrži greške.',
 551+);
 552+
 553+/** Tagalog (Tagalog)
 554+ * @author AnakngAraw
 555+ */
 556+$messages['tl'] = array(
 557+ 'tiff-desc' => 'Tagapaghawak para sa pagtanaw ng mga talaksang TIFF na nasa modalidad na panglarawan',
 558+ 'tiff_no_metadata' => 'Hindi makuha ang metadata mula sa TIFF',
 559+ 'tiff_page_error' => 'Wala sa sakop ang bilang ng pahina',
 560+ 'tiff_too_many_embed_files' => 'Naglalaman ang larawan ng napakaraming ibinaong mga talaksan.',
 561+ 'tiff_sourcefile_too_large' => 'Napakalaki ng resolusyon ng pinagmulang talaksan. Walang malilikhang maliit na larawan.',
 562+ 'tiff_targetfile_too_large' => 'Napakalaki ng resolusyon ng puntiryang talaksan. Walang malilikhang maliit na larawan.',
 563+ 'tiff_file_too_large' => "Napakalaki ng ikinargang-paitaas na talaksan kaya't tinanggihan.",
 564+ 'tiff_out_of_service' => 'Hindi maaasikaso ang talaksang ikinargang pataas. Hindi kasi makuha ang ImageMagick.',
 565+ 'tiff_too_much_meta' => 'Gumagamit ng labis na puwang ang metadata.',
 566+ 'tiff_error_cached' => 'Maaari lamang muling ibigay ang talaksan pagkatapos ng tagal ng agwat ng pagkukubli.',
 567+ 'tiff_size_error' => 'Hindi tumutugma ang inulat na sukat ng talaksan sa talagang sukat ng talaksan.',
 568+ 'tiff_script_detected' => 'Naglalaman ng mga baybayin ang ikinargang talaksan.',
 569+ 'tiff_bad_file' => 'Naglalaman ng mga kamalian ang ikinargang talaksan.',
 570+ 'tiff-file-info-size' => '(pahina $5, $1 × $2 piksel, sukat ng talaksan: $3, uri ng MIME: $4)',
 571+);
 572+
 573+/** Vietnamese (Tiếng Việt)
 574+ * @author Minh Nguyen
 575+ */
 576+$messages['vi'] = array(
 577+ 'tiff_no_metadata' => 'Không thể lấy siêu dữ liệu từ TIFF',
 578+ 'tiff_page_error' => 'Số trang không nằm trong giới hạn',
 579+ 'tiff_out_of_service' => 'Không thể xử lý tập tin được tải lên vì ImageMagick không có sẵn.',
 580+ 'tiff_too_much_meta' => 'Siêu dữ liệu tốn nhiều không gian quá.',
 581+ 'tiff_script_detected' => 'Tập tin được tải lên chứa script.',
 582+ 'tiff_bad_file' => 'Tập tin được tải lên có lỗi.',
 583+ 'tiff-file-info-size' => '(trang $5, $1×$2 điểm ảnh, kích thước: $3, định dạng MIME: $4)',
 584+);
 585+
 586+/** Yiddish (ייִדיש)
 587+ * @author פוילישער
 588+ */
 589+$messages['yi'] = array(
 590+ 'tiff_too_much_meta' => 'מעטאַדאַטן באַניצן צו פֿיל פלאַץ.',
 591+ 'tiff-file-info-size' => '(בלטַט $5, $1 × $2 פיקסעל, טעקע גרייס: $3, טיפ MIME: $4)',
 592+);
 593+
Property changes on: branches/wmf/1.16wmf4/extensions/PagedTiffHandler/PagedTiffHandler.i18n.php
___________________________________________________________________
Added: svn:eol-style
1594 + native
Index: branches/wmf/1.16wmf4/extensions/PagedTiffHandler/PagedTiffHandler.php
@@ -0,0 +1,111 @@
 2+<?php
 3+/**
 4+ * Copyright © Wikimedia Deutschland, 2009
 5+ * Authors Hallo Welt! Medienwerkstatt GmbH
 6+ * Authors Sebastian Ulbricht, Daniel Lynge, Marc Reymann, Markus Glaser
 7+ *
 8+ * This program is free software; you can redistribute it and/or modify
 9+ * it under the terms of the GNU General Public License as published by
 10+ * the Free Software Foundation; either version 2 of the License, or
 11+ * (at your option) any later version.
 12+ *
 13+ * This program is distributed in the hope that it will be useful,
 14+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
 15+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 16+ * GNU General Public License for more details.
 17+ *
 18+ * You should have received a copy of the GNU General Public License along
 19+ * with this program; if not, write to the Free Software Foundation, Inc.,
 20+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 21+ * http://www.gnu.org/copyleft/gpl.html
 22+ */
 23+
 24+# Not a valid entry point, skip unless MEDIAWIKI is defined
 25+if ( !defined( 'MEDIAWIKI' ) ) {
 26+ echo 'PagedTiffHandler extension';
 27+ exit( 1 );
 28+}
 29+
 30+/* Add to LocalSettings.php
 31+require_once("$IP/extensions/PagedTiffHandler/PagedTiffHandler.php");
 32+
 33+$wgUseImageMagick = true;
 34+$wgImageMagickConvertCommand = "C:\Program Files\ImageMagick-6.5.6-Q8\convert";
 35+$wgImageMagickIdentifyCommand = "C:\Program Files\ImageMagick-6.5.6-Q8\identify";
 36+$wgTiffExivCommand = "C:\Program Files\Exiv2\exiv2";
 37+$wgMaxUploadSize = 1073741824;
 38+$wgShowEXIF = true;
 39+*/
 40+
 41+$wgExtensionCredits['media'][] = array(
 42+ 'path' => __FILE__,
 43+ 'name' => 'PagedTiffHandler',
 44+ 'author' => array(
 45+ '[http://www.hallowelt.biz HalloWelt! Medienwerkstatt GmbH]',
 46+ 'Sebastian Ulbricht',
 47+ 'Daniel Lynge',
 48+ 'Marc Reymann',
 49+ 'Markus Glaser for Wikimedia Deutschland'
 50+ ),
 51+ 'descriptionmsg' => 'tiff-desc',
 52+ 'url' => 'http://www.mediawiki.org/wiki/Extension:PagedTiffHandler',
 53+);
 54+
 55+$wgTiffIdentifyRejectMessages = array(
 56+ '/TIFFErrors?/',
 57+ '/^identify: Compression algorithm does not support random access/',
 58+ '/^identify: Old-style LZW codes, convert file/',
 59+ '/^identify: Sorry, requested compression method is not configured/',
 60+ '/^identify: ThunderDecode: Not enough data at scanline/',
 61+ '/^identify: .+?: Read error on strip/',
 62+ '/^identify: .+?: Can not read TIFF directory/',
 63+ '/^identify: Not a TIFF/',
 64+);
 65+
 66+$wgTiffIdentifyBypassMessages = array(
 67+ //'/TIFFWarnings/',
 68+ //'/TIFFWarning/',
 69+ '/^identify: .*TIFFReadDirectory/',
 70+ '/^identify: .+?: unknown field with tag .+? encountered/'
 71+);
 72+
 73+// Use PHP-TiffReader
 74+// This is still experimental
 75+$wgTiffUseTiffReader = false;
 76+$wgTiffReaderPath = dirname( __FILE__ );
 77+$wgTiffReaderCheckEofForJS = 4; // check the last 4MB for JS
 78+
 79+// Path to identify
 80+$wgImageMagickIdentifyCommand = '/usr/bin/identify';
 81+// Path to exiv2
 82+$wgTiffExivCommand = '/usr/bin/exiv2';
 83+// Use exiv2?
 84+$wgTiffUseExiv = false;
 85+// Path to vips
 86+$wgTiffVipsCommand = '/usr/bin/vips';
 87+// Use vips
 88+$wgTiffUseVips = false;
 89+// Maximum number of embedded files in tiff image
 90+$wgTiffMaxEmbedFiles = 10000;
 91+// Maximum resolution of embedded images (product of width x height pixels)
 92+$wgMaxImageAreaForVips = 1600*1600; // max. Resolution 1600 x 1600 pixels
 93+// Maximum size of metadata
 94+$wgTiffMaxMetaSize = 64*1024;
 95+// TTL of cache entries for errors
 96+$wgTiffErrorCacheTTL = 24*60*60;
 97+
 98+$wgFileExtensions[] = 'tiff';
 99+$wgFileExtensions[] = 'tif';
 100+
 101+$dir = dirname( __FILE__ ) . '/';
 102+$wgExtensionMessagesFiles['PagedTiffHandler'] = $dir . 'PagedTiffHandler.i18n.php';
 103+$wgAutoloadClasses['PagedTiffImage'] = $dir . 'PagedTiffHandler.image.php';
 104+$wgAutoloadClasses['PagedTiffHandler'] = $dir . 'PagedTiffHandler_body.php';
 105+$wgAutoloadClasses['TiffReader'] = $dir . 'TiffReader.php';
 106+$wgAutoloadClasses['PagedTiffHandlerSeleniumTestSuite'] = $dir . 'selenium/PagedTiffHandlerTestSuite.php';
 107+
 108+$wgMediaHandlers['image/tiff'] = 'PagedTiffHandler';
 109+$wgHooks['UploadVerification'][] = 'PagedTiffHandler::check';
 110+$wgHooks['LanguageGetMagic'][] = 'PagedTiffHandler::addTiffLossyMagicWordLang';
 111+//$wgHooks['PagedTiffHandlerRenderCommand'][] = 'PagedTiffHandler::renderCommand';
 112+//$wgHooks['PagedTiffHandlerExivCommand'][] = 'PagedTiffImage::exivCommand';
Property changes on: branches/wmf/1.16wmf4/extensions/PagedTiffHandler/PagedTiffHandler.php
___________________________________________________________________
Added: svn:eol-style
1113 + native
Index: branches/wmf/1.16wmf4/extensions/PagedTiffHandler/PagedTiffHandler.image.php
@@ -0,0 +1,233 @@
 2+<?php
 3+/**
 4+ * Copyright © Wikimedia Deutschland, 2009
 5+ * Authors Hallo Welt! Medienwerkstatt GmbH
 6+ * Authors Sebastian Ulbricht, Daniel Lynge, Marc Reymann, Markus Glaser
 7+ *
 8+ * This program is free software; you can redistribute it and/or modify
 9+ * it under the terms of the GNU General Public License as published by
 10+ * the Free Software Foundation; either version 2 of the License, or
 11+ * (at your option) any later version.
 12+ *
 13+ * This program is distributed in the hope that it will be useful,
 14+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
 15+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 16+ * GNU General Public License for more details.
 17+ *
 18+ * You should have received a copy of the GNU General Public License along
 19+ * with this program; if not, write to the Free Software Foundation, Inc.,
 20+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 21+ * http://www.gnu.org/copyleft/gpl.html
 22+ */
 23+
 24+/**
 25+ * inspired by djvuimage from Brion Vibber
 26+ * modified and written by xarax
 27+ * adapted to tiff by Hallo Welt! - Medienwerkstatt GmbH
 28+ */
 29+
 30+class PagedTiffImage {
 31+ protected $_meta = null;
 32+ protected $mFilename;
 33+
 34+ function __construct( $filename ) {
 35+ $this->mFilename = $filename;
 36+ }
 37+
 38+ /**
 39+ * Called by MimeMagick functions.
 40+ */
 41+ public function isValid() {
 42+ return count( $this->retrieveMetaData() );
 43+ }
 44+
 45+ /**
 46+ * Returns an array that corresponds to the native PHP function getimagesize().
 47+ */
 48+ public function getImageSize() {
 49+ $data = $this->retrieveMetaData();
 50+ $size = $this->getPageSize( $data, 1 );
 51+
 52+ if ( $size ) {
 53+ $width = $size['width'];
 54+ $height = $size['height'];
 55+ return array( $width, $height, 'Tiff',
 56+ "width=\"$width\" height=\"$height\"" );
 57+ }
 58+ return false;
 59+ }
 60+
 61+ /**
 62+ * Returns an array with width and height of the tiff page.
 63+ */
 64+ public static function getPageSize( $data, $page ) {
 65+ if ( isset( $data['page_data'][$page] ) ) {
 66+ return array(
 67+ 'width' => $data['page_data'][$page]['width'],
 68+ 'height' => $data['page_data'][$page]['height']
 69+ );
 70+ }
 71+ return false;
 72+ }
 73+
 74+ /**
 75+ * Reads metadata of the tiff file via shell command and returns an associative array.
 76+ * layout:
 77+ * meta['page_amount'] = amount of pages
 78+ * meta['page_data'] = metadata per page
 79+ * meta['exif'] = Exif, XMP and IPTC
 80+ * meta['errors'] = identify-errors
 81+ * meta['warnings'] = identify-warnings
 82+ */
 83+ public function retrieveMetaData() {
 84+ global $wgImageMagickIdentifyCommand, $wgTiffExivCommand, $wgTiffUseExiv;
 85+
 86+ if ( $this->_meta === null ) {
 87+ if ( $wgImageMagickIdentifyCommand ) {
 88+
 89+ wfProfileIn( 'PagedTiffImage::retrieveMetaData' );
 90+
 91+ // ImageMagick is used to get the basic metadata of individual pages
 92+ $cmd = wfEscapeShellArg( $wgImageMagickIdentifyCommand ) .
 93+ ' -format "[BEGIN]page=%p\nalpha=%A\nalpha2=%r\nheight=%h\nwidth=%w\ndepth=%z[END]" ' .
 94+ wfEscapeShellArg( $this->mFilename ) . ' 2>&1';
 95+
 96+ wfProfileIn( 'identify' );
 97+ wfDebug( __METHOD__ . ": $cmd\n" );
 98+ $dump = wfShellExec( $cmd, $retval );
 99+ wfProfileOut( 'identify' );
 100+ if ( $retval ) {
 101+ $data['errors'][] = "identify command failed: $cmd";
 102+ wfDebug( __METHOD__ . ": identify command failed: $cmd\n" );
 103+ return $data; // fail. we *need* that info
 104+ }
 105+ $this->_meta = $this->convertDumpToArray( $dump );
 106+ $this->_meta['exif'] = array();
 107+
 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 );
 116+
 117+ wfRunHooks( 'PagedTiffHandlerExivCommand', array( &$cmd, $this->mFilename ) );
 118+
 119+ wfProfileIn( 'exiv2' );
 120+ wfDebug( __METHOD__ . ": $cmd\n" );
 121+ $dump = wfShellExec( $cmd, $retval );
 122+ wfProfileOut( 'exiv2' );
 123+
 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+ }
 129+
 130+ $result = array();
 131+ preg_match_all( '/(\w+)\s+(.+)/', $dump, $result, PREG_SET_ORDER );
 132+
 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' );
 146+ }
 147+ }
 148+ unset( $this->_meta['exif']['Image'] );
 149+ unset( $this->_meta['exif']['filename'] );
 150+ unset( $this->_meta['exif']['Base filename'] );
 151+ return $this->_meta;
 152+ }
 153+
 154+ /**
 155+ * helper function of retrieveMetaData().
 156+ * parses shell return from identify-command into an array.
 157+ */
 158+ protected function convertDumpToArray( $dump ) {
 159+ global $wgTiffIdentifyRejectMessages, $wgTiffIdentifyBypassMessages;
 160+
 161+ $data = array();
 162+ if ( strval( $dump ) == '' ) {
 163+ $data['errors'][] = "no metadata";
 164+ return $data;
 165+ }
 166+
 167+ $infos = null;
 168+ preg_match_all( '/\[BEGIN\](.+?)\[END\]/si', $dump, $infos, PREG_SET_ORDER );
 169+ $data['page_amount'] = count( $infos );
 170+ $data['page_data'] = array();
 171+ foreach ( $infos as $info ) {
 172+ $entry = array();
 173+ $lines = explode( "\n", $info[1] );
 174+ foreach ( $lines as $line ) {
 175+ if ( trim( $line ) == '' ) {
 176+ continue;
 177+ }
 178+ $parts = explode( '=', $line );
 179+ if ( trim( $parts[0] ) == 'alpha' && trim( $parts[1] ) == '%A' ) {
 180+ continue;
 181+ }
 182+ if ( trim( $parts[0] ) == 'alpha2' && !isset( $entry['alpha'] ) ) {
 183+ switch( trim( $parts[1] ) ) {
 184+ case 'DirectClassRGBMatte':
 185+ case 'DirectClassRGBA':
 186+ $entry['alpha'] = 'true';
 187+ break;
 188+ default:
 189+ $entry['alpha'] = 'false';
 190+ break;
 191+ }
 192+ continue;
 193+ }
 194+ $entry[trim( $parts[0] )] = trim( $parts[1] );
 195+ }
 196+ $entry['pixels'] = $entry['height'] * $entry['width'];
 197+ $data['page_data'][$entry['page']] = $entry;
 198+ }
 199+
 200+
 201+ $dump = preg_replace( '/\[BEGIN\](.+?)\[END\]/si', '', $dump );
 202+ if ( strlen( $dump ) ) {
 203+ $errors = explode( "\n", $dump );
 204+ foreach ( $errors as $error ) {
 205+ $error = trim( $error );
 206+ if ( $error === '' )
 207+ continue;
 208+
 209+ $knownError = false;
 210+ foreach ( $wgTiffIdentifyRejectMessages as $msg ) {
 211+ if ( preg_match( $msg, trim( $error ) ) ) {
 212+ $data['errors'][] = $error;
 213+ $knownError = true;
 214+ break;
 215+ }
 216+ }
 217+ if ( !$knownError ) {
 218+ // ignore messages that match $wgTiffIdentifyBypassMessages
 219+ foreach ( $wgTiffIdentifyBypassMessages as $msg ) {
 220+ if ( preg_match( $msg, trim( $error ) ) ) {
 221+ // $data['warnings'][] = $error;
 222+ $knownError = true;
 223+ break;
 224+ }
 225+ }
 226+ }
 227+ if ( !$knownError ) {
 228+ $data['warnings'][] = $error;
 229+ }
 230+ }
 231+ }
 232+ return $data;
 233+ }
 234+}
Property changes on: branches/wmf/1.16wmf4/extensions/PagedTiffHandler/PagedTiffHandler.image.php
___________________________________________________________________
Added: svn:eol-style
1235 + native
Property changes on: branches/wmf/1.16wmf4/extensions/PagedTiffHandler
___________________________________________________________________
Added: svn:ignore
2236 + nbproject

Status & tagging log