Merge "Added common metadata caching to the djvu handler"
[lhc/web/wiklou.git] / includes / media / DjVu.php
index ba60af4..749ef23 100644 (file)
@@ -27,6 +27,8 @@
  * @ingroup Media
  */
 class DjVuHandler extends ImageHandler {
+       const EXPENSIVE_SIZE_LIMIT = 10485760; // 10MiB
+
        /**
         * @return bool
         */
@@ -49,6 +51,15 @@ class DjVuHandler extends ImageHandler {
                return true;
        }
 
+       /**
+        * True if creating thumbnails from the file is large or otherwise resource-intensive.
+        * @param File $file
+        * @return bool
+        */
+       public function isExpensiveToThumbnail( $file ) {
+               return $file->getSize() > static::EXPENSIVE_SIZE_LIMIT;
+       }
+
        /**
         * @param File $file
         * @return bool
@@ -137,31 +148,12 @@ class DjVuHandler extends ImageHandler {
        function doTransform( $image, $dstPath, $dstUrl, $params, $flags = 0 ) {
                global $wgDjvuRenderer, $wgDjvuPostProcessor;
 
-               // Fetch XML and check it, to give a more informative error message than the one which
-               // normaliseParams will inevitably give.
-               $xml = $image->getMetadata();
-               if ( !$xml ) {
-                       $width = isset( $params['width'] ) ? $params['width'] : 0;
-                       $height = isset( $params['height'] ) ? $params['height'] : 0;
-
-                       return new MediaTransformError( 'thumbnail_error', $width, $height,
-                               wfMessage( 'djvu_no_xml' )->text() );
-               }
-
                if ( !$this->normaliseParams( $image, $params ) ) {
                        return new TransformParameterError( $params );
                }
                $width = $params['width'];
                $height = $params['height'];
                $page = $params['page'];
-               if ( $page > $this->pageCount( $image ) ) {
-                       return new MediaTransformError(
-                               'thumbnail_error',
-                               $width,
-                               $height,
-                               wfMessage( 'djvu_page_error' )->text()
-                       );
-               }
 
                if ( $flags & self::TRANSFORM_LATER ) {
                        $params = array(
@@ -221,11 +213,9 @@ class DjVuHandler extends ImageHandler {
                        $cmd .= " | {$wgDjvuPostProcessor}";
                }
                $cmd .= ' > ' . wfEscapeShellArg( $dstPath ) . ') 2>&1';
-               wfProfileIn( 'ddjvu' );
                wfDebug( __METHOD__ . ": $cmd\n" );
                $retval = '';
                $err = wfShellExec( $cmd, $retval );
-               wfProfileOut( 'ddjvu' );
 
                $removed = $this->removeBadFile( $dstPath, $retval );
                if ( $retval != 0 || $removed ) {
@@ -313,7 +303,6 @@ class DjVuHandler extends ImageHandler {
 
                        return false;
                }
-               wfProfileIn( __METHOD__ );
 
                wfSuppressWarnings();
                try {
@@ -339,7 +328,6 @@ class DjVuHandler extends ImageHandler {
                        wfDebug( "Bogus multipage XML metadata on '{$image->getName()}'\n" );
                }
                wfRestoreWarnings();
-               wfProfileOut( __METHOD__ );
                if ( $gettext ) {
                        return $image->djvuTextTree;
                } else {
@@ -388,29 +376,55 @@ class DjVuHandler extends ImageHandler {
        }
 
        function pageCount( $image ) {
-               $tree = $this->getMetaTree( $image );
-               if ( !$tree ) {
-                       return false;
+               global $wgMemc;
+
+               $key = wfMemcKey( 'file-djvu', 'pageCount', $image->getSha1() );
+
+               $count = $wgMemc->get( $key );
+               if ( $count === false ) {
+                       $tree = $this->getMetaTree( $image );
+                       if ( !$tree ) {
+                               return false;
+                       }
+                       $count = count( $tree->xpath( '//OBJECT' ) );
+                       $wgMemc->set( $key, $count );
                }
 
-               return count( $tree->xpath( '//OBJECT' ) );
+               return $count;
        }
 
        function getPageDimensions( $image, $page ) {
-               $tree = $this->getMetaTree( $image );
-               if ( !$tree ) {
-                       return false;
-               }
+               global $wgMemc;
 
-               $o = $tree->BODY[0]->OBJECT[$page - 1];
-               if ( $o ) {
-                       return array(
-                               'width' => intval( $o['width'] ),
-                               'height' => intval( $o['height'] )
-                       );
-               } else {
-                       return false;
+               $key = wfMemcKey( 'file-djvu', 'dimensions', $image->getSha1() );
+
+               $dimsByPage = $wgMemc->get( $key );
+               if ( !is_array( $dimsByPage ) ) {
+                       $tree = $this->getMetaTree( $image );
+                       if ( !$tree ) {
+                               return false;
+                       }
+
+                       $dimsByPage = array();
+                       $count = count( $tree->xpath( '//OBJECT' ) );
+                       for ( $i = 0; $i < $count; ++$i ) {
+                               $o = $tree->BODY[0]->OBJECT[$i];
+                               if ( $o ) {
+                                       $dimsByPage[$i] = array(
+                                               'width' => (int)$o['width'],
+                                               'height' => (int)$o['height']
+                                       );
+                               } else {
+                                       $dimsByPage[$i] = false;
+                               }
+                       }
+
+                       $wgMemc->set( $key, $dimsByPage );
                }
+
+               $index = $page - 1; // MW starts pages at 1
+
+               return isset( $dimsByPage[$index] ) ? $dimsByPage[$index] : false;
        }
 
        /**