22 private const EXPENSIVE_SIZE_LIMIT = 10_485_760;
25 private const STATE_DJVU_IMAGE =
'djvuImage';
26 private const STATE_TEXT_TREE =
'djvuTextTree';
27 private const STATE_META_TREE =
'djvuMetaTree';
28 private const CACHE_VERSION =
'v2';
34 $djvuRenderer = MediaWikiServices::getInstance()->getMainConfig()->get( MainConfigNames::DjvuRenderer );
35 $djvuDump = MediaWikiServices::getInstance()->getMainConfig()->get( MainConfigNames::DjvuDump );
36 if ( !$djvuRenderer || !$djvuDump ) {
37 wfDebug(
"DjVu is disabled, please set \$wgDjvuRenderer and \$wgDjvuDump" );
58 return $file->
getSize() > static::EXPENSIVE_SIZE_LIMIT;
74 'img_width' =>
'width',
85 if ( $name ===
'page' && trim( $value ) !== (
string)intval( $value ) ) {
90 return in_array( $name, [
'width',
'height',
'page' ] ) && $value > 0;
98 $page = $params[
'page'] ?? 1;
99 if ( !isset( $params[
'width'] ) ) {
103 return "page{$page}-{$params['width']}px";
112 if ( preg_match(
'/^page(\d+)-(\d+)px$/', $str, $m ) ) {
113 return [
'width' => $m[2],
'page' => $m[1] ];
124 'width' => $params[
'width'],
125 'page' => $params[
'page'],
137 public function doTransform( $image, $dstPath, $dstUrl, $params, $flags = 0 ) {
138 $djvuRenderer = MediaWikiServices::getInstance()->getMainConfig()->get( MainConfigNames::DjvuRenderer );
139 $djvuPostProcessor = MediaWikiServices::getInstance()->getMainConfig()
140 ->get( MainConfigNames::DjvuPostProcessor );
144 $width = $params[
'width'];
145 $height = $params[
'height'];
146 $page = $params[
'page'];
148 if ( $flags & self::TRANSFORM_LATER ) {
170 if ( $image->getSize() >= 1e7 ) {
173 'doWork' =>
static function () use ( $image ) {
174 return $image->getLocalRefPath();
180 $srcPath = $image->getLocalRefPath();
183 if ( $srcPath ===
false ) {
185 sprintf(
'Thumbnail failed on %s: could not get local copy of "%s"',
189 $params[
'width'], $params[
'height'],
194 # Use a subshell (brackets) to aggregate stderr from both pipeline commands
195 # before redirecting it to the overall stdout. This works in both Linux and Windows XP.
196 $cmd =
'(' . Shell::escape(
200 "-size={$params['physicalWidth']}x{$params['physicalHeight']}",
202 if ( $djvuPostProcessor ) {
203 $cmd .=
" | {$djvuPostProcessor}";
205 $cmd .=
' > ' . Shell::escape( $dstPath ) .
') 2>&1';
206 wfDebug( __METHOD__ .
": $cmd" );
211 if ( $retval !== 0 || $removed ) {
232 private function getDjVuImage( $state,
$path ) {
233 $deja = $state->getHandlerState( self::STATE_DJVU_IMAGE );
236 $state->setHandlerState( self::STATE_DJVU_IMAGE, $deja );
248 private function getMetadataInternal(
File $file, $gettext ) {
249 $itemNames = [
'error',
'_error',
'data' ];
251 $itemNames[] =
'text';
255 if ( isset( $unser[
'error'] ) ) {
258 if ( isset( $unser[
'_error'] ) ) {
271 if ( $gettext && $image->getHandlerState( self::STATE_TEXT_TREE ) ) {
272 return $image->getHandlerState( self::STATE_TEXT_TREE );
274 if ( !$gettext && $image->getHandlerState( self::STATE_META_TREE ) ) {
275 return $image->getHandlerState( self::STATE_META_TREE );
278 $metadata = $this->getMetadataInternal( $image, $gettext );
284 unset( $metadata[
'text'] );
291 $djvuOutputExtension = MediaWikiServices::getInstance()->getMainConfig()
292 ->get( MainConfigNames::DjvuOutputExtension );
293 static $djvuMime =
null;
294 if ( $djvuMime ===
null ) {
295 $magic = MediaWikiServices::getInstance()->getMimeAnalyzer();
296 $djvuMime = $magic->getMimeTypeFromExtensionOrNull( $djvuOutputExtension );
299 return [ $djvuOutputExtension, $djvuMime ];
304 wfDebug(
"Getting DjVu metadata for $path" );
306 $djvuImage = $this->getDjVuImage( $state,
$path );
307 $metadata = $djvuImage->retrieveMetaData();
308 if ( $metadata ===
false ) {
310 $metadata = [
'error' =>
'Error extracting metadata' ];
312 return [
'metadata' => $metadata ] + $djvuImage->getImageSize();
330 return $info ? $info[
'pageCount'] :
false;
338 if ( $info && isset( $info[
'dimensionsByPage'][$index] ) ) {
339 return $info[
'dimensionsByPage'][$index];
347 $cache = MediaWikiServices::getInstance()->getMainWANObjectCache();
348 return $cache->getWithSetCallback(
349 $cache->makeKey(
'file-djvu',
'dimensions', self::CACHE_VERSION, $file->
getSha1() ),
350 $cache::TTL_INDEFINITE,
351 function () use ( $file ) {
355 [
'pcTTL' => $cache::TTL_INDEFINITE ]
370 if ( !isset( $metatree[
'data'] ) || !$metatree[
'data'] ) {
373 foreach ( $metatree[
'data'][
'pages'] as $page ) {
375 $dimsByPage[] =
false;
378 'width' => (int)$page[
'width'],
379 'height' => (
int)$page[
'height'],
384 'pageCount' => count( $metatree[
'data'][
'pages'] ),
385 'dimensionsByPage' => $dimsByPage
399 if ( isset( $tree[
'text'] ) && isset( $tree[
'text'][$page - 1] ) ) {
400 return $tree[
'text'][$page - 1];
wfDebug( $text, $dest='all', array $context=[])
Sends a line to the debug log if enabled or, optionally, to a comment in output.
wfShellExec( $cmd, &$retval=null, $environ=[], $limits=[], $options=[])
Execute a shell command, with time and memory limits mirrored from the PHP configuration if supported...
wfHostname()
Get host name of the current machine, for use in error reporting.
wfDebugLog( $logGroup, $text, $dest='all', array $context=[])
Send a line to a supplementary debug log file, if configured, or main debug log if not.
wfMkdirParents( $dir, $mode=null, $caller=null)
Make directory, and make all parent directories if they don't exist.
wfMessage( $key,... $params)
This is the function for getting translated interface messages.
getDimensionInfoFromMetaTree( $metatree)
Given the metadata, returns dimension information about the document.
makeParamString( $params)
isExpensiveToThumbnail( $file)
True if creating thumbnails from the file is large or otherwise resource-intensive.
validateParam( $name, $value)
getDimensionInfo(File $file)
getScriptParams( $params)
doTransform( $image, $dstPath, $dstUrl, $params, $flags=0)
pageCount(File $image)
Page count for a multi-page document, false if unsupported or unknown.to overrideint|false
getPageText(File $image, $page)
isFileMetadataValid( $image)
Check if the metadata is valid for this handler.If it returns MediaHandler::METADATA_BAD (or false),...
getSizeAndMetadata( $state, $path)
Get image size information and metadata array.If this returns null, the caller will fall back to getI...
getPageDimensions(File $image, $page)
Get an associative array of page dimensions Currently "width" and "height" are understood,...
getMetadataType( $image)
Get a string describing the type of metadata, for display purposes.to overrideThis method is currentl...
getMetaTree( $image, $gettext=false)
Cache a document tree for the DjVu metadata.
getThumbType( $ext, $mime, $params=null)
Get the thumbnail extension and MIME type for a given source MIME type.to overridearray Thumbnail ext...
useSplitMetadata()
If this returns true, LocalFile may split metadata up and store its constituent items separately....
Support for detecting/validating DjVu image files and getting some basic file metadata (resolution et...
Media handler abstract base class for images.
normaliseParams( $image, &$params)
Changes the parameter array as necessary, ready for transformation.Should be idempotent....
A class containing constants representing the names of configuration variables.
Media transform output for images.