MediaWiki
REL1_19
|
00001 <?php 00014 class DjVuHandler extends ImageHandler { 00015 00019 function isEnabled() { 00020 global $wgDjvuRenderer, $wgDjvuDump, $wgDjvuToXML; 00021 if ( !$wgDjvuRenderer || ( !$wgDjvuDump && !$wgDjvuToXML ) ) { 00022 wfDebug( "DjVu is disabled, please set \$wgDjvuRenderer and \$wgDjvuDump\n" ); 00023 return false; 00024 } else { 00025 return true; 00026 } 00027 } 00028 00033 function mustRender( $file ) { 00034 return true; 00035 } 00036 00041 function isMultiPage( $file ) { 00042 return true; 00043 } 00044 00048 function getParamMap() { 00049 return array( 00050 'img_width' => 'width', 00051 'img_page' => 'page', 00052 ); 00053 } 00054 00060 function validateParam( $name, $value ) { 00061 if ( in_array( $name, array( 'width', 'height', 'page' ) ) ) { 00062 if ( $value <= 0 ) { 00063 return false; 00064 } else { 00065 return true; 00066 } 00067 } else { 00068 return false; 00069 } 00070 } 00071 00076 function makeParamString( $params ) { 00077 $page = isset( $params['page'] ) ? $params['page'] : 1; 00078 if ( !isset( $params['width'] ) ) { 00079 return false; 00080 } 00081 return "page{$page}-{$params['width']}px"; 00082 } 00083 00088 function parseParamString( $str ) { 00089 $m = false; 00090 if ( preg_match( '/^page(\d+)-(\d+)px$/', $str, $m ) ) { 00091 return array( 'width' => $m[2], 'page' => $m[1] ); 00092 } else { 00093 return false; 00094 } 00095 } 00096 00101 function getScriptParams( $params ) { 00102 return array( 00103 'width' => $params['width'], 00104 'page' => $params['page'], 00105 ); 00106 } 00107 00116 function doTransform( $image, $dstPath, $dstUrl, $params, $flags = 0 ) { 00117 global $wgDjvuRenderer, $wgDjvuPostProcessor; 00118 00119 // Fetch XML and check it, to give a more informative error message than the one which 00120 // normaliseParams will inevitably give. 00121 $xml = $image->getMetadata(); 00122 if ( !$xml ) { 00123 $width = isset( $params['width'] ) ? $params['width'] : 0; 00124 $height = isset( $params['height'] ) ? $params['height'] : 0; 00125 return new MediaTransformError( 'thumbnail_error', $width, $height, 00126 wfMsg( 'djvu_no_xml' ) ); 00127 } 00128 00129 if ( !$this->normaliseParams( $image, $params ) ) { 00130 return new TransformParameterError( $params ); 00131 } 00132 $width = $params['width']; 00133 $height = $params['height']; 00134 $srcPath = $image->getLocalRefPath(); 00135 $page = $params['page']; 00136 if ( $page > $this->pageCount( $image ) ) { 00137 return new MediaTransformError( 'thumbnail_error', $width, $height, wfMsg( 'djvu_page_error' ) ); 00138 } 00139 00140 if ( $flags & self::TRANSFORM_LATER ) { 00141 return new ThumbnailImage( $image, $dstUrl, $width, $height, $dstPath, $page ); 00142 } 00143 00144 if ( !wfMkdirParents( dirname( $dstPath ), null, __METHOD__ ) ) { 00145 return new MediaTransformError( 'thumbnail_error', $width, $height, wfMsg( 'thumbnail_dest_directory' ) ); 00146 } 00147 00148 # Use a subshell (brackets) to aggregate stderr from both pipeline commands 00149 # before redirecting it to the overall stdout. This works in both Linux and Windows XP. 00150 $cmd = '(' . wfEscapeShellArg( 00151 $wgDjvuRenderer, 00152 "-format=ppm", 00153 "-page={$page}", 00154 "-size={$params['physicalWidth']}x{$params['physicalHeight']}", 00155 $srcPath ); 00156 if ( $wgDjvuPostProcessor ) { 00157 $cmd .= " | {$wgDjvuPostProcessor}"; 00158 } 00159 $cmd .= ' > ' . wfEscapeShellArg($dstPath) . ') 2>&1'; 00160 wfProfileIn( 'ddjvu' ); 00161 wfDebug( __METHOD__.": $cmd\n" ); 00162 $retval = ''; 00163 $err = wfShellExec( $cmd, $retval ); 00164 wfProfileOut( 'ddjvu' ); 00165 00166 $removed = $this->removeBadFile( $dstPath, $retval ); 00167 if ( $retval != 0 || $removed ) { 00168 wfDebugLog( 'thumbnail', 00169 sprintf( 'thumbnail failed on %s: error %d "%s" from "%s"', 00170 wfHostname(), $retval, trim($err), $cmd ) ); 00171 return new MediaTransformError( 'thumbnail_error', $width, $height, $err ); 00172 } else { 00173 return new ThumbnailImage( $image, $dstUrl, $width, $height, $dstPath, $page ); 00174 } 00175 } 00176 00182 function getDjVuImage( $image, $path ) { 00183 if ( !$image ) { 00184 $deja = new DjVuImage( $path ); 00185 } elseif ( !isset( $image->dejaImage ) ) { 00186 $deja = $image->dejaImage = new DjVuImage( $path ); 00187 } else { 00188 $deja = $image->dejaImage; 00189 } 00190 return $deja; 00191 } 00192 00198 function getMetaTree( $image , $gettext = false ) { 00199 if ( isset( $image->dejaMetaTree ) ) { 00200 return $image->dejaMetaTree; 00201 } 00202 00203 $metadata = $image->getMetadata(); 00204 if ( !$this->isMetadataValid( $image, $metadata ) ) { 00205 wfDebug( "DjVu XML metadata is invalid or missing, should have been fixed in upgradeRow\n" ); 00206 return false; 00207 } 00208 wfProfileIn( __METHOD__ ); 00209 00210 wfSuppressWarnings(); 00211 try { 00212 // Set to false rather than null to avoid further attempts 00213 $image->dejaMetaTree = false; 00214 $image->djvuTextTree = false; 00215 $tree = new SimpleXMLElement( $metadata ); 00216 if( $tree->getName() == 'mw-djvu' ) { 00217 foreach($tree->children() as $b){ 00218 if( $b->getName() == 'DjVuTxt' ) { 00219 $image->djvuTextTree = $b; 00220 } 00221 elseif ( $b->getName() == 'DjVuXML' ) { 00222 $image->dejaMetaTree = $b; 00223 } 00224 } 00225 } else { 00226 $image->dejaMetaTree = $tree; 00227 } 00228 } catch( Exception $e ) { 00229 wfDebug( "Bogus multipage XML metadata on '{$image->getName()}'\n" ); 00230 } 00231 wfRestoreWarnings(); 00232 wfProfileOut( __METHOD__ ); 00233 if( $gettext ) { 00234 return $image->djvuTextTree; 00235 } else { 00236 return $image->dejaMetaTree; 00237 } 00238 } 00239 00240 function getImageSize( $image, $path ) { 00241 return $this->getDjVuImage( $image, $path )->getImageSize(); 00242 } 00243 00244 function getThumbType( $ext, $mime, $params = null ) { 00245 global $wgDjvuOutputExtension; 00246 static $mime; 00247 if ( !isset( $mime ) ) { 00248 $magic = MimeMagic::singleton(); 00249 $mime = $magic->guessTypesForExtension( $wgDjvuOutputExtension ); 00250 } 00251 return array( $wgDjvuOutputExtension, $mime ); 00252 } 00253 00254 function getMetadata( $image, $path ) { 00255 wfDebug( "Getting DjVu metadata for $path\n" ); 00256 return $this->getDjVuImage( $image, $path )->retrieveMetaData(); 00257 } 00258 00259 function getMetadataType( $image ) { 00260 return 'djvuxml'; 00261 } 00262 00263 function isMetadataValid( $image, $metadata ) { 00264 return !empty( $metadata ) && $metadata != serialize(array()); 00265 } 00266 00267 function pageCount( $image ) { 00268 $tree = $this->getMetaTree( $image ); 00269 if ( !$tree ) { 00270 return false; 00271 } 00272 return count( $tree->xpath( '//OBJECT' ) ); 00273 } 00274 00275 function getPageDimensions( $image, $page ) { 00276 $tree = $this->getMetaTree( $image ); 00277 if ( !$tree ) { 00278 return false; 00279 } 00280 00281 $o = $tree->BODY[0]->OBJECT[$page-1]; 00282 if ( $o ) { 00283 return array( 00284 'width' => intval( $o['width'] ), 00285 'height' => intval( $o['height'] ) 00286 ); 00287 } else { 00288 return false; 00289 } 00290 } 00291 00292 function getPageText( $image, $page ){ 00293 $tree = $this->getMetaTree( $image, true ); 00294 if ( !$tree ) { 00295 return false; 00296 } 00297 00298 $o = $tree->BODY[0]->PAGE[$page-1]; 00299 if ( $o ) { 00300 $txt = $o['value']; 00301 return $txt; 00302 } else { 00303 return false; 00304 } 00305 00306 } 00307 00308 }