summaryrefslogtreecommitdiff
path: root/includes/media/ExifBitmap.php
diff options
context:
space:
mode:
Diffstat (limited to 'includes/media/ExifBitmap.php')
-rw-r--r--includes/media/ExifBitmap.php78
1 files changed, 74 insertions, 4 deletions
diff --git a/includes/media/ExifBitmap.php b/includes/media/ExifBitmap.php
index f56a947f..5ba5c68c 100644
--- a/includes/media/ExifBitmap.php
+++ b/includes/media/ExifBitmap.php
@@ -30,6 +30,7 @@
class ExifBitmapHandler extends BitmapHandler {
const BROKEN_FILE = '-1'; // error extracting metadata
const OLD_BROKEN_FILE = '0'; // outdated error extracting metadata.
+ const SRGB_ICC_PROFILE_NAME = 'IEC 61966-2.1 Default RGB colour space - sRGB';
function convertMetadataVersion( $metadata, $version = 1 ) {
// basically flattens arrays.
@@ -100,9 +101,9 @@ class ExifBitmapHandler extends BitmapHandler {
if ( $metadata === self::BROKEN_FILE ) {
return self::METADATA_GOOD;
}
- wfSuppressWarnings();
+ MediaWiki\suppressWarnings();
$exif = unserialize( $metadata );
- wfRestoreWarnings();
+ MediaWiki\restoreWarnings();
if ( !isset( $exif['MEDIAWIKI_EXIF_VERSION'] )
|| $exif['MEDIAWIKI_EXIF_VERSION'] != Exif::version()
) {
@@ -224,9 +225,9 @@ class ExifBitmapHandler extends BitmapHandler {
if ( !$data ) {
return 0;
}
- wfSuppressWarnings();
+ MediaWiki\suppressWarnings();
$data = unserialize( $data );
- wfRestoreWarnings();
+ MediaWiki\restoreWarnings();
if ( isset( $data['Orientation'] ) ) {
# See http://sylvana.net/jpegcrop/exif_orientation.html
switch ( $data['Orientation'] ) {
@@ -243,4 +244,73 @@ class ExifBitmapHandler extends BitmapHandler {
return 0;
}
+
+ protected function transformImageMagick( $image, $params ) {
+ global $wgUseTinyRGBForJPGThumbnails;
+
+ $ret = parent::transformImageMagick( $image, $params );
+
+ if ( $ret ) {
+ return $ret;
+ }
+
+ if ( $params['mimeType'] === 'image/jpeg' && $wgUseTinyRGBForJPGThumbnails ) {
+ // T100976 If the profile embedded in the JPG is sRGB, swap it for the smaller
+ // (and free) TinyRGB
+
+ $this->swapICCProfile(
+ $params['dstPath'],
+ self::SRGB_ICC_PROFILE_NAME,
+ realpath( __DIR__ ) . '/tinyrgb.icc'
+ );
+ }
+
+ return false;
+ }
+
+ /**
+ * Swaps an embedded ICC profile for another, if found. Depends on exiftool, no-op if not installed.
+ * @param string $filepath File to be manipulated (will be overwritten)
+ * @param string $oldProfileString Exact name of color profile to look for (the one that will be replaced)
+ * @param string $profileFilepath ICC profile file to apply to the file
+ * @since 1.26
+ * @return bool
+ */
+ public function swapICCProfile( $filepath, $oldProfileString, $profileFilepath ) {
+ global $wgExiftool;
+
+ if ( !$wgExiftool || !is_executable( $wgExiftool ) ) {
+ return false;
+ }
+
+ $cmd = wfEscapeShellArg( $wgExiftool,
+ '-DeviceModelDesc',
+ '-S',
+ '-T',
+ $filepath
+ );
+
+ $output = wfShellExecWithStderr( $cmd, $retval );
+
+ if ( $retval !== 0 || strcasecmp( trim( $output ), $oldProfileString ) !== 0 ) {
+ // We can't establish that this file has the expected ICC profile, don't process it
+ return false;
+ }
+
+ $cmd = wfEscapeShellArg( $wgExiftool,
+ '-overwrite_original',
+ '-icc_profile<=' . $profileFilepath,
+ $filepath
+ );
+
+ $output = wfShellExecWithStderr( $cmd, $retval );
+
+ if ( $retval !== 0 ) {
+ $this->logErrorForExternalProcess( $retval, $output, $cmd );
+
+ return false;
+ }
+
+ return true;
+ }
}