Rm extra space
[lhc/web/wiklou.git] / includes / media / Bitmap.php
index a5cc711..604e944 100644 (file)
@@ -12,7 +12,6 @@
  * @ingroup Media
  */
 class BitmapHandler extends ImageHandler {
-
        /**
         * @param $image File
         * @param $params array Transform parameters. Entries with the keys 'width'
@@ -21,12 +20,10 @@ class BitmapHandler extends ImageHandler {
         * @return bool
         */
        function normaliseParams( $image, &$params ) {
-               
                if ( !parent::normaliseParams( $image, $params ) ) {
                        return false;
                }
 
-               $mimeType = $image->getMimeType();
                # Obtain the source, pre-rotation dimensions
                $srcWidth = $image->getWidth( $params['page'] );
                $srcHeight = $image->getHeight( $params['page'] );
@@ -42,41 +39,25 @@ class BitmapHandler extends ImageHandler {
                                return true;
                        }
                }
-               
-               return true;
-       }
-       
-       /**
-        * Check if the file is smaller than the maximum image area for 
-        * thumbnailing. Check will always pass if the scaler is 'hookaborted' or
-        * if the scaler is 'im' and the mime type is 'image/jpeg'
-        * 
-        * @param File $image
-        * @param string $scaler 
-        */
-       function checkImageArea( $image, $scaler ) {
-               global $wgMaxImageArea;
-               # Don't thumbnail an image so big that it will fill hard drives and send servers into swap
-               # JPEG has the handy property of allowing thumbnailing without full decompression, so we make
-               # an exception for it.
-               
-               
-               if ( $image->getMimeType() == 'image/jpeg' && $scaler == 'im' )
-               {
-                       # ImageMagick can efficiently downsize jpg images without loading
-                       # the entire file in memory
-                       return true;
-               }
-               
-               if ( $scaler == 'hookaborted' )
-               {
-                       # If a hook wants to transform the image, it is responsible for 
-                       # checking the image size, so abort here
-                       return true;
+
+               # Check if the file is smaller than the maximum image area for thumbnailing
+               $checkImageAreaHookResult = null;
+               wfRunHooks( 'BitmapHandlerCheckImageArea', array( $image, &$params, &$checkImageAreaHookResult ) );
+               if ( is_null( $checkImageAreaHookResult ) ) {
+                       global $wgMaxImageArea;
+
+                       if ( $srcWidth * $srcHeight > $wgMaxImageArea &&
+                                       !( $image->getMimeType() == 'image/jpeg' &&
+                                               self::getScalerType( false, false ) == 'im' ) ) {
+                               # Only ImageMagick can efficiently downsize jpg images without loading
+                               # the entire file in memory
+                               return false;
+                       }
+               } else {
+                       return $checkImageAreaHookResult;
                }
-               
-               # Do the actual check
-               return $this->getImageArea( $image, $image->getWidth(), $image->getHeight() ) <= $wgMaxImageArea;
+
+               return true;
        }
 
 
@@ -105,10 +86,15 @@ class BitmapHandler extends ImageHandler {
        }
 
 
-       // Function that returns the number of pixels to be thumbnailed.
-       // Intended for animated GIFs to multiply by the number of frames.
-       function getImageArea( $image, $width, $height ) {
-               return $width * $height;
+       /**
+        * Function that returns the number of pixels to be thumbnailed.
+        * Intended for animated GIFs to multiply by the number of frames.
+        *
+        * @param File $image
+        * @return int
+        */
+       function getImageArea( $image ) {
+               return $image->getWidth() * $image->getHeight();
        }
 
        /**
@@ -139,12 +125,15 @@ class BitmapHandler extends ImageHandler {
                        'srcWidth' => $image->getWidth(),
                        'srcHeight' => $image->getHeight(),
                        'mimeType' => $image->getMimeType(),
-                       'srcPath' => $image->getPath(),
+                       'srcPath' => $image->getLocalRefPath(),
                        'dstPath' => $dstPath,
                        'dstUrl' => $dstUrl,
                );
 
-               wfDebug( __METHOD__ . ": creating {$scalerParams['physicalDimensions']} thumbnail at $dstPath\n" );
+               # Determine scaler type
+               $scaler = self::getScalerType( $dstPath );
+
+               wfDebug( __METHOD__ . ": creating {$scalerParams['physicalDimensions']} thumbnail at $dstPath using scaler $scaler\n" );
 
                if ( !$image->mustRender() &&
                                $scalerParams['physicalWidth'] == $scalerParams['srcWidth']
@@ -155,9 +144,6 @@ class BitmapHandler extends ImageHandler {
                        return $this->getClientScalingThumbnailImage( $image, $scalerParams );
                }
 
-               # Determine scaler type
-               $scaler = self::getScalerType( $dstPath );
-               wfDebug( __METHOD__ . ": scaler $scaler\n" );
 
                if ( $scaler == 'client' ) {
                        # Client-side image scaling, use the source URL
@@ -168,7 +154,7 @@ 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'], $dstPath );
+                               $scalerParams['clientHeight'], false );
                }
 
                # Try to make a target path for the thumbnail
@@ -184,12 +170,6 @@ class BitmapHandler extends ImageHandler {
                        wfDebug( __METHOD__ . ": Hook to BitmapHandlerTransform created an mto\n" );
                        $scaler = 'hookaborted';
                }
-               
-               # Check max image area
-               if ( !$this->checkImageArea( $image, $scaler ) )
-               {
-                       return new TransformParameterError( $params );
-               }
 
                switch ( $scaler ) {
                        case 'hookaborted':
@@ -299,15 +279,16 @@ class BitmapHandler extends ImageHandler {
                                        < $wgSharpenReductionThreshold ) {
                                $sharpen = "-sharpen " . wfEscapeShellArg( $wgSharpenParameter );
                        }
-                       // JPEG decoder hint to reduce memory, available since IM 6.5.6-2
-                       $decoderHint = "-define jpeg:size={$params['physicalDimensions']}";
+                       if ( version_compare( $this->getMagickVersion(), "6.5.6" ) >= 0 ) {
+                               // JPEG decoder hint to reduce memory, available since IM 6.5.6-2
+                               $decoderHint = "-define jpeg:size={$params['physicalDimensions']}";
+                       }
 
                } elseif ( $params['mimeType'] == 'image/png' ) {
                        $quality = "-quality 95"; // zlib 9, adaptive filtering
 
                } elseif ( $params['mimeType'] == 'image/gif' ) {
-                       if ( $this->getImageArea( $image, $params['srcWidth'],
-                                       $params['srcHeight'] ) > $wgMaxAnimatedGifArea ) {
+                       if ( $this->getImageArea( $image ) > $wgMaxAnimatedGifArea ) {
                                // Extract initial frame only; we're so big it'll
                                // be a total drag. :P
                                $scene = 0;
@@ -321,6 +302,8 @@ class BitmapHandler extends ImageHandler {
                                        $animation_post = '-fuzz 5% -layers optimizeTransparency';
                                }
                        }
+               } elseif ( $params['mimeType'] == 'image/x-xcf' ) {
+                       $animation_post = '-layers merge';
                }
 
                // Use one thread only, to avoid deadlock bugs on OOM
@@ -395,8 +378,7 @@ class BitmapHandler extends ImageHandler {
                        } elseif( $params['mimeType'] == 'image/png' ) {
                                $im->setCompressionQuality( 95 );
                        } elseif ( $params['mimeType'] == 'image/gif' ) {
-                               if ( $this->getImageArea( $image, $params['srcWidth'],
-                                               $params['srcHeight'] ) > $wgMaxAnimatedGifArea ) {
+                               if ( $this->getImageArea( $image ) > $wgMaxAnimatedGifArea ) {
                                        // Extract initial frame only; we're so big it'll
                                        // be a total drag. :P
                                        $im->setImageScene( 0 );
@@ -525,7 +507,7 @@ class BitmapHandler extends ImageHandler {
                if ( !isset( $typemap[$params['mimeType']] ) ) {
                        $err = 'Image type not supported';
                        wfDebug( "$err\n" );
-                       $errMsg = wfMsg ( 'thumbnail_image-type' );
+                       $errMsg = wfMsg( 'thumbnail_image-type' );
                        return $this->getMediaTransformError( $params, $errMsg );
                }
                list( $loader, $colorStyle, $saveType ) = $typemap[$params['mimeType']];
@@ -533,14 +515,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 = wfMsg( 'thumbnail_gd-library', $loader );
                        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 = wfMsg( 'thumbnail_image-missing', $params['srcPath'] );
                        return $this->getMediaTransformError( $params, $errMsg );
                }