summaryrefslogtreecommitdiff
path: root/includes/media
diff options
context:
space:
mode:
Diffstat (limited to 'includes/media')
-rw-r--r--includes/media/BMP.php17
-rw-r--r--includes/media/Bitmap.php64
-rw-r--r--includes/media/BitmapMetadataHandler.php41
-rw-r--r--includes/media/Bitmap_ClientOnly.php20
-rw-r--r--includes/media/DjVu.php50
-rw-r--r--includes/media/DjVuImage.php4
-rw-r--r--includes/media/Exif.php9
-rw-r--r--includes/media/ExifBitmap.php20
-rw-r--r--includes/media/FormatMetadata.php125
-rw-r--r--includes/media/GIF.php30
-rw-r--r--includes/media/GIFMetadataExtractor.php17
-rw-r--r--includes/media/IPTC.php31
-rw-r--r--includes/media/ImageHandler.php249
-rw-r--r--includes/media/Jpeg.php17
-rw-r--r--includes/media/JpegMetadataExtractor.php44
-rw-r--r--includes/media/MediaHandler.php (renamed from includes/media/Generic.php)287
-rw-r--r--includes/media/MediaTransformOutput.php99
-rw-r--r--includes/media/PNG.php29
-rw-r--r--includes/media/PNGMetadataExtractor.php16
-rw-r--r--includes/media/SVG.php79
-rw-r--r--includes/media/SVGMetadataExtractor.php33
-rw-r--r--includes/media/Tiff.php15
-rw-r--r--includes/media/XCF.php17
-rw-r--r--includes/media/XMP.php62
-rw-r--r--includes/media/XMPInfo.php22
-rw-r--r--includes/media/XMPValidate.php22
26 files changed, 1012 insertions, 407 deletions
diff --git a/includes/media/BMP.php b/includes/media/BMP.php
index 6886e950..a515c635 100644
--- a/includes/media/BMP.php
+++ b/includes/media/BMP.php
@@ -1,6 +1,21 @@
<?php
/**
- * Handler for Microsoft's bitmap format
+ * Handler for Microsoft's bitmap format.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
*
* @file
* @ingroup Media
diff --git a/includes/media/Bitmap.php b/includes/media/Bitmap.php
index 619485cc..99ac854b 100644
--- a/includes/media/Bitmap.php
+++ b/includes/media/Bitmap.php
@@ -1,6 +1,21 @@
<?php
/**
- * Generic handler for bitmap images
+ * Generic handler for bitmap images.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
*
* @file
* @ingroup Media
@@ -152,8 +167,11 @@ class BitmapHandler extends ImageHandler {
if ( $flags & self::TRANSFORM_LATER ) {
wfDebug( __METHOD__ . ": Transforming later per flags.\n" );
- return new ThumbnailImage( $image, $dstUrl, $scalerParams['clientWidth'],
- $scalerParams['clientHeight'], false );
+ $params = array(
+ 'width' => $scalerParams['clientWidth'],
+ 'height' => $scalerParams['clientHeight']
+ );
+ return new ThumbnailImage( $image, $dstUrl, false, $params );
}
# Try to make a target path for the thumbnail
@@ -205,8 +223,11 @@ class BitmapHandler extends ImageHandler {
} elseif ( $mto ) {
return $mto;
} else {
- return new ThumbnailImage( $image, $dstUrl, $scalerParams['clientWidth'],
- $scalerParams['clientHeight'], $dstPath );
+ $params = array(
+ 'width' => $scalerParams['clientWidth'],
+ 'height' => $scalerParams['clientHeight']
+ );
+ return new ThumbnailImage( $image, $dstUrl, $dstPath, $params );
}
}
@@ -243,14 +264,17 @@ class BitmapHandler extends ImageHandler {
* client side
*
* @param $image File File associated with this thumbnail
- * @param $params array Array with scaler params
+ * @param $scalerParams array Array with scaler params
* @return ThumbnailImage
*
- * @fixme no rotation support
+ * @todo fixme: no rotation support
*/
- protected function getClientScalingThumbnailImage( $image, $params ) {
- return new ThumbnailImage( $image, $image->getURL(),
- $params['clientWidth'], $params['clientHeight'], null );
+ protected function getClientScalingThumbnailImage( $image, $scalerParams ) {
+ $params = array(
+ 'width' => $scalerParams['clientWidth'],
+ 'height' => $scalerParams['clientHeight']
+ );
+ return new ThumbnailImage( $image, $image->getURL(), null, $params );
}
/**
@@ -259,7 +283,7 @@ class BitmapHandler extends ImageHandler {
* @param $image File File associated with this thumbnail
* @param $params array Array with scaler params
*
- * @return MediaTransformError Error object if error occured, false (=no error) otherwise
+ * @return MediaTransformError Error object if error occurred, false (=no error) otherwise
*/
protected function transformImageMagick( $image, $params ) {
# use ImageMagick
@@ -358,7 +382,7 @@ class BitmapHandler extends ImageHandler {
* @param $image File File associated with this thumbnail
* @param $params array Array with scaler params
*
- * @return MediaTransformError Error object if error occured, false (=no error) otherwise
+ * @return MediaTransformError Error object if error occurred, false (=no error) otherwise
*/
protected function transformImageMagickExt( $image, $params ) {
global $wgSharpenReductionThreshold, $wgSharpenParameter, $wgMaxAnimatedGifArea;
@@ -435,7 +459,7 @@ class BitmapHandler extends ImageHandler {
* @param $image File File associated with this thumbnail
* @param $params array Array with scaler params
*
- * @return MediaTransformError Error object if error occured, false (=no error) otherwise
+ * @return MediaTransformError Error object if error occurred, false (=no error) otherwise
*/
protected function transformCustom( $image, $params ) {
# Use a custom convert command
@@ -462,7 +486,7 @@ class BitmapHandler extends ImageHandler {
}
/**
- * Log an error that occured in an external process
+ * Log an error that occurred in an external process
*
* @param $retval int
* @param $err int
@@ -491,7 +515,7 @@ class BitmapHandler extends ImageHandler {
* @param $image File File associated with this thumbnail
* @param $params array Array with scaler params
*
- * @return MediaTransformError Error object if error occured, false (=no error) otherwise
+ * @return MediaTransformError Error object if error occurred, false (=no error) otherwise
*/
protected function transformGd( $image, $params ) {
# Use PHP's builtin GD library functions.
@@ -509,7 +533,7 @@ class BitmapHandler extends ImageHandler {
if ( !isset( $typemap[$params['mimeType']] ) ) {
$err = 'Image type not supported';
wfDebug( "$err\n" );
- $errMsg = wfMsg( 'thumbnail_image-type' );
+ $errMsg = wfMessage( 'thumbnail_image-type' )->text();
return $this->getMediaTransformError( $params, $errMsg );
}
list( $loader, $colorStyle, $saveType ) = $typemap[$params['mimeType']];
@@ -517,14 +541,14 @@ class BitmapHandler extends ImageHandler {
if ( !function_exists( $loader ) ) {
$err = "Incomplete GD library configuration: missing function $loader";
wfDebug( "$err\n" );
- $errMsg = wfMsg( 'thumbnail_gd-library', $loader );
+ $errMsg = wfMessage( 'thumbnail_gd-library', $loader )->text();
return $this->getMediaTransformError( $params, $errMsg );
}
if ( !file_exists( $params['srcPath'] ) ) {
$err = "File seems to be missing: {$params['srcPath']}";
wfDebug( "$err\n" );
- $errMsg = wfMsg( 'thumbnail_image-missing', $params['srcPath'] );
+ $errMsg = wfMessage( 'thumbnail_image-missing', $params['srcPath'] )->text();
return $this->getMediaTransformError( $params, $errMsg );
}
@@ -572,6 +596,7 @@ class BitmapHandler extends ImageHandler {
/**
* Escape a string for ImageMagick's property input (e.g. -set -comment)
* See InterpretImageProperties() in magick/property.c
+ * @return mixed|string
*/
function escapeMagickProperty( $s ) {
// Double the backslashes
@@ -599,6 +624,7 @@ class BitmapHandler extends ImageHandler {
*
* @param $path string The file path
* @param $scene string The scene specification, or false if there is none
+ * @return string
*/
function escapeMagickInput( $path, $scene = false ) {
# Die on initial metacharacters (caller should prepend path)
@@ -616,6 +642,7 @@ class BitmapHandler extends ImageHandler {
/**
* Escape a string for ImageMagick's output filename. See
* InterpretImageFilename() in magick/image.c.
+ * @return string
*/
function escapeMagickOutput( $path, $scene = false ) {
$path = str_replace( '%', '%%', $path );
@@ -628,6 +655,7 @@ class BitmapHandler extends ImageHandler {
*
* @param $path string The file path
* @param $scene string The scene specification, or false if there is none
+ * @return string
*/
protected function escapeMagickPath( $path, $scene = false ) {
# Die on format specifiers (other than drive letters). The regex is
diff --git a/includes/media/BitmapMetadataHandler.php b/includes/media/BitmapMetadataHandler.php
index 746dddda..0a195547 100644
--- a/includes/media/BitmapMetadataHandler.php
+++ b/includes/media/BitmapMetadataHandler.php
@@ -1,13 +1,36 @@
<?php
/**
-Class to deal with reconciling and extracting metadata from bitmap images.
-This is meant to comply with http://www.metadataworkinggroup.org/pdf/mwg_guidance.pdf
+ * Extraction of metadata from different bitmap image types.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @ingroup Media
+ */
-This sort of acts as an intermediary between MediaHandler::getMetadata
-and the various metadata extractors.
-
-@todo other image formats.
-*/
+/**
+ * Class to deal with reconciling and extracting metadata from bitmap images.
+ * This is meant to comply with http://www.metadataworkinggroup.org/pdf/mwg_guidance.pdf
+ *
+ * This sort of acts as an intermediary between MediaHandler::getMetadata
+ * and the various metadata extractors.
+ *
+ * @todo other image formats.
+ * @ingroup Media
+ */
class BitmapMetadataHandler {
private $metadata = array();
@@ -122,7 +145,7 @@ class BitmapMetadataHandler {
/** Main entry point for jpeg's.
*
* @param $filename string filename (with full path)
- * @return metadata result array.
+ * @return array metadata result array.
* @throws MWException on invalid file.
*/
static function Jpeg ( $filename ) {
@@ -193,7 +216,7 @@ class BitmapMetadataHandler {
* They don't really have native metadata, so just merges together
* XMP and image comment.
*
- * @param $filename full path to file
+ * @param $filename string full path to file
* @return Array metadata array
*/
static public function GIF ( $filename ) {
diff --git a/includes/media/Bitmap_ClientOnly.php b/includes/media/Bitmap_ClientOnly.php
index 3c5d9738..63af2552 100644
--- a/includes/media/Bitmap_ClientOnly.php
+++ b/includes/media/Bitmap_ClientOnly.php
@@ -1,6 +1,21 @@
<?php
/**
- * Handler for bitmap images that will be resized by clients
+ * Handler for bitmap images that will be resized by clients.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
*
* @file
* @ingroup Media
@@ -37,7 +52,6 @@ class BitmapHandler_ClientOnly extends BitmapHandler {
if ( !$this->normaliseParams( $image, $params ) ) {
return new TransformParameterError( $params );
}
- return new ThumbnailImage( $image, $image->getURL(), $params['width'],
- $params['height'], $image->getLocalRefPath() );
+ return new ThumbnailImage( $image, $image->getURL(), $image->getLocalRefPath(), $params );
}
}
diff --git a/includes/media/DjVu.php b/includes/media/DjVu.php
index dedbee0d..84672e05 100644
--- a/includes/media/DjVu.php
+++ b/includes/media/DjVu.php
@@ -1,6 +1,21 @@
<?php
/**
- * Handler for DjVu images
+ * Handler for DjVu images.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
*
* @file
* @ingroup Media
@@ -123,7 +138,7 @@ class DjVuHandler extends ImageHandler {
$width = isset( $params['width'] ) ? $params['width'] : 0;
$height = isset( $params['height'] ) ? $params['height'] : 0;
return new MediaTransformError( 'thumbnail_error', $width, $height,
- wfMsg( 'djvu_no_xml' ) );
+ wfMessage( 'djvu_no_xml' )->text() );
}
if ( !$this->normaliseParams( $image, $params ) ) {
@@ -131,20 +146,35 @@ class DjVuHandler extends ImageHandler {
}
$width = $params['width'];
$height = $params['height'];
- $srcPath = $image->getLocalRefPath();
$page = $params['page'];
if ( $page > $this->pageCount( $image ) ) {
- return new MediaTransformError( 'thumbnail_error', $width, $height, wfMsg( 'djvu_page_error' ) );
+ return new MediaTransformError(
+ 'thumbnail_error',
+ $width,
+ $height,
+ wfMessage( 'djvu_page_error' )->text()
+ );
}
if ( $flags & self::TRANSFORM_LATER ) {
- return new ThumbnailImage( $image, $dstUrl, $width, $height, $dstPath, $page );
+ $params = array(
+ 'width' => $width,
+ 'height' => $height,
+ 'page' => $page
+ );
+ return new ThumbnailImage( $image, $dstUrl, $dstPath, $params );
}
if ( !wfMkdirParents( dirname( $dstPath ), null, __METHOD__ ) ) {
- return new MediaTransformError( 'thumbnail_error', $width, $height, wfMsg( 'thumbnail_dest_directory' ) );
+ return new MediaTransformError(
+ 'thumbnail_error',
+ $width,
+ $height,
+ wfMessage( 'thumbnail_dest_directory' )->text()
+ );
}
+ $srcPath = $image->getLocalRefPath();
# Use a subshell (brackets) to aggregate stderr from both pipeline commands
# before redirecting it to the overall stdout. This works in both Linux and Windows XP.
$cmd = '(' . wfEscapeShellArg( $wgDjvuRenderer ) . " -format=ppm -page={$page}" .
@@ -167,7 +197,12 @@ class DjVuHandler extends ImageHandler {
wfHostname(), $retval, trim($err), $cmd ) );
return new MediaTransformError( 'thumbnail_error', $width, $height, $err );
} else {
- return new ThumbnailImage( $image, $dstUrl, $width, $height, $dstPath, $page );
+ $params = array(
+ 'width' => $width,
+ 'height' => $height,
+ 'page' => $page
+ );
+ return new ThumbnailImage( $image, $dstUrl, $dstPath, $params );
}
}
@@ -191,6 +226,7 @@ class DjVuHandler extends ImageHandler {
* Cache a document tree for the DjVu XML metadata
* @param $image File
* @param $gettext Boolean: DOCUMENT (Default: false)
+ * @return bool
*/
function getMetaTree( $image , $gettext = false ) {
if ( isset( $image->dejaMetaTree ) ) {
diff --git a/includes/media/DjVuImage.php b/includes/media/DjVuImage.php
index 80b7408c..6aef562b 100644
--- a/includes/media/DjVuImage.php
+++ b/includes/media/DjVuImage.php
@@ -1,6 +1,6 @@
<?php
/**
- * DjVu image handler
+ * DjVu image handler.
*
* Copyright © 2006 Brion Vibber <brion@pobox.com>
* http://www.mediawiki.org/
@@ -21,6 +21,7 @@
* http://www.gnu.org/copyleft/gpl.html
*
* @file
+ * @ingroup Media
*/
/**
@@ -284,6 +285,7 @@ EOR;
/**
* Hack to temporarily work around djvutoxml bug
+ * @return bool|string
*/
function convertDumpToXML( $dump ) {
if ( strval( $dump ) == '' ) {
diff --git a/includes/media/Exif.php b/includes/media/Exif.php
index a4acdfe0..784a6018 100644
--- a/includes/media/Exif.php
+++ b/includes/media/Exif.php
@@ -1,5 +1,7 @@
<?php
/**
+ * Extraction and validation of image metadata.
+ *
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
@@ -368,6 +370,12 @@ class Exif {
$this->exifGPStoNumber( 'GPSDestLongitude' );
if ( isset( $this->mFilteredExifData['GPSAltitude'] ) && isset( $this->mFilteredExifData['GPSAltitudeRef'] ) ) {
+
+ // We know altitude data is a <num>/<denom> from the validation functions ran earlier.
+ // But multiplying such a string by -1 doesn't work well, so convert.
+ list( $num, $denom ) = explode( '/', $this->mFilteredExifData['GPSAltitude'] );
+ $this->mFilteredExifData['GPSAltitude'] = $num / $denom;
+
if ( $this->mFilteredExifData['GPSAltitudeRef'] === "\1" ) {
$this->mFilteredExifData['GPSAltitude'] *= - 1;
}
@@ -549,6 +557,7 @@ class Exif {
*/
/**
* Get $this->mRawExifData
+ * @return array
*/
function getData() {
return $this->mRawExifData;
diff --git a/includes/media/ExifBitmap.php b/includes/media/ExifBitmap.php
index 7b9867f7..34a1f511 100644
--- a/includes/media/ExifBitmap.php
+++ b/includes/media/ExifBitmap.php
@@ -1,5 +1,22 @@
<?php
/**
+ * Handler for bitmap images with exif metadata.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
* @file
* @ingroup Media
*/
@@ -182,7 +199,8 @@ class ExifBitmapHandler extends BitmapHandler {
*
* @param string $data
* @return int 0, 90, 180 or 270
- * @fixme orientation can include flipping as well; see if this is an issue!
+ * @todo FIXME orientation can include flipping as well; see if this is an
+ * issue!
*/
protected function getRotationForExif( $data ) {
if ( !$data ) {
diff --git a/includes/media/FormatMetadata.php b/includes/media/FormatMetadata.php
index 91cb6914..843c1fa2 100644
--- a/includes/media/FormatMetadata.php
+++ b/includes/media/FormatMetadata.php
@@ -1,5 +1,7 @@
<?php
/**
+ * Formating of image metadata values into human readable form.
+ *
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
@@ -98,14 +100,20 @@ class FormatMetadata {
) {
continue;
}
- $tags[$tag] = intval( $h[0] / $h[1] )
+ $tags[$tag] = str_pad( intval( $h[0] / $h[1] ), 2, '0', STR_PAD_LEFT )
. ':' . str_pad( intval( $m[0] / $m[1] ), 2, '0', STR_PAD_LEFT )
. ':' . str_pad( intval( $s[0] / $s[1] ), 2, '0', STR_PAD_LEFT );
- $time = wfTimestamp( TS_MW, '1971:01:01 ' . $tags[$tag] );
- // the 1971:01:01 is just a placeholder, and not shown to user.
- if ( $time && intval( $time ) > 0 ) {
- $tags[$tag] = $wgLang->time( $time );
+ try {
+ $time = wfTimestamp( TS_MW, '1971:01:01 ' . $tags[$tag] );
+ // the 1971:01:01 is just a placeholder, and not shown to user.
+ if ( $time && intval( $time ) > 0 ) {
+ $tags[$tag] = $wgLang->time( $time );
+ }
+ } catch ( TimestampException $e ) {
+ // This shouldn't happen, but we've seen bad formats
+ // such as 4-digit seconds in the wild.
+ // leave $tags[$tag] as-is
}
continue;
}
@@ -231,7 +239,7 @@ class FormatMetadata {
case 'dc-date':
case 'DateTimeMetadata':
if ( $val == '0000:00:00 00:00:00' || $val == ' : : : : ' ) {
- $val = wfMsg( 'exif-unknowndate' );
+ $val = wfMessage( 'exif-unknowndate' )->text();
} elseif ( preg_match( '/^(?:\d{4}):(?:\d\d):(?:\d\d) (?:\d\d):(?:\d\d):(?:\d\d)$/D', $val ) ) {
// Full date.
$time = wfTimestamp( TS_MW, $val );
@@ -307,7 +315,7 @@ class FormatMetadata {
'redeye' => ( $val & bindec( '01000000' ) ) >> 6,
// 'reserved' => ($val & bindec( '10000000' )) >> 7,
);
-
+ $flashMsgs = array();
# We do not need to handle unknown values since all are used.
foreach ( $flashDecode as $subTag => $subValue ) {
# We do not need any message for zeroed values.
@@ -589,7 +597,7 @@ class FormatMetadata {
case 'Software':
if ( is_array( $val ) ) {
//if its a software, version array.
- $val = wfMsg( 'exif-software-version-value', $val[0], $val[1] );
+ $val = wfMessage( 'exif-software-version-value', $val[0], $val[1] )->text();
} else {
$val = self::msg( $tag, '', $val );
}
@@ -597,8 +605,8 @@ class FormatMetadata {
case 'ExposureTime':
// Show the pretty fraction as well as decimal version
- $val = wfMsg( 'exif-exposuretime-format',
- self::formatFraction( $val ), self::formatNum( $val ) );
+ $val = wfMessage( 'exif-exposuretime-format',
+ self::formatFraction( $val ), self::formatNum( $val ) )->text();
break;
case 'ISOSpeedRatings':
// If its = 65535 that means its at the
@@ -611,13 +619,13 @@ class FormatMetadata {
}
break;
case 'FNumber':
- $val = wfMsg( 'exif-fnumber-format',
- self::formatNum( $val ) );
+ $val = wfMessage( 'exif-fnumber-format',
+ self::formatNum( $val ) )->text();
break;
case 'FocalLength': case 'FocalLengthIn35mmFilm':
- $val = wfMsg( 'exif-focallength-format',
- self::formatNum( $val ) );
+ $val = wfMessage( 'exif-focallength-format',
+ self::formatNum( $val ) )->text();
break;
case 'MaxApertureValue':
@@ -631,14 +639,14 @@ class FormatMetadata {
if ( is_numeric( $val ) ) {
$fNumber = pow( 2, $val / 2 );
if ( $fNumber !== false ) {
- $val = wfMsg( 'exif-maxaperturevalue-value',
+ $val = wfMessage( 'exif-maxaperturevalue-value',
self::formatNum( $val ),
self::formatNum( $fNumber, 2 )
- );
+ )->text();
}
}
break;
-
+
case 'iimCategory':
switch( strtolower( $val ) ) {
// See pg 29 of IPTC photo
@@ -694,7 +702,7 @@ class FormatMetadata {
case 'PixelYDimension':
case 'ImageWidth':
case 'ImageLength':
- $val = self::formatNum( $val ) . ' ' . wfMsg( 'unit-pixel' );
+ $val = self::formatNum( $val ) . ' ' . wfMessage( 'unit-pixel' )->text();
break;
// Do not transform fields with pure text.
@@ -800,7 +808,7 @@ class FormatMetadata {
break;
case 'LanguageCode':
- $lang = $wgLang->getLanguageName( strtolower( $val ) );
+ $lang = Language::fetchLanguageName( strtolower( $val ), $wgLang->getCode() );
if ($lang) {
$val = htmlspecialchars( $lang );
} else {
@@ -825,14 +833,14 @@ class FormatMetadata {
* This turns an array of (for example) authors into a bulleted list.
*
* This is public on the basis it might be useful outside of this class.
- *
+ *
* @param $vals Array array of values
* @param $type String Type of array (either lang, ul, ol).
* lang = language assoc array with keys being the lang code
* ul = unordered list, ol = ordered list
* type can also come from the '_type' member of $vals.
* @param $noHtml Boolean If to avoid returning anything resembling
- * html. (Ugly hack for backwards compatibility with old mediawiki).
+ * html. (Ugly hack for backwards compatibility with old mediawiki).
* @return String single value (in wiki-syntax).
*/
public static function flattenArray( $vals, $type = 'ul', $noHtml = false ) {
@@ -874,7 +882,7 @@ class FormatMetadata {
// If default is set, save it for later,
// as we don't know if it's equal to
// one of the lang codes. (In xmp
- // you specify the language for a
+ // you specify the language for a
// default property by having both
// a default prop, and one in the language
// that are identical)
@@ -937,11 +945,11 @@ class FormatMetadata {
* @param $lang String lang code of item or false
* @param $default Boolean if it is default value.
* @param $noHtml Boolean If to avoid html (for back-compat)
- * @return language item (Note: despite how this looks,
- * this is treated as wikitext not html).
+ * @throws MWException
+ * @return string language item (Note: despite how this looks,
+ * this is treated as wikitext not html).
*/
private static function langItem( $value, $lang, $default = false, $noHtml = false ) {
- global $wgContLang;
if ( $lang === false && $default === false) {
throw new MWException('$lang and $default cannot both '
. 'be false.');
@@ -956,21 +964,21 @@ class FormatMetadata {
if ( $lang === false ) {
if ( $noHtml ) {
- return wfMsg( 'metadata-langitem-default',
- $wrappedValue ) . "\n\n";
+ return wfMessage( 'metadata-langitem-default',
+ $wrappedValue )->text() . "\n\n";
} /* else */
return '<li class="mw-metadata-lang-default">'
- . wfMsg( 'metadata-langitem-default',
- $wrappedValue )
+ . wfMessage( 'metadata-langitem-default',
+ $wrappedValue )->text()
. "</li>\n";
}
$lowLang = strtolower( $lang );
- $langName = $wgContLang->getLanguageName( $lowLang );
+ $langName = Language::fetchLanguageName( $lowLang );
if ( $langName === '' ) {
//try just the base language name. (aka en-US -> en ).
list( $langPrefix ) = explode( '-', $lowLang, 2 );
- $langName = $wgContLang->getLanguageName( $langPrefix );
+ $langName = Language::fetchLanguageName( $langPrefix );
if ( $langName === '' ) {
// give up.
$langName = $lang;
@@ -979,8 +987,8 @@ class FormatMetadata {
// else we have a language specified
if ( $noHtml ) {
- return '*' . wfMsg( 'metadata-langitem',
- $wrappedValue, $langName, $lang );
+ return '*' . wfMessage( 'metadata-langitem',
+ $wrappedValue, $langName, $lang )->text();
} /* else: */
$item = '<li class="mw-metadata-lang-code-'
@@ -989,8 +997,8 @@ class FormatMetadata {
$item .= ' mw-metadata-lang-default';
}
$item .= '" lang="' . $lang . '">';
- $item .= wfMsg( 'metadata-langitem',
- $wrappedValue, $langName, $lang );
+ $item .= wfMessage( 'metadata-langitem',
+ $wrappedValue, $langName, $lang )->text();
$item .= "</li>\n";
return $item;
}
@@ -1004,24 +1012,22 @@ class FormatMetadata {
* @param $val String: the value of the tag
* @param $arg String: an argument to pass ($1)
* @param $arg2 String: a 2nd argument to pass ($2)
- * @return string A wfMsg of "exif-$tag-$val" in lower case
+ * @return string A wfMessage of "exif-$tag-$val" in lower case
*/
static function msg( $tag, $val, $arg = null, $arg2 = null ) {
global $wgContLang;
if ($val === '')
$val = 'value';
- return wfMsg( $wgContLang->lc( "exif-$tag-$val" ), $arg, $arg2 );
+ return wfMessage( $wgContLang->lc( "exif-$tag-$val" ), $arg, $arg2 )->text();
}
/**
* Format a number, convert numbers from fractions into floating point
* numbers, joins arrays of numbers with commas.
*
- * @private
- *
* @param $num Mixed: the value to format
- * @param $round digits to round to or false.
+ * @param $round float|int|bool digits to round to or false.
* @return mixed A floating point number or whatever we were fed
*/
static function formatNum( $num, $round = false ) {
@@ -1102,8 +1108,9 @@ class FormatMetadata {
return $a;
}
- /** Fetch the human readable version of a news code.
- * A news code is an 8 digit code. The first two
+ /**
+ * Fetch the human readable version of a news code.
+ * A news code is an 8 digit code. The first two
* digits are a general classification, so we just
* translate that.
*
@@ -1111,7 +1118,7 @@ class FormatMetadata {
* a string, not an int.
*
* @param $val String: The 8 digit news code.
- * @return The human readable form
+ * @return string The human readable form
*/
static private function convertNewsCode( $val ) {
if ( !preg_match( '/^\d{8}$/D', $val ) ) {
@@ -1183,7 +1190,7 @@ class FormatMetadata {
* Format a coordinate value, convert numbers from floating point
* into degree minute second representation.
*
- * @param $coord Array: degrees, minutes and seconds
+ * @param $coord int degrees, minutes and seconds
* @param $type String: latitude or longitude (for if its a NWS or E)
* @return mixed A floating point number or whatever we were fed
*/
@@ -1193,17 +1200,14 @@ class FormatMetadata {
$nCoord = -$coord;
if ( $type === 'latitude' ) {
$ref = 'S';
- }
- elseif ( $type === 'longitude' ) {
+ } elseif ( $type === 'longitude' ) {
$ref = 'W';
}
- }
- else {
+ } else {
$nCoord = $coord;
if ( $type === 'latitude' ) {
$ref = 'N';
- }
- elseif ( $type === 'longitude' ) {
+ } elseif ( $type === 'longitude' ) {
$ref = 'E';
}
}
@@ -1216,7 +1220,7 @@ class FormatMetadata {
$min = self::formatNum( $min );
$sec = self::formatNum( $sec );
- return wfMsg( 'exif-coordinate-format', $deg, $min, $sec, $ref, $coord );
+ return wfMessage( 'exif-coordinate-format', $deg, $min, $sec, $ref, $coord )->text();
}
/**
@@ -1274,7 +1278,7 @@ class FormatMetadata {
// Todo: This can potentially be multi-line.
// Need to check how that works in XMP.
$street = '<span class="extended-address">'
- . htmlspecialchars(
+ . htmlspecialchars(
$vals['CiAdrExtadr'] )
. '</span>';
}
@@ -1321,7 +1325,7 @@ class FormatMetadata {
}
if ( isset( $vals['CiAdrPcode'] ) ) {
$postal = '<span class="postal-code">'
- . htmlspecialchars(
+ . htmlspecialchars(
$vals['CiAdrPcode'] )
. '</span>';
}
@@ -1337,9 +1341,9 @@ class FormatMetadata {
. htmlspecialchars( $vals['CiUrlWork'] )
. '</span>';
}
- return wfMsg( 'exif-contact-value', $email, $url,
+ return wfMessage( 'exif-contact-value', $email, $url,
$street, $city, $region, $postal, $country,
- $tel );
+ $tel )->text();
}
}
}
@@ -1352,12 +1356,19 @@ class FormatMetadata {
**/
class FormatExif {
var $meta;
- function FormatExif ( $meta ) {
+
+ /**
+ * @param $meta array
+ */
+ function FormatExif( $meta ) {
wfDeprecated(__METHOD__);
$this->meta = $meta;
}
- function getFormattedData ( ) {
+ /**
+ * @return array
+ */
+ function getFormattedData() {
return FormatMetadata::getFormattedData( $this->meta );
}
}
diff --git a/includes/media/GIF.php b/includes/media/GIF.php
index 32618e94..84b9b8ca 100644
--- a/includes/media/GIF.php
+++ b/includes/media/GIF.php
@@ -2,6 +2,21 @@
/**
* Handler for GIF images.
*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
* @file
* @ingroup Media
*/
@@ -78,6 +93,17 @@ class GIFHandler extends BitmapHandler {
return false;
}
+ /**
+ * We cannot animate thumbnails that are bigger than a particular size
+ * @param File $file
+ * @return bool
+ */
+ function canAnimateThumbnail( $file ) {
+ global $wgMaxAnimatedGifArea;
+ $answer = $this->getImageArea( $file ) <= $wgMaxAnimatedGifArea;
+ return $answer;
+ }
+
function getMetadataType( $image ) {
return 'parsed-gif';
}
@@ -127,11 +153,11 @@ class GIFHandler extends BitmapHandler {
$info[] = $original;
if ( $metadata['looped'] ) {
- $info[] = wfMsgExt( 'file-info-gif-looped', 'parseinline' );
+ $info[] = wfMessage( 'file-info-gif-looped' )->parse();
}
if ( $metadata['frameCount'] > 1 ) {
- $info[] = wfMsgExt( 'file-info-gif-frames', 'parseinline', $metadata['frameCount'] );
+ $info[] = wfMessage( 'file-info-gif-frames' )->numParams( $metadata['frameCount'] )->parse();
}
if ( $metadata['duration'] ) {
diff --git a/includes/media/GIFMetadataExtractor.php b/includes/media/GIFMetadataExtractor.php
index 5dbeb8f8..5fc5c1a7 100644
--- a/includes/media/GIFMetadataExtractor.php
+++ b/includes/media/GIFMetadataExtractor.php
@@ -7,6 +7,21 @@
* Deliberately not using MWExceptions to avoid external dependencies, encouraging
* redistribution.
*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
* @file
* @ingroup Media
*/
@@ -286,7 +301,7 @@ class GIFMetadataExtractor {
* sub-blocks in the returned value. Normally this is false,
* except XMP is weird and does a hack where you need to keep
* these length bytes.
- * @return The data.
+ * @return string The data.
*/
static function readBlock( $fh, $includeLengths = false ) {
$data = '';
diff --git a/includes/media/IPTC.php b/includes/media/IPTC.php
index 1d19791c..8fd3552f 100644
--- a/includes/media/IPTC.php
+++ b/includes/media/IPTC.php
@@ -1,8 +1,31 @@
<?php
/**
-*Class for some IPTC functions.
+ * Class for some IPTC functions.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @ingroup Media
+ */
-*/
+/**
+ * Class for some IPTC functions.
+ *
+ * @ingroup Media
+ */
class IPTC {
/**
@@ -395,10 +418,10 @@ class IPTC {
/**
* Helper function to convert charset for iptc values.
- * @param $data Mixed String or Array: The iptc string
+ * @param $data string|array The iptc string
* @param $charset String: The charset
*
- * @return string
+ * @return string|array
*/
private static function convIPTC ( $data, $charset ) {
if ( is_array( $data ) ) {
diff --git a/includes/media/ImageHandler.php b/includes/media/ImageHandler.php
new file mode 100644
index 00000000..61759074
--- /dev/null
+++ b/includes/media/ImageHandler.php
@@ -0,0 +1,249 @@
+<?php
+/**
+ * Media-handling base classes and generic functionality.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @ingroup Media
+ */
+
+/**
+ * Media handler abstract base class for images
+ *
+ * @ingroup Media
+ */
+abstract class ImageHandler extends MediaHandler {
+
+ /**
+ * @param $file File
+ * @return bool
+ */
+ function canRender( $file ) {
+ return ( $file->getWidth() && $file->getHeight() );
+ }
+
+ function getParamMap() {
+ return array( 'img_width' => 'width' );
+ }
+
+ function validateParam( $name, $value ) {
+ if ( in_array( $name, array( 'width', 'height' ) ) ) {
+ if ( $value <= 0 ) {
+ return false;
+ } else {
+ return true;
+ }
+ } else {
+ return false;
+ }
+ }
+
+ function makeParamString( $params ) {
+ if ( isset( $params['physicalWidth'] ) ) {
+ $width = $params['physicalWidth'];
+ } elseif ( isset( $params['width'] ) ) {
+ $width = $params['width'];
+ } else {
+ throw new MWException( 'No width specified to '.__METHOD__ );
+ }
+ # Removed for ProofreadPage
+ #$width = intval( $width );
+ return "{$width}px";
+ }
+
+ function parseParamString( $str ) {
+ $m = false;
+ if ( preg_match( '/^(\d+)px$/', $str, $m ) ) {
+ return array( 'width' => $m[1] );
+ } else {
+ return false;
+ }
+ }
+
+ function getScriptParams( $params ) {
+ return array( 'width' => $params['width'] );
+ }
+
+ /**
+ * @param $image File
+ * @param $params
+ * @return bool
+ */
+ function normaliseParams( $image, &$params ) {
+ $mimeType = $image->getMimeType();
+
+ if ( !isset( $params['width'] ) ) {
+ return false;
+ }
+
+ if ( !isset( $params['page'] ) ) {
+ $params['page'] = 1;
+ } else {
+ if ( $params['page'] > $image->pageCount() ) {
+ $params['page'] = $image->pageCount();
+ }
+
+ if ( $params['page'] < 1 ) {
+ $params['page'] = 1;
+ }
+ }
+
+ $srcWidth = $image->getWidth( $params['page'] );
+ $srcHeight = $image->getHeight( $params['page'] );
+
+ if ( isset( $params['height'] ) && $params['height'] != -1 ) {
+ # Height & width were both set
+ if ( $params['width'] * $srcHeight > $params['height'] * $srcWidth ) {
+ # Height is the relative smaller dimension, so scale width accordingly
+ $params['width'] = self::fitBoxWidth( $srcWidth, $srcHeight, $params['height'] );
+
+ if ( $params['width'] == 0 ) {
+ # Very small image, so we need to rely on client side scaling :(
+ $params['width'] = 1;
+ }
+
+ $params['physicalWidth'] = $params['width'];
+ } else {
+ # Height was crap, unset it so that it will be calculated later
+ unset( $params['height'] );
+ }
+ }
+
+ if ( !isset( $params['physicalWidth'] ) ) {
+ # Passed all validations, so set the physicalWidth
+ $params['physicalWidth'] = $params['width'];
+ }
+
+ # Because thumbs are only referred to by width, the height always needs
+ # to be scaled by the width to keep the thumbnail sizes consistent,
+ # even if it was set inside the if block above
+ $params['physicalHeight'] = File::scaleHeight( $srcWidth, $srcHeight,
+ $params['physicalWidth'] );
+
+ # Set the height if it was not validated in the if block higher up
+ if ( !isset( $params['height'] ) || $params['height'] == -1 ) {
+ $params['height'] = $params['physicalHeight'];
+ }
+
+
+ if ( !$this->validateThumbParams( $params['physicalWidth'],
+ $params['physicalHeight'], $srcWidth, $srcHeight, $mimeType ) ) {
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Validate thumbnail parameters and fill in the correct height
+ *
+ * @param $width Integer: specified width (input/output)
+ * @param $height Integer: height (output only)
+ * @param $srcWidth Integer: width of the source image
+ * @param $srcHeight Integer: height of the source image
+ * @param $mimeType
+ * @return bool False to indicate that an error should be returned to the user.
+ */
+ function validateThumbParams( &$width, &$height, $srcWidth, $srcHeight, $mimeType ) {
+ $width = intval( $width );
+
+ # Sanity check $width
+ if( $width <= 0) {
+ wfDebug( __METHOD__.": Invalid destination width: $width\n" );
+ return false;
+ }
+ if ( $srcWidth <= 0 ) {
+ wfDebug( __METHOD__.": Invalid source width: $srcWidth\n" );
+ return false;
+ }
+
+ $height = File::scaleHeight( $srcWidth, $srcHeight, $width );
+ if ( $height == 0 ) {
+ # Force height to be at least 1 pixel
+ $height = 1;
+ }
+ return true;
+ }
+
+ /**
+ * @param $image File
+ * @param $script
+ * @param $params
+ * @return bool|ThumbnailImage
+ */
+ function getScriptedTransform( $image, $script, $params ) {
+ if ( !$this->normaliseParams( $image, $params ) ) {
+ return false;
+ }
+ $url = $script . '&' . wfArrayToCGI( $this->getScriptParams( $params ) );
+
+ if( $image->mustRender() || $params['width'] < $image->getWidth() ) {
+ return new ThumbnailImage( $image, $url, false, $params );
+ }
+ }
+
+ function getImageSize( $image, $path ) {
+ wfSuppressWarnings();
+ $gis = getimagesize( $path );
+ wfRestoreWarnings();
+ return $gis;
+ }
+
+ /**
+ * @param $file File
+ * @return string
+ */
+ function getShortDesc( $file ) {
+ global $wgLang;
+ $nbytes = htmlspecialchars( $wgLang->formatSize( $file->getSize() ) );
+ $widthheight = wfMessage( 'widthheight' )->numParams( $file->getWidth(), $file->getHeight() )->escaped();
+
+ return "$widthheight ($nbytes)";
+ }
+
+ /**
+ * @param $file File
+ * @return string
+ */
+ function getLongDesc( $file ) {
+ global $wgLang;
+ $pages = $file->pageCount();
+ $size = htmlspecialchars( $wgLang->formatSize( $file->getSize() ) );
+ if ( $pages === false || $pages <= 1 ) {
+ $msg = wfMessage( 'file-info-size' )->numParams( $file->getWidth(),
+ $file->getHeight() )->params( $size,
+ $file->getMimeType() )->parse();
+ } else {
+ $msg = wfMessage( 'file-info-size-pages' )->numParams( $file->getWidth(),
+ $file->getHeight() )->params( $size,
+ $file->getMimeType() )->numParams( $pages )->parse();
+ }
+ return $msg;
+ }
+
+ /**
+ * @param $file File
+ * @return string
+ */
+ function getDimensionsString( $file ) {
+ $pages = $file->pageCount();
+ if ( $pages > 1 ) {
+ return wfMessage( 'widthheightpage' )->numParams( $file->getWidth(), $file->getHeight(), $pages )->text();
+ } else {
+ return wfMessage( 'widthheight' )->numParams( $file->getWidth(), $file->getHeight() )->text();
+ }
+ }
+}
diff --git a/includes/media/Jpeg.php b/includes/media/Jpeg.php
index 7033409b..a15b6524 100644
--- a/includes/media/Jpeg.php
+++ b/includes/media/Jpeg.php
@@ -1,5 +1,22 @@
<?php
/**
+ * Handler for JPEG images.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
* @file
* @ingroup Media
*/
diff --git a/includes/media/JpegMetadataExtractor.php b/includes/media/JpegMetadataExtractor.php
index 224b4a2b..8d7e43b9 100644
--- a/includes/media/JpegMetadataExtractor.php
+++ b/includes/media/JpegMetadataExtractor.php
@@ -1,10 +1,34 @@
<?php
/**
-* Class for reading jpegs and extracting metadata.
-* see also BitmapMetadataHandler.
-*
-* Based somewhat on GIFMetadataExtrator.
-*/
+ * Extraction of JPEG image metadata.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @ingroup Media
+ */
+
+/**
+ * Class for reading jpegs and extracting metadata.
+ * see also BitmapMetadataHandler.
+ *
+ * Based somewhat on GIFMetadataExtrator.
+ *
+ * @ingroup Media
+ */
class JpegMetadataExtractor {
const MAX_JPEG_SEGMENTS = 200;
@@ -143,13 +167,17 @@ class JpegMetadataExtractor {
/**
* Helper function for jpegSegmentSplitter
* @param &$fh FileHandle for jpeg file
- * @return data content of segment.
+ * @return string data content of segment.
*/
private static function jpegExtractMarker( &$fh ) {
$size = wfUnpack( "nint", fread( $fh, 2 ), 2 );
- if ( $size['int'] <= 2 ) throw new MWException( "invalid marker size in jpeg" );
+ if ( $size['int'] <= 2 ) {
+ throw new MWException( "invalid marker size in jpeg" );
+ }
$segment = fread( $fh, $size['int'] - 2 );
- if ( strlen( $segment ) !== $size['int'] - 2 ) throw new MWException( "Segment shorter than expected" );
+ if ( strlen( $segment ) !== $size['int'] - 2 ) {
+ throw new MWException( "Segment shorter than expected" );
+ }
return $segment;
}
diff --git a/includes/media/Generic.php b/includes/media/MediaHandler.php
index 271d3a8d..965099fd 100644
--- a/includes/media/Generic.php
+++ b/includes/media/MediaHandler.php
@@ -1,6 +1,21 @@
<?php
/**
- * Media-handling base classes and generic functionality
+ * Media-handling base classes and generic functionality.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
*
* @file
* @ingroup Media
@@ -160,6 +175,7 @@ abstract class MediaHandler {
* MediaHandler::METADATA_GOOD for if the metadata is a-ok,
* MediaHanlder::METADATA_COMPATIBLE if metadata is old but backwards
* compatible (which may or may not trigger a metadata reload).
+ * @return bool
*/
function isMetadataValid( $image, $metadata ) {
return self::METADATA_GOOD;
@@ -173,6 +189,7 @@ abstract class MediaHandler {
* Used when the repository has a thumbnailScriptUrl option configured.
*
* Return false to fall back to the regular getTransform().
+ * @return bool
*/
function getScriptedTransform( $image, $script, $params ) {
return false;
@@ -186,6 +203,7 @@ abstract class MediaHandler {
* @param $dstPath String: filesystem destination path
* @param $dstUrl String: Destination URL to use in output HTML
* @param $params Array: Arbitrary set of parameters validated by $this->validateParam()
+ * @return MediaTransformOutput
*/
final function getTransform( $image, $dstPath, $dstUrl, $params ) {
return $this->doTransform( $image, $dstPath, $dstUrl, $params, self::TRANSFORM_LATER );
@@ -227,27 +245,46 @@ abstract class MediaHandler {
/**
* True if the handled types can be transformed
+ * @return bool
*/
function canRender( $file ) { return true; }
/**
* True if handled types cannot be displayed directly in a browser
* but can be rendered
+ * @return bool
*/
function mustRender( $file ) { return false; }
/**
* True if the type has multi-page capabilities
+ * @return bool
*/
function isMultiPage( $file ) { return false; }
/**
* Page count for a multi-page document, false if unsupported or unknown
+ * @return bool
*/
function pageCount( $file ) { return false; }
/**
* The material is vectorized and thus scaling is lossless
+ * @return bool
*/
function isVectorized( $file ) { return false; }
/**
+ * The material is an image, and is animated.
+ * In particular, video material need not return true.
+ * @note Before 1.20, this was a method of ImageHandler only
+ * @return bool
+ */
+ function isAnimatedImage( $file ) { return false; }
+ /**
+ * If the material is animated, we can animate the thumbnail
+ * @since 1.20
+ * @return bool If material is not animated, handler may return any value.
+ */
+ function canAnimateThumbnail( $file ) { return true; }
+ /**
* False if the handler is disabled for all files
+ * @return bool
*/
function isEnabled() { return true; }
@@ -258,6 +295,8 @@ abstract class MediaHandler {
* Returns false if unknown or if the document is not multi-page.
*
* @param $image File
+ * @param $page Unused, left for backcompatibility?
+ * @return array
*/
function getPageDimensions( $image, $page ) {
$gis = $this->getImageSize( $image, $image->getLocalRefPath() );
@@ -270,6 +309,7 @@ abstract class MediaHandler {
/**
* Generic getter for text layer.
* Currently overloaded by PDF and DjVu handlers
+ * @return bool
*/
function getPageText( $image, $page ) {
return false;
@@ -300,6 +340,7 @@ abstract class MediaHandler {
* all the formatting according to some standard. That makes it possible
* to do things like visual indication of grouped and chained streams
* in ogg container files.
+ * @return bool
*/
function formatMetadata( $image ) {
return false;
@@ -344,7 +385,7 @@ abstract class MediaHandler {
*/
function visibleMetadataFields() {
$fields = array();
- $lines = explode( "\n", wfMsgForContent( 'metadata-fields' ) );
+ $lines = explode( "\n", wfMessage( 'metadata-fields' )->inContentLanguage()->text() );
foreach( $lines as $line ) {
$matches = array();
if( preg_match( '/^\\*\s*(.*?)\s*$/', $line, $matches ) ) {
@@ -471,7 +512,7 @@ abstract class MediaHandler {
* match the handler class, a Status object should be returned containing
* relevant errors.
*
- * @param $fileName The local path to the file.
+ * @param $fileName string The local path to the file.
* @return Status object
*/
function verifyUpload( $fileName ) {
@@ -482,9 +523,9 @@ abstract class MediaHandler {
* Check for zero-sized thumbnails. These can be generated when
* no disk space is available or some other error occurs
*
- * @param $dstPath The location of the suspect file
- * @param $retval Return value of some shell process, file will be deleted if this is non-zero
- * @return true if removed, false otherwise
+ * @param $dstPath string The location of the suspect file
+ * @param $retval int Return value of some shell process, file will be deleted if this is non-zero
+ * @return bool True if removed, false otherwise
*/
function removeBadFile( $dstPath, $retval = 0 ) {
if( file_exists( $dstPath ) ) {
@@ -509,7 +550,7 @@ abstract class MediaHandler {
/**
* Remove files from the purge list
- *
+ *
* @param array $files
* @param array $options
*/
@@ -517,235 +558,3 @@ abstract class MediaHandler {
// Do nothing
}
}
-
-/**
- * Media handler abstract base class for images
- *
- * @ingroup Media
- */
-abstract class ImageHandler extends MediaHandler {
-
- /**
- * @param $file File
- * @return bool
- */
- function canRender( $file ) {
- return ( $file->getWidth() && $file->getHeight() );
- }
-
- function getParamMap() {
- return array( 'img_width' => 'width' );
- }
-
- function validateParam( $name, $value ) {
- if ( in_array( $name, array( 'width', 'height' ) ) ) {
- if ( $value <= 0 ) {
- return false;
- } else {
- return true;
- }
- } else {
- return false;
- }
- }
-
- function makeParamString( $params ) {
- if ( isset( $params['physicalWidth'] ) ) {
- $width = $params['physicalWidth'];
- } elseif ( isset( $params['width'] ) ) {
- $width = $params['width'];
- } else {
- throw new MWException( 'No width specified to '.__METHOD__ );
- }
- # Removed for ProofreadPage
- #$width = intval( $width );
- return "{$width}px";
- }
-
- function parseParamString( $str ) {
- $m = false;
- if ( preg_match( '/^(\d+)px$/', $str, $m ) ) {
- return array( 'width' => $m[1] );
- } else {
- return false;
- }
- }
-
- function getScriptParams( $params ) {
- return array( 'width' => $params['width'] );
- }
-
- /**
- * @param $image File
- * @param $params
- * @return bool
- */
- function normaliseParams( $image, &$params ) {
- $mimeType = $image->getMimeType();
-
- if ( !isset( $params['width'] ) ) {
- return false;
- }
-
- if ( !isset( $params['page'] ) ) {
- $params['page'] = 1;
- } else {
- if ( $params['page'] > $image->pageCount() ) {
- $params['page'] = $image->pageCount();
- }
-
- if ( $params['page'] < 1 ) {
- $params['page'] = 1;
- }
- }
-
- $srcWidth = $image->getWidth( $params['page'] );
- $srcHeight = $image->getHeight( $params['page'] );
-
- if ( isset( $params['height'] ) && $params['height'] != -1 ) {
- # Height & width were both set
- if ( $params['width'] * $srcHeight > $params['height'] * $srcWidth ) {
- # Height is the relative smaller dimension, so scale width accordingly
- $params['width'] = self::fitBoxWidth( $srcWidth, $srcHeight, $params['height'] );
-
- if ( $params['width'] == 0 ) {
- # Very small image, so we need to rely on client side scaling :(
- $params['width'] = 1;
- }
-
- $params['physicalWidth'] = $params['width'];
- } else {
- # Height was crap, unset it so that it will be calculated later
- unset( $params['height'] );
- }
- }
-
- if ( !isset( $params['physicalWidth'] ) ) {
- # Passed all validations, so set the physicalWidth
- $params['physicalWidth'] = $params['width'];
- }
-
- # Because thumbs are only referred to by width, the height always needs
- # to be scaled by the width to keep the thumbnail sizes consistent,
- # even if it was set inside the if block above
- $params['physicalHeight'] = File::scaleHeight( $srcWidth, $srcHeight,
- $params['physicalWidth'] );
-
- # Set the height if it was not validated in the if block higher up
- if ( !isset( $params['height'] ) || $params['height'] == -1 ) {
- $params['height'] = $params['physicalHeight'];
- }
-
-
- if ( !$this->validateThumbParams( $params['physicalWidth'],
- $params['physicalHeight'], $srcWidth, $srcHeight, $mimeType ) ) {
- return false;
- }
- return true;
- }
-
- /**
- * Validate thumbnail parameters and fill in the correct height
- *
- * @param $width Integer: specified width (input/output)
- * @param $height Integer: height (output only)
- * @param $srcWidth Integer: width of the source image
- * @param $srcHeight Integer: height of the source image
- * @param $mimeType Unused
- * @return false to indicate that an error should be returned to the user.
- */
- function validateThumbParams( &$width, &$height, $srcWidth, $srcHeight, $mimeType ) {
- $width = intval( $width );
-
- # Sanity check $width
- if( $width <= 0) {
- wfDebug( __METHOD__.": Invalid destination width: $width\n" );
- return false;
- }
- if ( $srcWidth <= 0 ) {
- wfDebug( __METHOD__.": Invalid source width: $srcWidth\n" );
- return false;
- }
-
- $height = File::scaleHeight( $srcWidth, $srcHeight, $width );
- if ( $height == 0 ) {
- # Force height to be at least 1 pixel
- $height = 1;
- }
- return true;
- }
-
- /**
- * @param $image File
- * @param $script
- * @param $params
- * @return bool|ThumbnailImage
- */
- function getScriptedTransform( $image, $script, $params ) {
- if ( !$this->normaliseParams( $image, $params ) ) {
- return false;
- }
- $url = $script . '&' . wfArrayToCGI( $this->getScriptParams( $params ) );
- $page = isset( $params['page'] ) ? $params['page'] : false;
-
- if( $image->mustRender() || $params['width'] < $image->getWidth() ) {
- return new ThumbnailImage( $image, $url, $params['width'], $params['height'], $page );
- }
- }
-
- function getImageSize( $image, $path ) {
- wfSuppressWarnings();
- $gis = getimagesize( $path );
- wfRestoreWarnings();
- return $gis;
- }
-
- function isAnimatedImage( $image ) {
- return false;
- }
-
- /**
- * @param $file File
- * @return string
- */
- function getShortDesc( $file ) {
- global $wgLang;
- $nbytes = htmlspecialchars( $wgLang->formatSize( $file->getSize() ) );
- $widthheight = wfMessage( 'widthheight' )->numParams( $file->getWidth(), $file->getHeight() )->escaped();
-
- return "$widthheight ($nbytes)";
- }
-
- /**
- * @param $file File
- * @return string
- */
- function getLongDesc( $file ) {
- global $wgLang;
- $pages = $file->pageCount();
- $size = htmlspecialchars( $wgLang->formatSize( $file->getSize() ) );
- if ( $pages === false || $pages <= 1 ) {
- $msg = wfMessage( 'file-info-size' )->numParams( $file->getWidth(),
- $file->getHeight() )->params( $size,
- $file->getMimeType() )->parse();
- } else {
- $msg = wfMessage( 'file-info-size-pages' )->numParams( $file->getWidth(),
- $file->getHeight() )->params( $size,
- $file->getMimeType() )->numParams( $pages )->parse();
- }
- return $msg;
- }
-
- /**
- * @param $file File
- * @return string
- */
- function getDimensionsString( $file ) {
- $pages = $file->pageCount();
- if ( $pages > 1 ) {
- return wfMessage( 'widthheightpage' )->numParams( $file->getWidth(), $file->getHeight(), $pages )->text();
- } else {
- return wfMessage( 'widthheight' )->numParams( $file->getWidth(), $file->getHeight() )->text();
- }
- }
-}
diff --git a/includes/media/MediaTransformOutput.php b/includes/media/MediaTransformOutput.php
index fcfb2f45..773824cb 100644
--- a/includes/media/MediaTransformOutput.php
+++ b/includes/media/MediaTransformOutput.php
@@ -2,6 +2,21 @@
/**
* Base class for the output of file transformation methods.
*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
* @file
* @ingroup Media
*/
@@ -21,28 +36,37 @@ abstract class MediaTransformOutput {
protected $storagePath = false;
/**
- * Get the width of the output box
+ * @return integer Width of the output box
*/
public function getWidth() {
return $this->width;
}
/**
- * Get the height of the output box
+ * @return integer Height of the output box
*/
public function getHeight() {
return $this->height;
}
/**
- * @return string The thumbnail URL
+ * Get the final extension of the thumbnail.
+ * Returns false for scripted transformations.
+ * @return string|false
+ */
+ public function getExtension() {
+ return $this->path ? FileBackend::extensionFromPath( $this->path ) : false;
+ }
+
+ /**
+ * @return string|false The thumbnail URL
*/
public function getUrl() {
return $this->url;
}
/**
- * @return string|false The permanent thumbnail storage path
+ * @return string|bool The permanent thumbnail storage path
*/
public function getStoragePath() {
return $this->storagePath;
@@ -69,7 +93,7 @@ abstract class MediaTransformOutput {
* custom-url-link Custom URL to link to
* custom-title-link Custom Title object to link to
* valign vertical-align property, if the output is an inline element
- * img-class Class applied to the <img> tag, if there is such a tag
+ * img-class Class applied to the "<img>" tag, if there is such a tag
*
* For images, desc-link and file-link are implemented as a click-through. For
* sounds and videos, they may be displayed in other ways.
@@ -80,6 +104,7 @@ abstract class MediaTransformOutput {
/**
* This will be overridden to return true in error classes
+ * @return bool
*/
public function isError() {
return false;
@@ -90,7 +115,7 @@ abstract class MediaTransformOutput {
* This will return false if there was an error, the
* thumbnail is to be handled client-side only, or if
* transformation was deferred via TRANSFORM_LATER.
- *
+ *
* @return Bool
*/
public function hasFile() {
@@ -113,7 +138,7 @@ abstract class MediaTransformOutput {
* Get the path of a file system copy of the thumbnail.
* Callers should never write to this path.
*
- * @return string|false Returns false if there isn't one
+ * @return string|bool Returns false if there isn't one
*/
public function getLocalCopyPath() {
if ( $this->isError() ) {
@@ -132,7 +157,14 @@ abstract class MediaTransformOutput {
* @return Bool success
*/
public function streamFile( $headers = array() ) {
- return $this->path && StreamFile::stream( $this->getLocalCopyPath(), $headers );
+ if ( !$this->path ) {
+ return false;
+ } elseif ( FileBackend::isStoragePath( $this->path ) ) {
+ $be = $this->file->getRepo()->getBackend();
+ return $be->streamFile( array( 'src' => $this->path, 'headers' => $headers ) )->isOK();
+ } else { // FS-file
+ return StreamFile::stream( $this->getLocalCopyPath(), $headers );
+ }
}
/**
@@ -182,25 +214,46 @@ class ThumbnailImage extends MediaTransformOutput {
* Get a thumbnail object from a file and parameters.
* If $path is set to null, the output file is treated as a source copy.
* If $path is set to false, no output file will be created.
- *
+ * $parameters should include, as a minimum, (file) 'width' and 'height'.
+ * It may also include a 'page' parameter for multipage files.
+ *
* @param $file File object
* @param $url String: URL path to the thumb
- * @param $width Integer: file's width
- * @param $height Integer: file's height
- * @param $path String|false|null: filesystem path to the thumb
- * @param $page Integer: page number, for multipage files
+ * @param $path String|bool|null: filesystem path to the thumb
+ * @param $parameters Array: Associative array of parameters
* @private
*/
- function __construct( $file, $url, $width, $height, $path = false, $page = false ) {
+ function __construct( $file, $url, $path = false, $parameters = array() ) {
+ # Previous parameters:
+ # $file, $url, $width, $height, $path = false, $page = false
+
+ if( is_array( $parameters ) ){
+ $defaults = array(
+ 'page' => false
+ );
+ $actualParams = $parameters + $defaults;
+ } else {
+ # Using old format, should convert. Later a warning could be added here.
+ $numArgs = func_num_args();
+ $actualParams = array(
+ 'width' => $path,
+ 'height' => $parameters,
+ 'page' => ( $numArgs > 5 ) ? func_get_arg( 5 ) : false
+ );
+ $path = ( $numArgs > 4 ) ? func_get_arg( 4 ) : false;
+ }
+
$this->file = $file;
$this->url = $url;
+ $this->path = $path;
+
# These should be integers when they get here.
# If not, there's a bug somewhere. But let's at
# least produce valid HTML code regardless.
- $this->width = round( $width );
- $this->height = round( $height );
- $this->path = $path;
- $this->page = $page;
+ $this->width = round( $actualParams['width'] );
+ $this->height = round( $actualParams['height'] );
+
+ $this->page = $actualParams['page'];
}
/**
@@ -221,6 +274,9 @@ class ThumbnailImage extends MediaTransformOutput {
* custom-url-link Custom URL to link to
* custom-title-link Custom Title object to link to
* custom target-link Value of the target attribute, for custom-target-link
+ * parser-extlink-* Attributes added by parser for external links:
+ * parser-extlink-rel: add rel="nofollow"
+ * parser-extlink-target: link target, but overridden by custom-target-link
*
* For images, desc-link and file-link are implemented as a click-through. For
* sounds and videos, they may be displayed in other ways.
@@ -243,6 +299,11 @@ class ThumbnailImage extends MediaTransformOutput {
}
if ( !empty( $options['custom-target-link'] ) ) {
$linkAttribs['target'] = $options['custom-target-link'];
+ } elseif ( !empty( $options['parser-extlink-target'] ) ) {
+ $linkAttribs['target'] = $options['parser-extlink-target'];
+ }
+ if ( !empty( $options['parser-extlink-rel'] ) ) {
+ $linkAttribs['rel'] = $options['parser-extlink-rel'];
}
} elseif ( !empty( $options['custom-title-link'] ) ) {
$title = $options['custom-title-link'];
@@ -326,6 +387,6 @@ class TransformParameterError extends MediaTransformError {
parent::__construct( 'thumbnail_error',
max( isset( $params['width'] ) ? $params['width'] : 0, 120 ),
max( isset( $params['height'] ) ? $params['height'] : 0, 120 ),
- wfMsg( 'thumbnail_invalid_params' ) );
+ wfMessage( 'thumbnail_invalid_params' )->text() );
}
}
diff --git a/includes/media/PNG.php b/includes/media/PNG.php
index 8fe9ecb4..1b329e57 100644
--- a/includes/media/PNG.php
+++ b/includes/media/PNG.php
@@ -2,6 +2,21 @@
/**
* Handler for PNG images.
*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
* @file
* @ingroup Media
*/
@@ -65,6 +80,14 @@ class PNGHandler extends BitmapHandler {
}
return false;
}
+ /**
+ * We do not support making APNG thumbnails, so always false
+ * @param $image File
+ * @return bool false
+ */
+ function canAnimateThumbnail( $image ) {
+ return false;
+ }
function getMetadataType( $image ) {
return 'parsed-png';
@@ -113,13 +136,13 @@ class PNGHandler extends BitmapHandler {
$info[] = $original;
if ( $metadata['loopCount'] == 0 ) {
- $info[] = wfMsgExt( 'file-info-png-looped', 'parseinline' );
+ $info[] = wfMessage( 'file-info-png-looped' )->parse();
} elseif ( $metadata['loopCount'] > 1 ) {
- $info[] = wfMsgExt( 'file-info-png-repeat', 'parseinline', $metadata['loopCount'] );
+ $info[] = wfMessage( 'file-info-png-repeat' )->numParams( $metadata['loopCount'] )->parse();
}
if ( $metadata['frameCount'] > 0 ) {
- $info[] = wfMsgExt( 'file-info-png-frames', 'parseinline', $metadata['frameCount'] );
+ $info[] = wfMessage( 'file-info-png-frames' )->numParams( $metadata['frameCount'] )->parse();
}
if ( $metadata['duration'] ) {
diff --git a/includes/media/PNGMetadataExtractor.php b/includes/media/PNGMetadataExtractor.php
index d3c44d4f..9dcde406 100644
--- a/includes/media/PNGMetadataExtractor.php
+++ b/includes/media/PNGMetadataExtractor.php
@@ -1,10 +1,26 @@
<?php
/**
* PNG frame counter and metadata extractor.
+ *
* Slightly derived from GIFMetadataExtractor.php
* Deliberately not using MWExceptions to avoid external dependencies, encouraging
* redistribution.
*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
* @file
* @ingroup Media
*/
diff --git a/includes/media/SVG.php b/includes/media/SVG.php
index aac838e1..55fa5547 100644
--- a/includes/media/SVG.php
+++ b/includes/media/SVG.php
@@ -2,6 +2,21 @@
/**
* Handler for SVG images.
*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
* @file
* @ingroup Media
*/
@@ -49,6 +64,13 @@ class SvgHandler extends ImageHandler {
}
/**
+ * We do not support making animated svg thumbnails
+ */
+ function canAnimateThumb( $file ) {
+ return false;
+ }
+
+ /**
* @param $image File
* @param $params
* @return bool
@@ -93,20 +115,20 @@ class SvgHandler extends ImageHandler {
$clientHeight = $params['height'];
$physicalWidth = $params['physicalWidth'];
$physicalHeight = $params['physicalHeight'];
- $srcPath = $image->getLocalRefPath();
if ( $flags & self::TRANSFORM_LATER ) {
- return new ThumbnailImage( $image, $dstUrl, $clientWidth, $clientHeight, $dstPath );
+ return new ThumbnailImage( $image, $dstUrl, $dstPath, $params );
}
if ( !wfMkdirParents( dirname( $dstPath ), null, __METHOD__ ) ) {
return new MediaTransformError( 'thumbnail_error', $clientWidth, $clientHeight,
- wfMsg( 'thumbnail_dest_directory' ) );
+ wfMessage( 'thumbnail_dest_directory' )->text() );
}
+ $srcPath = $image->getLocalRefPath();
$status = $this->rasterize( $srcPath, $dstPath, $physicalWidth, $physicalHeight );
if( $status === true ) {
- return new ThumbnailImage( $image, $dstUrl, $clientWidth, $clientHeight, $dstPath );
+ return new ThumbnailImage( $image, $dstUrl, $dstPath, $params );
} else {
return $status; // MediaTransformError
}
@@ -119,7 +141,7 @@ class SvgHandler extends ImageHandler {
* @param string $dstPath
* @param string $width
* @param string $height
- * @return true|MediaTransformError
+ * @return bool|MediaTransformError
*/
public function rasterize( $srcPath, $dstPath, $width, $height ) {
global $wgSVGConverters, $wgSVGConverter, $wgSVGConverterPath;
@@ -199,15 +221,30 @@ class SvgHandler extends ImageHandler {
}
/**
+ * Subtitle for the image. Different from the base
+ * class so it can be denoted that SVG's have
+ * a "nominal" resolution, and not a fixed one,
+ * as well as so animation can be denoted.
+ *
* @param $file File
* @return string
*/
function getLongDesc( $file ) {
global $wgLang;
- return wfMsgExt( 'svg-long-desc', 'parseinline',
- $wgLang->formatNum( $file->getWidth() ),
- $wgLang->formatNum( $file->getHeight() ),
- $wgLang->formatSize( $file->getSize() ) );
+ $size = $wgLang->formatSize( $file->getSize() );
+
+ if ( $this->isAnimatedImage( $file ) ) {
+ $msg = wfMessage( 'svg-long-desc-animated' );
+ } else {
+ $msg = wfMessage( 'svg-long-desc' );
+ }
+
+ $msg->numParams(
+ $file->getWidth(),
+ $file->getHeight()
+ );
+ $msg->Params( $size );
+ return $msg->parse();
}
function getMetadata( $file, $filename ) {
@@ -238,11 +275,19 @@ class SvgHandler extends ImageHandler {
}
function isMetadataValid( $image, $metadata ) {
- return $this->unpackMetadata( $metadata ) !== false;
+ $meta = $this->unpackMetadata( $metadata );
+ if ( $meta === false ) {
+ return self::METADATA_BAD;
+ }
+ if ( !isset( $meta['originalWidth'] ) ) {
+ // Old but compatible
+ return self::METADATA_COMPATIBLE;
+ }
+ return self::METADATA_GOOD;
}
function visibleMetadataFields() {
- $fields = array( 'title', 'description', 'animated' );
+ $fields = array( 'objectname', 'imagedescription' );
return $fields;
}
@@ -263,8 +308,6 @@ class SvgHandler extends ImageHandler {
if ( !$metadata ) {
return false;
}
- unset( $metadata['version'] );
- unset( $metadata['metadata'] ); /* non-formatted XML */
/* TODO: add a formatter
$format = new FormatSVG( $metadata );
@@ -275,9 +318,10 @@ class SvgHandler extends ImageHandler {
$visibleFields = $this->visibleMetadataFields();
// Rename fields to be compatible with exif, so that
- // the labels for these fields work.
- $conversion = array( 'width' => 'imagewidth',
- 'height' => 'imagelength',
+ // the labels for these fields work and reuse existing messages.
+ $conversion = array(
+ 'originalwidth' => 'imagewidth',
+ 'originalheight' => 'imagelength',
'description' => 'imagedescription',
'title' => 'objectname',
);
@@ -285,6 +329,9 @@ class SvgHandler extends ImageHandler {
$tag = strtolower( $name );
if ( isset( $conversion[$tag] ) ) {
$tag = $conversion[$tag];
+ } else {
+ // Do not output other metadata not in list
+ continue;
}
self::addMeta( $result,
in_array( $tag, $visibleFields ) ? 'visible' : 'collapsed',
diff --git a/includes/media/SVGMetadataExtractor.php b/includes/media/SVGMetadataExtractor.php
index db9f05fd..851fe428 100644
--- a/includes/media/SVGMetadataExtractor.php
+++ b/includes/media/SVGMetadataExtractor.php
@@ -1,6 +1,6 @@
<?php
/**
- * SVGMetadataExtractor.php
+ * Extraction of SVG image metadata.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -19,12 +19,15 @@
*
* @file
* @ingroup Media
- * @author Derk-Jan Hartman <hartman _at_ videolan d0t org>
+ * @author "Derk-Jan Hartman <hartman _at_ videolan d0t org>"
* @author Brion Vibber
* @copyright Copyright © 2010-2010 Brion Vibber, Derk-Jan Hartman
* @license http://www.gnu.org/copyleft/gpl.html GNU General Public License
*/
+/**
+ * @ingroup Media
+ */
class SVGMetadataExtractor {
static function getMetadata( $filename ) {
$svg = new SVGReader( $filename );
@@ -32,6 +35,9 @@ class SVGMetadataExtractor {
}
}
+/**
+ * @ingroup Media
+ */
class SVGReader {
const DEFAULT_WIDTH = 512;
const DEFAULT_HEIGHT = 512;
@@ -77,6 +83,12 @@ class SVGReader {
$this->metadata['width'] = self::DEFAULT_WIDTH;
$this->metadata['height'] = self::DEFAULT_HEIGHT;
+ // The size in the units specified by the SVG file
+ // (for the metadata box)
+ // Per the SVG spec, if unspecified, default to '100%'
+ $this->metadata['originalWidth'] = '100%';
+ $this->metadata['originalHeight'] = '100%';
+
// Because we cut off the end of the svg making an invalid one. Complicated
// try catch thing to make sure warnings get restored. Seems like there should
// be a better way.
@@ -84,6 +96,8 @@ class SVGReader {
try {
$this->read();
} catch( Exception $e ) {
+ // Note, if this happens, the width/height will be taken to be 0x0.
+ // Should we consider it the default 512x512 instead?
wfRestoreWarnings();
throw $e;
}
@@ -99,6 +113,7 @@ class SVGReader {
/**
* Read the SVG
+ * @return bool
*/
public function read() {
$keepReading = $this->reader->read();
@@ -132,6 +147,11 @@ class SVGReader {
$this->readField( $tag, 'description' );
} elseif ( $isSVG && $tag == 'metadata' && $type == XmlReader::ELEMENT ) {
$this->readXml( $tag, 'metadata' );
+ } elseif ( $isSVG && $tag == 'script' ) {
+ // We normally do not allow scripted svgs.
+ // However its possible to configure MW to let them
+ // in, and such files should be considered animated.
+ $this->metadata['animated'] = true;
} elseif ( $tag !== '#text' ) {
$this->debug( "Unhandled top-level XML tag $tag" );
@@ -212,6 +232,11 @@ class SVGReader {
break;
} elseif ( $this->reader->namespaceURI == self::NS_SVG && $this->reader->nodeType == XmlReader::ELEMENT ) {
switch( $this->reader->localName ) {
+ case 'script':
+ // Normally we disallow files with
+ // <script>, but its possible
+ // to configure MW to disable
+ // such checks.
case 'animate':
case 'set':
case 'animateMotion':
@@ -248,7 +273,7 @@ class SVGReader {
/**
* Parse the attributes of an SVG element
*
- * The parser has to be in the start element of <svg>
+ * The parser has to be in the start element of "<svg>"
*/
private function handleSVGAttribs( ) {
$defaultWidth = self::DEFAULT_WIDTH;
@@ -271,9 +296,11 @@ class SVGReader {
}
if( $this->reader->getAttribute('width') ) {
$width = $this->scaleSVGUnit( $this->reader->getAttribute('width'), $defaultWidth );
+ $this->metadata['originalWidth'] = $this->reader->getAttribute( 'width' );
}
if( $this->reader->getAttribute('height') ) {
$height = $this->scaleSVGUnit( $this->reader->getAttribute('height'), $defaultHeight );
+ $this->metadata['originalHeight'] = $this->reader->getAttribute( 'height' );
}
if( !isset( $width ) && !isset( $height ) ) {
diff --git a/includes/media/Tiff.php b/includes/media/Tiff.php
index 0f317e1a..d95c9074 100644
--- a/includes/media/Tiff.php
+++ b/includes/media/Tiff.php
@@ -2,6 +2,21 @@
/**
* Handler for Tiff images.
*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
* @file
* @ingroup Media
*/
diff --git a/includes/media/XCF.php b/includes/media/XCF.php
index 806db73c..555fa1fb 100644
--- a/includes/media/XCF.php
+++ b/includes/media/XCF.php
@@ -7,6 +7,21 @@
* Specification in Gnome repository:
* http://svn.gnome.org/viewvc/gimp/trunk/devel-docs/xcf.txt?view=markup
*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
* @file
* @ingroup Media
*/
@@ -58,7 +73,7 @@ class XCFHandler extends BitmapHandler {
* @author Hashar
*
* @param $filename String Full path to a XCF file
- * @return false|metadata array just like PHP getimagesize()
+ * @return bool|array metadata array just like PHP getimagesize()
*/
static function getXCFMetaData( $filename ) {
# Decode master structure
diff --git a/includes/media/XMP.php b/includes/media/XMP.php
index 0dbf5632..36660b3d 100644
--- a/includes/media/XMP.php
+++ b/includes/media/XMP.php
@@ -1,5 +1,27 @@
<?php
/**
+ * Reader for XMP data containing properties relevant to images.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @ingroup Media
+ */
+
+/**
* Class for reading xmp data containing properties relevant to
* images, and spitting out an array that FormatExif accepts.
*
@@ -191,10 +213,16 @@ class XMPReader {
unset( $data['xmp-special'] );
// Convert GPSAltitude to negative if below sea level.
- if ( isset( $data['xmp-exif']['GPSAltitudeRef'] ) ) {
- if ( $data['xmp-exif']['GPSAltitudeRef'] == '1'
- && isset( $data['xmp-exif']['GPSAltitude'] )
- ) {
+ if ( isset( $data['xmp-exif']['GPSAltitudeRef'] )
+ && isset( $data['xmp-exif']['GPSAltitude'] )
+ ) {
+
+ // Must convert to a real before multiplying by -1
+ // XMPValidate guarantees there will always be a '/' in this value.
+ list( $nom, $denom ) = explode( '/', $data['xmp-exif']['GPSAltitude'] );
+ $data['xmp-exif']['GPSAltitude'] = $nom / $denom;
+
+ if ( $data['xmp-exif']['GPSAltitudeRef'] == '1' ) {
$data['xmp-exif']['GPSAltitude'] *= -1;
}
unset( $data['xmp-exif']['GPSAltitudeRef'] );
@@ -439,13 +467,15 @@ class XMPReader {
* generally means we've finished processing a nested structure.
* resets some internal variables to indicate that.
*
- * Note this means we hit the </closing element> not the </rdf:Seq>.
+ * Note this means we hit the closing element not the "</rdf:Seq>".
*
- * For example, when processing:
+ * @par For example, when processing:
+ * @code{,xml}
* <exif:ISOSpeedRatings> <rdf:Seq> <rdf:li>64</rdf:li>
* </rdf:Seq> </exif:ISOSpeedRatings>
+ * @endcode
*
- * This method is called when we hit the </exif:ISOSpeedRatings> tag.
+ * This method is called when we hit the "</exif:ISOSpeedRatings>" tag.
*
* @param $elm String namespace . space . tag name.
*/
@@ -501,15 +531,17 @@ class XMPReader {
* Hit a closing element in MODE_LI (either rdf:Seq, or rdf:Bag )
* Add information about what type of element this is.
*
- * Note we still have to hit the outer </property>
+ * Note we still have to hit the outer "</property>"
*
- * For example, when processing:
+ * @par For example, when processing:
+ * @code{,xml}
* <exif:ISOSpeedRatings> <rdf:Seq> <rdf:li>64</rdf:li>
* </rdf:Seq> </exif:ISOSpeedRatings>
+ * @endcode
*
- * This method is called when we hit the </rdf:Seq>.
+ * This method is called when we hit the "</rdf:Seq>".
* (For comparison, we call endElementModeSimple when we
- * hit the </rdf:li>)
+ * hit the "</rdf:li>")
*
* @param $elm String namespace . ' ' . element name
*/
@@ -988,7 +1020,7 @@ class XMPReader {
* Also does some initial set up for the wrapper element
*
* @param $parser XMLParser
- * @param $elm String namespace <space> element
+ * @param $elm String namespace "<space>" element
* @param $attribs Array attribute name => value
*/
function startElement( $parser, $elm, $attribs ) {
@@ -1071,11 +1103,13 @@ class XMPReader {
* Process attributes.
* Simple values can be stored as either a tag or attribute
*
- * Often the initial <rdf:Description> tag just has all the simple
+ * Often the initial "<rdf:Description>" tag just has all the simple
* properties as attributes.
*
- * Example:
+ * @par Example:
+ * @code
* <rdf:Description rdf:about="" xmlns:exif="http://ns.adobe.com/exif/1.0/" exif:DigitalZoomRatio="0/10">
+ * @endcode
*
* @param $attribs Array attribute=>value array.
*/
diff --git a/includes/media/XMPInfo.php b/includes/media/XMPInfo.php
index 156d9b50..83b8a102 100644
--- a/includes/media/XMPInfo.php
+++ b/includes/media/XMPInfo.php
@@ -1,5 +1,27 @@
<?php
/**
+ * Definitions for XMPReader class.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @ingroup Media
+ */
+
+/**
* This class is just a container for a big array
* used by XMPReader to determine which XMP items to
* extract.
diff --git a/includes/media/XMPValidate.php b/includes/media/XMPValidate.php
index 600d99de..5ce3c00b 100644
--- a/includes/media/XMPValidate.php
+++ b/includes/media/XMPValidate.php
@@ -1,5 +1,27 @@
<?php
/**
+ * Methods for validating XMP properties.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @ingroup Media
+ */
+
+/**
* This contains some static methods for
* validating XMP properties. See XMPInfo and XMPReader classes.
*