function testTooBigMustRenderImage() { $file = new FakeDimensionFile(array(4000, 4000)); $file->mustRender = true; $handler = new BitmapHandler(); $params = array('width' => '5000'); // Still bigger than max size. $this->assertFalse($handler->normaliseParams($file, $params)); }
/** * * @dataProvider providerFiles */ function testRotationRendering($name, $type, $info, $thumbs) { if (!BitmapHandler::canRotate()) { $this->markTestSkipped("This test needs a rasterizer that can auto-rotate."); } foreach ($thumbs as $size => $out) { if (preg_match('/^(\\d+)px$/', $size, $matches)) { $params = array('width' => $matches[1]); } elseif (preg_match('/^(\\d+)x(\\d+)px$/', $size, $matches)) { $params = array('width' => $matches[1], 'height' => $matches[2]); } else { throw new MWException('bogus test data format ' . $size); } $file = $this->localFile($name, $type); $thumb = $file->transform($params, File::RENDER_NOW); $this->assertEquals($out[0], $thumb->getWidth(), "{$name}: thumb reported width check for {$size}"); $this->assertEquals($out[1], $thumb->getHeight(), "{$name}: thumb reported height check for {$size}"); $gis = getimagesize($thumb->getPath()); if ($out[0] > $info['width']) { // Physical image won't be scaled bigger than the original. $this->assertEquals($info['width'], $gis[0], "{$name}: thumb actual width check for {$size}"); $this->assertEquals($info['height'], $gis[1], "{$name}: thumb actual height check for {$size}"); } else { $this->assertEquals($out[0], $gis[0], "{$name}: thumb actual width check for {$size}"); $this->assertEquals($out[1], $gis[1], "{$name}: thumb actual height check for {$size}"); } } }
/** * @param ResourceLoaderContext $context * @return array */ protected function getConfig($context) { $hash = $context->getHash(); if (isset($this->configVars[$hash])) { return $this->configVars[$hash]; } global $wgLoadScript, $wgScript, $wgStylePath, $wgScriptExtension, $wgArticlePath, $wgScriptPath, $wgServer, $wgContLang, $wgVariantArticlePath, $wgActionPaths, $wgVersion, $wgEnableAPI, $wgEnableWriteAPI, $wgDBname, $wgSitename, $wgFileExtensions, $wgExtensionAssetsPath, $wgCookiePrefix, $wgResourceLoaderMaxQueryLength, $wgResourceLoaderStorageEnabled, $wgResourceLoaderStorageVersion, $wgSearchType; $mainPage = Title::newMainPage(); /** * Namespace related preparation * - wgNamespaceIds: Key-value pairs of all localized, canonical and aliases for namespaces. * - wgCaseSensitiveNamespaces: Array of namespaces that are case-sensitive. */ $namespaceIds = $wgContLang->getNamespaceIds(); $caseSensitiveNamespaces = array(); foreach (MWNamespace::getCanonicalNamespaces() as $index => $name) { $namespaceIds[$wgContLang->lc($name)] = $index; if (!MWNamespace::isCapitalized($index)) { $caseSensitiveNamespaces[] = $index; } } // Build list of variables $vars = array('wgLoadScript' => $wgLoadScript, 'debug' => $context->getDebug(), 'skin' => $context->getSkin(), 'stylepath' => $wgStylePath, 'wgUrlProtocols' => wfUrlProtocols(), 'wgArticlePath' => $wgArticlePath, 'wgScriptPath' => $wgScriptPath, 'wgScriptExtension' => $wgScriptExtension, 'wgScript' => $wgScript, 'wgSearchType' => $wgSearchType, 'wgVariantArticlePath' => $wgVariantArticlePath, 'wgActionPaths' => (object) $wgActionPaths, 'wgServer' => $wgServer, 'wgUserLanguage' => $context->getLanguage(), 'wgContentLanguage' => $wgContLang->getCode(), 'wgVersion' => $wgVersion, 'wgEnableAPI' => $wgEnableAPI, 'wgEnableWriteAPI' => $wgEnableWriteAPI, 'wgMainPageTitle' => $mainPage->getPrefixedText(), 'wgFormattedNamespaces' => $wgContLang->getFormattedNamespaces(), 'wgNamespaceIds' => $namespaceIds, 'wgContentNamespaces' => MWNamespace::getContentNamespaces(), 'wgSiteName' => $wgSitename, 'wgFileExtensions' => array_values(array_unique($wgFileExtensions)), 'wgDBname' => $wgDBname, 'wgFileCanRotate' => BitmapHandler::canRotate(), 'wgAvailableSkins' => Skin::getSkinNames(), 'wgExtensionAssetsPath' => $wgExtensionAssetsPath, 'wgCookiePrefix' => $wgCookiePrefix, 'wgResourceLoaderMaxQueryLength' => $wgResourceLoaderMaxQueryLength, 'wgCaseSensitiveNamespaces' => $caseSensitiveNamespaces, 'wgLegalTitleChars' => Title::convertByteClassToUnicodeClass(Title::legalChars()), 'wgResourceLoaderStorageVersion' => $wgResourceLoaderStorageVersion, 'wgResourceLoaderStorageEnabled' => $wgResourceLoaderStorageEnabled); wfRunHooks('ResourceLoaderGetConfigVars', array(&$vars)); $this->configVars[$hash] = $vars; return $this->configVars[$hash]; }
/** * @param $context ResourceLoaderContext * @return array */ protected function getConfig($context) { global $wgLoadScript, $wgScript, $wgStylePath, $wgScriptExtension, $wgArticlePath, $wgScriptPath, $wgServer, $wgContLang, $wgVariantArticlePath, $wgActionPaths, $wgUseAjax, $wgVersion, $wgEnableAPI, $wgEnableWriteAPI, $wgDBname, $wgEnableMWSuggest, $wgSitename, $wgFileExtensions, $wgExtensionAssetsPath, $wgCookiePrefix, $wgResourceLoaderMaxQueryLength; $mainPage = Title::newMainPage(); /** * Namespace related preparation * - wgNamespaceIds: Key-value pairs of all localized, canonical and aliases for namespaces. * - wgCaseSensitiveNamespaces: Array of namespaces that are case-sensitive. */ $namespaceIds = $wgContLang->getNamespaceIds(); $caseSensitiveNamespaces = array(); foreach (MWNamespace::getCanonicalNamespaces() as $index => $name) { $namespaceIds[$wgContLang->lc($name)] = $index; if (!MWNamespace::isCapitalized($index)) { $caseSensitiveNamespaces[] = $index; } } // Build list of variables $vars = array('wgLoadScript' => $wgLoadScript, 'debug' => $context->getDebug(), 'skin' => $context->getSkin(), 'stylepath' => $wgStylePath, 'wgUrlProtocols' => wfUrlProtocols(), 'wgArticlePath' => $wgArticlePath, 'wgScriptPath' => $wgScriptPath, 'wgScriptExtension' => $wgScriptExtension, 'wgScript' => $wgScript, 'wgVariantArticlePath' => $wgVariantArticlePath, 'wgActionPaths' => (object) $wgActionPaths, 'wgServer' => $wgServer, 'wgUserLanguage' => $context->getLanguage(), 'wgContentLanguage' => $wgContLang->getCode(), 'wgVersion' => $wgVersion, 'wgEnableAPI' => $wgEnableAPI, 'wgEnableWriteAPI' => $wgEnableWriteAPI, 'wgDefaultDateFormat' => $wgContLang->getDefaultDateFormat(), 'wgMonthNames' => $wgContLang->getMonthNamesArray(), 'wgMonthNamesShort' => $wgContLang->getMonthAbbreviationsArray(), 'wgMainPageTitle' => $mainPage ? $mainPage->getPrefixedText() : null, 'wgFormattedNamespaces' => $wgContLang->getFormattedNamespaces(), 'wgNamespaceIds' => $namespaceIds, 'wgSiteName' => $wgSitename, 'wgFileExtensions' => array_values($wgFileExtensions), 'wgDBname' => $wgDBname, 'wgFileCanRotate' => BitmapHandler::canRotate(), 'wgAvailableSkins' => Skin::getSkinNames(), 'wgExtensionAssetsPath' => $wgExtensionAssetsPath, 'wgCookiePrefix' => $wgCookiePrefix, 'wgResourceLoaderMaxQueryLength' => $wgResourceLoaderMaxQueryLength, 'wgCaseSensitiveNamespaces' => $caseSensitiveNamespaces, 'wgSassParams' => SassUtil::getSassSettings()); if ($wgUseAjax && $wgEnableMWSuggest) { $vars['wgMWSuggestTemplate'] = SearchEngine::getMWSuggestTemplate(); } wfRunHooks('ResourceLoaderGetConfigVars', array(&$vars)); return $vars; }
function getLongDesc($image) { global $wgLang; $original = parent::getLongDesc($image); wfSuppressWarnings(); $metadata = unserialize($image->getMetadata()); wfRestoreWarnings(); if (!$metadata || $metadata['frameCount'] <= 0) { return $original; } $info = array(); $info[] = $original; if ($metadata['loopCount'] == 0) { $info[] = wfMsgExt('file-info-png-looped', 'parseinline'); } elseif ($metadata['loopCount'] > 1) { $info[] = wfMsgExt('file-info-png-repeat', 'parseinline', $metadata['loopCount']); } if ($metadata['frameCount'] > 0) { $info[] = wfMsgExt('file-info-png-frames', 'parseinline', $metadata['frameCount']); } if ($metadata['duration']) { $info[] = $wgLang->formatTimePeriod($metadata['duration']); } return $wgLang->commaList($info); }
function getLongDesc($image) { global $wgUser, $wgLang; $sk = $wgUser->getSkin(); $metadata = @unserialize($image->getMetadata()); if (!$metadata) { return parent::getLongDesc($image); } $info = array(); $info[] = $image->getMimeType(); $info[] = $sk->formatSize($image->getSize()); if ($metadata['looped']) { $info[] = wfMsgExt('file-info-gif-looped', 'parseinline'); } if ($metadata['frameCount'] > 1) { $info[] = wfMsgExt('file-info-gif-frames', 'parseinline', $metadata['frameCount']); } if ($metadata['duration']) { $info[] = $wgLang->formatTimePeriod($metadata['duration']); } $infoString = $wgLang->commaList($info); return "({$infoString})"; }
/** * @param $image File * @return string */ function getLongDesc($image) { global $wgLang; $original = parent::getLongDesc($image); wfSuppressWarnings(); $metadata = unserialize($image->getMetadata()); wfRestoreWarnings(); if (!$metadata || $metadata['frameCount'] <= 1) { return $original; } /* Preserve original image info string, but strip the last char ')' so we can add even more */ $info = array(); $info[] = $original; if ($metadata['looped']) { $info[] = wfMsgExt('file-info-gif-looped', 'parseinline'); } if ($metadata['frameCount'] > 1) { $info[] = wfMsgExt('file-info-gif-frames', 'parseinline', $metadata['frameCount']); } if ($metadata['duration']) { $info[] = $wgLang->formatTimePeriod($metadata['duration']); } return $wgLang->commaList($info); }
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; }
/** * @param File $image * @return string */ function getLongDesc($image) { global $wgLang; $original = parent::getLongDesc($image); MediaWiki\suppressWarnings(); $metadata = unserialize($image->getMetadata()); MediaWiki\restoreWarnings(); if (!$metadata || $metadata['frameCount'] <= 0) { return $original; } $info = []; $info[] = $original; if ($metadata['loopCount'] == 0) { $info[] = wfMessage('file-info-png-looped')->parse(); } elseif ($metadata['loopCount'] > 1) { $info[] = wfMessage('file-info-png-repeat')->numParams($metadata['loopCount'])->parse(); } if ($metadata['frameCount'] > 0) { $info[] = wfMessage('file-info-png-frames')->numParams($metadata['frameCount'])->parse(); } if ($metadata['duration']) { $info[] = $wgLang->formatTimePeriod($metadata['duration']); } return $wgLang->commaList($info); }
/** * @param File $image * @return string */ function getLongDesc($image) { global $wgLang; $original = parent::getLongDesc($image); MediaWiki\suppressWarnings(); $metadata = unserialize($image->getMetadata()); MediaWiki\restoreWarnings(); if (!$metadata || $metadata['frameCount'] <= 1) { return $original; } /* Preserve original image info string, but strip the last char ')' so we can add even more */ $info = []; $info[] = $original; if ($metadata['looped']) { $info[] = wfMessage('file-info-gif-looped')->parse(); } if ($metadata['frameCount'] > 1) { $info[] = wfMessage('file-info-gif-frames')->numParams($metadata['frameCount'])->parse(); } if ($metadata['duration']) { $info[] = $wgLang->formatTimePeriod($metadata['duration']); } return $wgLang->commaList($info); }
/** * @see $wgEnableAutoRotation * @return bool Whether auto rotation is enabled */ public static function autoRotateEnabled() { global $wgEnableAutoRotation; if ($wgEnableAutoRotation === null) { // Only enable auto-rotation when the bitmap handler can rotate $wgEnableAutoRotation = BitmapHandler::canRotate(); } return $wgEnableAutoRotation; }
/** * Can we render this file? * * Image magick doesn't support indexed xcf files as of current * writing (as of 6.8.9-3) * @param File $file * @return bool */ public function canRender($file) { MediaWiki\suppressWarnings(); $xcfMeta = unserialize($file->getMetadata()); MediaWiki\restoreWarnings(); if (isset($xcfMeta['colorType']) && $xcfMeta['colorType'] === 'index-coloured') { return false; } return parent::canRender($file); }
/** * On supporting image formats, try to read out the low-level orientation * of the file and return the angle that the file needs to be rotated to * be viewed. * * This information is only useful when manipulating the original file; * the width and height we normally work with is logical, and will match * any produced output views. * * @param File $file * @return int 0, 90, 180 or 270 */ public function getRotation($file) { if (!BitmapHandler::autoRotateEnabled()) { return 0; } $data = $file->getMetadata(); return $this->getRotationForExif($data); }
/** * Get the thumbnail code for videos * @param File $image * @param String $dstPath * @param String $dstUrl * @param Array $params * @param int $flags * @return object ThumbnailVideo object or error object */ function doTransform($image, $dstPath, $dstUrl, $params, $flags = 0) { $oThumbnailImage = parent::doTransform($image, $dstPath, $dstUrl, $params, $flags); return new ThumbnailVideo($oThumbnailImage->file, $oThumbnailImage->url, $oThumbnailImage->width, $oThumbnailImage->height, $oThumbnailImage->path, $oThumbnailImage->page); }
/** * @param $context ResourceLoaderContext * @return array */ protected function getConfig( $context ) { global $wgLoadScript, $wgScript, $wgStylePath, $wgScriptExtension, $wgArticlePath, $wgScriptPath, $wgServer, $wgContLang, $wgVariantArticlePath, $wgActionPaths, $wgVersion, $wgEnableAPI, $wgEnableWriteAPI, $wgDBname, $wgSitename, $wgFileExtensions, $wgExtensionAssetsPath, $wgCookiePrefix, $wgResourceLoaderMaxQueryLength; $mainPage = Title::newMainPage(); /** * Namespace related preparation * - wgNamespaceIds: Key-value pairs of all localized, canonical and aliases for namespaces. * - wgCaseSensitiveNamespaces: Array of namespaces that are case-sensitive. */ $namespaceIds = $wgContLang->getNamespaceIds(); $caseSensitiveNamespaces = array(); foreach ( MWNamespace::getCanonicalNamespaces() as $index => $name ) { $namespaceIds[$wgContLang->lc( $name )] = $index; if ( !MWNamespace::isCapitalized( $index ) ) { $caseSensitiveNamespaces[] = $index; } } // Build list of variables $vars = array( 'wgLoadScript' => $wgLoadScript, 'debug' => $context->getDebug(), 'skin' => $context->getSkin(), 'stylepath' => $wgStylePath, 'wgUrlProtocols' => wfUrlProtocols(), 'wgArticlePath' => $wgArticlePath, 'wgScriptPath' => $wgScriptPath, 'wgScriptExtension' => $wgScriptExtension, 'wgScript' => $wgScript, 'wgVariantArticlePath' => $wgVariantArticlePath, // Force object to avoid "empty" associative array from // becoming [] instead of {} in JS (bug 34604) 'wgActionPaths' => (object)$wgActionPaths, 'wgServer' => $wgServer, 'wgUserLanguage' => $context->getLanguage(), 'wgContentLanguage' => $wgContLang->getCode(), 'wgVersion' => $wgVersion, 'wgEnableAPI' => $wgEnableAPI, 'wgEnableWriteAPI' => $wgEnableWriteAPI, 'wgMainPageTitle' => $mainPage->getPrefixedText(), 'wgFormattedNamespaces' => $wgContLang->getFormattedNamespaces(), 'wgNamespaceIds' => $namespaceIds, 'wgSiteName' => $wgSitename, 'wgFileExtensions' => array_values( array_unique( $wgFileExtensions ) ), 'wgDBname' => $wgDBname, // This sucks, it is only needed on Special:Upload, but I could // not find a way to add vars only for a certain module 'wgFileCanRotate' => BitmapHandler::canRotate(), 'wgAvailableSkins' => Skin::getSkinNames(), 'wgExtensionAssetsPath' => $wgExtensionAssetsPath, // MediaWiki sets cookies to have this prefix by default 'wgCookiePrefix' => $wgCookiePrefix, 'wgResourceLoaderMaxQueryLength' => $wgResourceLoaderMaxQueryLength, 'wgCaseSensitiveNamespaces' => $caseSensitiveNamespaces, 'wgLegalTitleChars' => Title::convertByteClassToUnicodeClass( Title::legalChars() ), ); wfRunHooks( 'ResourceLoaderGetConfigVars', array( &$vars ) ); return $vars; }
/** * Wrapper for base classes ImageHandler::getImageSize() that checks for * rotation reported from metadata and swaps the sizes to match. * * @param File $image * @param string $path * @return array */ function getImageSize($image, $path) { global $wgEnableAutoRotation; $gis = parent::getImageSize($image, $path); // Don't just call $image->getMetadata(); FSFile::getPropsFromPath() calls us with a bogus object. // This may mean we read EXIF data twice on initial upload. if ($wgEnableAutoRotation) { $meta = $this->getMetadata($image, $path); $rotation = $this->getRotationForExif($meta); } else { $rotation = 0; } if ($rotation == 90 || $rotation == 270) { $width = $gis[0]; $gis[0] = $gis[1]; $gis[1] = $width; } return $gis; }
/** * Should we rotate images in the preview on Special:Upload. * * This controls js: mw.config.get( 'wgFileCanRotate' ) * * @todo What about non-BitmapHandler handled files? */ public static function rotationEnabled() { $bitmapHandler = new BitmapHandler(); return $bitmapHandler->autoRotateEnabled(); }
if ( !isset( $wgLocalFileRepo['backend'] ) ) { $wgLocalFileRepo['backend'] = $wgLocalFileRepo['name'] . '-backend'; } foreach ( $wgForeignFileRepos as &$repo ) { if ( !isset( $repo['directory'] ) && $repo['class'] === 'ForeignAPIRepo' ) { $repo['directory'] = $wgUploadDirectory; // b/c } if ( !isset( $repo['backend'] ) ) { $repo['backend'] = $repo['name'] . '-backend'; } } unset( $repo ); // no global pollution; destroy reference if ( is_null( $wgEnableAutoRotation ) ) { // Only enable auto-rotation when the bitmap handler can rotate $wgEnableAutoRotation = BitmapHandler::canRotate(); } if ( $wgRCFilterByAge ) { # # Trim down $wgRCLinkDays so that it only lists links which are valid # # as determined by $wgRCMaxAge. # # Note that we allow 1 link higher than the max for things like 56 days but a 60 day link. sort( $wgRCLinkDays ); for ( $i = 0; $i < count( $wgRCLinkDays ); $i++ ) { if ( $wgRCLinkDays[$i] >= $wgRCMaxAge / ( 3600 * 24 ) ) { $wgRCLinkDays = array_slice( $wgRCLinkDays, 0, $i + 1, false ); break; } } }
/** * @covers BitmapHandler::getImageArea */ public function testImageArea() { $file = new FakeDimensionFile(array(7, 9)); $handler = new BitmapHandler(); $this->assertEquals(63, $handler->getImageArea($file)); }
/** * Check the file and params against $wgVipsOptions * * @param BitmapHandler $handler * @param File $file * @param array $params * @return bool */ protected static function getHandlerOptions( $handler, $file, $params ) { global $wgVipsOptions; # Iterate over conditions foreach ( $wgVipsOptions as $option ) { if ( isset( $option['conditions'] ) ) { $condition = $option['conditions']; } else { # Unconditionally pass return $option; } if ( isset( $condition['mimeType'] ) && $file->getMimeType() != $condition['mimeType'] ) { continue; } $area = $handler->getImageArea( $file ); if ( isset( $condition['minArea'] ) && $area < $condition['minArea'] ) { continue; } if ( isset( $condition['maxArea'] ) && $area >= $condition['maxArea'] ) { continue; } $shrinkFactor = $file->getWidth() / ( ( ( $handler->getRotation( $file ) % 180 ) == 90 ) ? $params['physicalHeight'] : $params['physicalWidth'] ); if ( isset( $condition['minShrinkFactor'] ) && $shrinkFactor < $condition['minShrinkFactor'] ) { continue; } if ( isset( $condition['maxShrinkFactor'] ) && $shrinkFactor >= $condition['maxShrinkFactor'] ) { continue; } # This condition passed return $option; } # All conditions failed return false; }