36 private const EXPENSIVE_SIZE_LIMIT = 10_485_760;
39 private const STATE_DJVU_IMAGE =
'djvuImage';
40 private const STATE_TEXT_TREE =
'djvuTextTree';
41 private const STATE_META_TREE =
'djvuMetaTree';
42 private const CACHE_VERSION =
'v2';
48 $djvuRenderer = MediaWikiServices::getInstance()->getMainConfig()->get( MainConfigNames::DjvuRenderer );
49 $djvuDump = MediaWikiServices::getInstance()->getMainConfig()->get( MainConfigNames::DjvuDump );
50 if ( !$djvuRenderer || !$djvuDump ) {
51 wfDebug(
"DjVu is disabled, please set \$wgDjvuRenderer and \$wgDjvuDump" );
72 return $file->
getSize() > static::EXPENSIVE_SIZE_LIMIT;
88 'img_width' =>
'width',
99 if ( $name ===
'page' && trim( $value ) !== (
string)intval( $value ) ) {
104 return in_array( $name, [
'width',
'height',
'page' ] ) && $value > 0;
112 $page = $params[
'page'] ?? 1;
113 if ( !isset( $params[
'width'] ) ) {
117 return "page{$page}-{$params['width']}px";
126 if ( preg_match(
'/^page(\d+)-(\d+)px$/', $str, $m ) ) {
127 return [
'width' => $m[2],
'page' => $m[1] ];
138 'width' => $params[
'width'],
139 'page' => $params[
'page'],
151 public function doTransform( $image, $dstPath, $dstUrl, $params, $flags = 0 ) {
152 $djvuRenderer = MediaWikiServices::getInstance()->getMainConfig()->get( MainConfigNames::DjvuRenderer );
153 $djvuPostProcessor = MediaWikiServices::getInstance()->getMainConfig()
154 ->get( MainConfigNames::DjvuPostProcessor );
158 $width = $params[
'width'];
159 $height = $params[
'height'];
160 $page = $params[
'page'];
162 if ( $flags & self::TRANSFORM_LATER ) {
184 if ( $image->getSize() >= 1e7 ) {
187 'doWork' =>
static function () use ( $image ) {
188 return $image->getLocalRefPath();
194 $srcPath = $image->getLocalRefPath();
197 if ( $srcPath ===
false ) {
199 sprintf(
'Thumbnail failed on %s: could not get local copy of "%s"',
203 $params[
'width'], $params[
'height'],
208 # Use a subshell (brackets) to aggregate stderr from both pipeline commands
209 # before redirecting it to the overall stdout. This works in both Linux and Windows XP.
210 $cmd =
'(' . Shell::escape(
214 "-size={$params['physicalWidth']}x{$params['physicalHeight']}",
216 if ( $djvuPostProcessor ) {
217 $cmd .=
" | {$djvuPostProcessor}";
219 $cmd .=
' > ' . Shell::escape( $dstPath ) .
') 2>&1';
220 wfDebug( __METHOD__ .
": $cmd" );
225 if ( $retval !== 0 || $removed ) {
246 private function getDjVuImage( $state,
$path ) {
247 $deja = $state->getHandlerState( self::STATE_DJVU_IMAGE );
250 $state->setHandlerState( self::STATE_DJVU_IMAGE, $deja );
262 private function getMetadataInternal(
File $file, $gettext ) {
263 $itemNames = [
'error',
'_error',
'data' ];
265 $itemNames[] =
'text';
269 if ( isset( $unser[
'error'] ) ) {
272 if ( isset( $unser[
'_error'] ) ) {
285 if ( $gettext && $image->getHandlerState( self::STATE_TEXT_TREE ) ) {
286 return $image->getHandlerState( self::STATE_TEXT_TREE );
288 if ( !$gettext && $image->getHandlerState( self::STATE_META_TREE ) ) {
289 return $image->getHandlerState( self::STATE_META_TREE );
292 $metadata = $this->getMetadataInternal( $image, $gettext );
298 unset( $metadata[
'text'] );
304 $djvuOutputExtension = MediaWikiServices::getInstance()->getMainConfig()
305 ->get( MainConfigNames::DjvuOutputExtension );
306 static $djvuMime =
null;
307 if ( $djvuMime ===
null ) {
308 $magic = MediaWikiServices::getInstance()->getMimeAnalyzer();
309 $djvuMime = $magic->getMimeTypeFromExtensionOrNull( $djvuOutputExtension );
312 return [ $djvuOutputExtension, $djvuMime ];
316 wfDebug(
"Getting DjVu metadata for $path" );
318 $djvuImage = $this->getDjVuImage( $state,
$path );
319 $metadata = $djvuImage->retrieveMetaData();
320 if ( $metadata ===
false ) {
322 $metadata = [
'error' =>
'Error extracting metadata' ];
324 return [
'metadata' => $metadata ] + $djvuImage->getImageSize();
339 return $info ? $info[
'pageCount'] :
false;
346 if ( $info && isset( $info[
'dimensionsByPage'][$index] ) ) {
347 return $info[
'dimensionsByPage'][$index];
354 $cache = MediaWikiServices::getInstance()->getMainWANObjectCache();
355 return $cache->getWithSetCallback(
356 $cache->makeKey(
'file-djvu',
'dimensions', self::CACHE_VERSION, $file->
getSha1() ),
357 $cache::TTL_INDEFINITE,
358 function () use ( $file ) {
362 [
'pcTTL' => $cache::TTL_INDEFINITE ]
377 if ( !isset( $metatree[
'data'] ) || !$metatree[
'data'] ) {
380 foreach ( $metatree[
'data'][
'pages'] as $page ) {
382 $dimsByPage[] =
false;
385 'width' => (int)$page[
'width'],
386 'height' => (
int)$page[
'height'],
391 'pageCount' => count( $metatree[
'data'][
'pages'] ),
392 'dimensionsByPage' => $dimsByPage
406 if ( isset( $tree[
'text'] ) && isset( $tree[
'text'][$page - 1] ) ) {
407 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.
getPageText(File $image, $page)
isFileMetadataValid( $image)
Check if the metadata is valid for this handler.
getSizeAndMetadata( $state, $path)
Get image size information and metadata array.
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.
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.
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.