]> scripts.mit.edu Git - autoinstallsdev/mediawiki.git/blob - includes/media/ImageHandler.php
MediaWiki 1.30.2
[autoinstallsdev/mediawiki.git] / includes / media / ImageHandler.php
1 <?php
2 /**
3  * Media-handling base classes and generic functionality.
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License along
16  * with this program; if not, write to the Free Software Foundation, Inc.,
17  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18  * http://www.gnu.org/copyleft/gpl.html
19  *
20  * @file
21  * @ingroup Media
22  */
23
24 /**
25  * Media handler abstract base class for images
26  *
27  * @ingroup Media
28  */
29 abstract class ImageHandler extends MediaHandler {
30         /**
31          * @param File $file
32          * @return bool
33          */
34         public function canRender( $file ) {
35                 return ( $file->getWidth() && $file->getHeight() );
36         }
37
38         public function getParamMap() {
39                 return [ 'img_width' => 'width' ];
40         }
41
42         public function validateParam( $name, $value ) {
43                 if ( in_array( $name, [ 'width', 'height' ] ) ) {
44                         if ( $value <= 0 ) {
45                                 return false;
46                         } else {
47                                 return true;
48                         }
49                 } else {
50                         return false;
51                 }
52         }
53
54         public function makeParamString( $params ) {
55                 if ( isset( $params['physicalWidth'] ) ) {
56                         $width = $params['physicalWidth'];
57                 } elseif ( isset( $params['width'] ) ) {
58                         $width = $params['width'];
59                 } else {
60                         throw new MediaTransformInvalidParametersException( 'No width specified to ' . __METHOD__ );
61                 }
62
63                 # Removed for ProofreadPage
64                 # $width = intval( $width );
65                 return "{$width}px";
66         }
67
68         public function parseParamString( $str ) {
69                 $m = false;
70                 if ( preg_match( '/^(\d+)px$/', $str, $m ) ) {
71                         return [ 'width' => $m[1] ];
72                 } else {
73                         return false;
74                 }
75         }
76
77         function getScriptParams( $params ) {
78                 return [ 'width' => $params['width'] ];
79         }
80
81         /**
82          * @param File $image
83          * @param array &$params
84          * @return bool
85          */
86         function normaliseParams( $image, &$params ) {
87                 $mimeType = $image->getMimeType();
88
89                 if ( !isset( $params['width'] ) ) {
90                         return false;
91                 }
92
93                 if ( !isset( $params['page'] ) ) {
94                         $params['page'] = 1;
95                 } else {
96                         $params['page'] = intval( $params['page'] );
97                         if ( $params['page'] > $image->pageCount() ) {
98                                 $params['page'] = $image->pageCount();
99                         }
100
101                         if ( $params['page'] < 1 ) {
102                                 $params['page'] = 1;
103                         }
104                 }
105
106                 $srcWidth = $image->getWidth( $params['page'] );
107                 $srcHeight = $image->getHeight( $params['page'] );
108
109                 if ( isset( $params['height'] ) && $params['height'] != -1 ) {
110                         # Height & width were both set
111                         if ( $params['width'] * $srcHeight > $params['height'] * $srcWidth ) {
112                                 # Height is the relative smaller dimension, so scale width accordingly
113                                 $params['width'] = self::fitBoxWidth( $srcWidth, $srcHeight, $params['height'] );
114
115                                 if ( $params['width'] == 0 ) {
116                                         # Very small image, so we need to rely on client side scaling :(
117                                         $params['width'] = 1;
118                                 }
119
120                                 $params['physicalWidth'] = $params['width'];
121                         } else {
122                                 # Height was crap, unset it so that it will be calculated later
123                                 unset( $params['height'] );
124                         }
125                 }
126
127                 if ( !isset( $params['physicalWidth'] ) ) {
128                         # Passed all validations, so set the physicalWidth
129                         $params['physicalWidth'] = $params['width'];
130                 }
131
132                 # Because thumbs are only referred to by width, the height always needs
133                 # to be scaled by the width to keep the thumbnail sizes consistent,
134                 # even if it was set inside the if block above
135                 $params['physicalHeight'] = File::scaleHeight( $srcWidth, $srcHeight,
136                         $params['physicalWidth'] );
137
138                 # Set the height if it was not validated in the if block higher up
139                 if ( !isset( $params['height'] ) || $params['height'] == -1 ) {
140                         $params['height'] = $params['physicalHeight'];
141                 }
142
143                 if ( !$this->validateThumbParams( $params['physicalWidth'],
144                         $params['physicalHeight'], $srcWidth, $srcHeight, $mimeType )
145                 ) {
146                         return false;
147                 }
148
149                 return true;
150         }
151
152         /**
153          * Validate thumbnail parameters and fill in the correct height
154          *
155          * @param int &$width Specified width (input/output)
156          * @param int &$height Height (output only)
157          * @param int $srcWidth Width of the source image
158          * @param int $srcHeight Height of the source image
159          * @param string $mimeType Unused
160          * @return bool False to indicate that an error should be returned to the user.
161          */
162         function validateThumbParams( &$width, &$height, $srcWidth, $srcHeight, $mimeType ) {
163                 $width = intval( $width );
164
165                 # Sanity check $width
166                 if ( $width <= 0 ) {
167                         wfDebug( __METHOD__ . ": Invalid destination width: $width\n" );
168
169                         return false;
170                 }
171                 if ( $srcWidth <= 0 ) {
172                         wfDebug( __METHOD__ . ": Invalid source width: $srcWidth\n" );
173
174                         return false;
175                 }
176
177                 $height = File::scaleHeight( $srcWidth, $srcHeight, $width );
178                 if ( $height == 0 ) {
179                         # Force height to be at least 1 pixel
180                         $height = 1;
181                 }
182
183                 return true;
184         }
185
186         /**
187          * @param File $image
188          * @param string $script
189          * @param array $params
190          * @return bool|MediaTransformOutput
191          */
192         function getScriptedTransform( $image, $script, $params ) {
193                 if ( !$this->normaliseParams( $image, $params ) ) {
194                         return false;
195                 }
196                 $url = wfAppendQuery( $script, $this->getScriptParams( $params ) );
197
198                 if ( $image->mustRender() || $params['width'] < $image->getWidth() ) {
199                         return new ThumbnailImage( $image, $url, false, $params );
200                 }
201         }
202
203         function getImageSize( $image, $path ) {
204                 MediaWiki\suppressWarnings();
205                 $gis = getimagesize( $path );
206                 MediaWiki\restoreWarnings();
207
208                 return $gis;
209         }
210
211         /**
212          * Function that returns the number of pixels to be thumbnailed.
213          * Intended for animated GIFs to multiply by the number of frames.
214          *
215          * If the file doesn't support a notion of "area" return 0.
216          *
217          * @param File $image
218          * @return int
219          */
220         function getImageArea( $image ) {
221                 return $image->getWidth() * $image->getHeight();
222         }
223
224         /**
225          * @param File $file
226          * @return string
227          */
228         function getShortDesc( $file ) {
229                 global $wgLang;
230                 $nbytes = htmlspecialchars( $wgLang->formatSize( $file->getSize() ) );
231                 $widthheight = wfMessage( 'widthheight' )
232                         ->numParams( $file->getWidth(), $file->getHeight() )->escaped();
233
234                 return "$widthheight ($nbytes)";
235         }
236
237         /**
238          * @param File $file
239          * @return string
240          */
241         function getLongDesc( $file ) {
242                 global $wgLang;
243                 $pages = $file->pageCount();
244                 $size = htmlspecialchars( $wgLang->formatSize( $file->getSize() ) );
245                 if ( $pages === false || $pages <= 1 ) {
246                         $msg = wfMessage( 'file-info-size' )->numParams( $file->getWidth(),
247                                 $file->getHeight() )->params( $size,
248                                         '<span class="mime-type">' . $file->getMimeType() . '</span>' )->parse();
249                 } else {
250                         $msg = wfMessage( 'file-info-size-pages' )->numParams( $file->getWidth(),
251                                 $file->getHeight() )->params( $size,
252                                         '<span class="mime-type">' . $file->getMimeType() . '</span>' )->numParams( $pages )->parse();
253                 }
254
255                 return $msg;
256         }
257
258         /**
259          * @param File $file
260          * @return string
261          */
262         function getDimensionsString( $file ) {
263                 $pages = $file->pageCount();
264                 if ( $pages > 1 ) {
265                         return wfMessage( 'widthheightpage' )
266                                 ->numParams( $file->getWidth(), $file->getHeight(), $pages )->text();
267                 } else {
268                         return wfMessage( 'widthheight' )
269                                 ->numParams( $file->getWidth(), $file->getHeight() )->text();
270                 }
271         }
272
273         public function sanitizeParamsForBucketing( $params ) {
274                 $params = parent::sanitizeParamsForBucketing( $params );
275
276                 // We unset the height parameters in order to let normaliseParams recalculate them
277                 // Otherwise there might be a height discrepancy
278                 if ( isset( $params['height'] ) ) {
279                         unset( $params['height'] );
280                 }
281
282                 if ( isset( $params['physicalHeight'] ) ) {
283                         unset( $params['physicalHeight'] );
284                 }
285
286                 return $params;
287         }
288 }