Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 54
0.00% covered (danger)
0.00%
0 / 7
CRAP
0.00% covered (danger)
0.00%
0 / 1
ThreeDHandler
0.00% covered (danger)
0.00%
0 / 54
0.00% covered (danger)
0.00%
0 / 7
210
0.00% covered (danger)
0.00%
0 / 1
 mustRender
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 isVectorized
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 normaliseParams
0.00% covered (danger)
0.00%
0 / 16
0.00% covered (danger)
0.00%
0 / 1
30
 doTransform
0.00% covered (danger)
0.00%
0 / 33
0.00% covered (danger)
0.00%
0 / 1
20
 getImageSize
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getThumbType
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 parserTransformHook
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2
3namespace MediaWiki\Extension\ThreeD;
4
5use File;
6use ImageHandler;
7use MediaTransformError;
8use MediaTransformOutput;
9use MediaWiki\Shell\Shell;
10use Parser;
11use ThumbnailImage;
12use TransformParameterError;
13
14/**
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License along
27 * with this program; if not, write to the Free Software Foundation, Inc.,
28 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
29 * http://www.gnu.org/copyleft/gpl.html
30 */
31
32class ThreeDHandler extends ImageHandler {
33    /**
34     * @param File $file
35     * @return bool
36     */
37    public function mustRender( $file ) {
38        return true;
39    }
40
41    /**
42     * @param File $file
43     * @return bool
44     */
45    public function isVectorized( $file ) {
46        return true;
47    }
48
49    /**
50     * @param File $image
51     * @param array &$params
52     * @return bool
53     */
54    public function normaliseParams( $image, &$params ) {
55        global $wgSVGMaxSize;
56        if ( !parent::normaliseParams( $image, $params ) ) {
57            return false;
58        }
59        // Note: the annotation below is incomplete to save up space, expand if necessary
60        '@phan-var array{physicalWidth:int,physicalHeight:int} $params';
61
62        // Don't make an image bigger than wgMaxSVGSize on the smaller side
63        if ( $params['physicalWidth'] <= $params['physicalHeight'] ) {
64            if ( $params['physicalWidth'] > $wgSVGMaxSize ) {
65                $srcWidth = $image->getWidth();
66                $srcHeight = $image->getHeight();
67                $params['physicalWidth'] = $wgSVGMaxSize;
68                $params['physicalHeight'] = File::scaleHeight( $srcWidth, $srcHeight, $wgSVGMaxSize );
69            }
70        } else {
71            if ( $params['physicalHeight'] > $wgSVGMaxSize ) {
72                $srcWidth = $image->getWidth();
73                $srcHeight = $image->getHeight();
74                $params['physicalWidth'] = File::scaleHeight( $srcHeight, $srcWidth, $wgSVGMaxSize );
75                $params['physicalHeight'] = $wgSVGMaxSize;
76            }
77        }
78
79        return true;
80    }
81
82    /**
83     * @param File $image
84     * @param string $dstPath
85     * @param string $dstUrl
86     * @param array $params
87     * @param int $flags
88     *
89     * @return MediaTransformError|MediaTransformOutput|ThumbnailImage|TransformParameterError
90     */
91    public function doTransform( $image, $dstPath, $dstUrl, $params, $flags = 0 ) {
92        global $wg3dProcessor, $wg3dProcessEnviron, $wgMax3d2pngMemory;
93
94        // Impose an aspect ratio
95        $params['height'] = (int)round( $params['width'] / ( 640 / 480 ) );
96
97        if ( $flags & self::TRANSFORM_LATER ) {
98            return new ThreeDThumbnailImage( $image, $dstUrl, $dstPath, $params );
99        }
100
101        $width = $params['width'];
102        $height = $params['height'];
103
104        if ( !wfMkdirParents( dirname( $dstPath ), null, __METHOD__ ) ) {
105            return new MediaTransformError(
106                'thumbnail_error',
107                $width,
108                $height,
109                wfMessage( 'thumbnail_dest_directory' )
110            );
111        }
112
113        $srcPath = $image->getLocalRefPath();
114
115        // $wg3dProcessor can be string (e.g. '/path/to/3d2png.js') or array
116        // (e.g. ['xvfb-run', '-a', '-s', '-ac -screen 0 1280x1024x24', '/path/to/3d2png.js'])
117        $cmd = Shell::command( array_merge( (array)$wg3dProcessor,
118            [
119                $srcPath,
120                sprintf( '%dx%d', $width, $height ),
121                $dstPath,
122            ] )
123        )
124            ->limits( [ 'memory' => $wgMax3d2pngMemory ] )
125            ->environment( $wg3dProcessEnviron )
126            ->profileMethod( __METHOD__ );
127
128        $result = $cmd->execute();
129
130        if ( $result->getExitCode() !== 0 ) {
131            $err = trim( $result->getStdout() );
132            wfDebugLog( 'thumbnail',
133                sprintf( 'thumbnail failed on %s: error %d "%s" from "%s"',
134                wfHostname(), $result->getExitCode(), $err, $cmd )
135            );
136            return new MediaTransformError( 'thumbnail_error', $width, $height, $err );
137        } else {
138            return new ThreeDThumbnailImage( $image, $dstUrl, $dstPath, $params );
139        }
140    }
141
142    /**
143     * @param File $file
144     * @param string $path Unused
145     * @param bool|array $metadata
146     * @return array
147     */
148    public function getImageSize( $file, $path, $metadata = false ) {
149        return [ 5120, 2880 ];
150    }
151
152    /**
153     * @param string $ext
154     * @param string $mime
155     * @param array|null $params
156     * @return array
157     */
158    public function getThumbType( $ext, $mime, $params = null ) {
159        return [ 'png', 'image/png' ];
160    }
161
162    /**
163     * @param Parser $parser
164     * @param File $file
165     */
166    public function parserTransformHook( $parser, $file ) {
167        $parser->getOutput()->addModuleStyles( [ 'ext.3d.styles' ] );
168    }
169
170}