Merge "Add CLDRPluralRuleError, added in parent commit, to the AutoLoader"
[lhc/web/wiklou.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 /**
32 * @param $file File
33 * @return bool
34 */
35 function canRender( $file ) {
36 return ( $file->getWidth() && $file->getHeight() );
37 }
38
39 function getParamMap() {
40 return array( 'img_width' => 'width' );
41 }
42
43 function validateParam( $name, $value ) {
44 if ( in_array( $name, array( 'width', 'height' ) ) ) {
45 if ( $value <= 0 ) {
46 return false;
47 } else {
48 return true;
49 }
50 } else {
51 return false;
52 }
53 }
54
55 function makeParamString( $params ) {
56 if ( isset( $params['physicalWidth'] ) ) {
57 $width = $params['physicalWidth'];
58 } elseif ( isset( $params['width'] ) ) {
59 $width = $params['width'];
60 } else {
61 throw new MWException( 'No width specified to '.__METHOD__ );
62 }
63 # Removed for ProofreadPage
64 #$width = intval( $width );
65 return "{$width}px";
66 }
67
68 function parseParamString( $str ) {
69 $m = false;
70 if ( preg_match( '/^(\d+)px$/', $str, $m ) ) {
71 return array( 'width' => $m[1] );
72 } else {
73 return false;
74 }
75 }
76
77 function getScriptParams( $params ) {
78 return array( 'width' => $params['width'] );
79 }
80
81 /**
82 * @param $image File
83 * @param $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 if ( $params['page'] > $image->pageCount() ) {
97 $params['page'] = $image->pageCount();
98 }
99
100 if ( $params['page'] < 1 ) {
101 $params['page'] = 1;
102 }
103 }
104
105 $srcWidth = $image->getWidth( $params['page'] );
106 $srcHeight = $image->getHeight( $params['page'] );
107
108 if ( isset( $params['height'] ) && $params['height'] != -1 ) {
109 # Height & width were both set
110 if ( $params['width'] * $srcHeight > $params['height'] * $srcWidth ) {
111 # Height is the relative smaller dimension, so scale width accordingly
112 $params['width'] = self::fitBoxWidth( $srcWidth, $srcHeight, $params['height'] );
113
114 if ( $params['width'] == 0 ) {
115 # Very small image, so we need to rely on client side scaling :(
116 $params['width'] = 1;
117 }
118
119 $params['physicalWidth'] = $params['width'];
120 } else {
121 # Height was crap, unset it so that it will be calculated later
122 unset( $params['height'] );
123 }
124 }
125
126 if ( !isset( $params['physicalWidth'] ) ) {
127 # Passed all validations, so set the physicalWidth
128 $params['physicalWidth'] = $params['width'];
129 }
130
131 # Because thumbs are only referred to by width, the height always needs
132 # to be scaled by the width to keep the thumbnail sizes consistent,
133 # even if it was set inside the if block above
134 $params['physicalHeight'] = File::scaleHeight( $srcWidth, $srcHeight,
135 $params['physicalWidth'] );
136
137 # Set the height if it was not validated in the if block higher up
138 if ( !isset( $params['height'] ) || $params['height'] == -1 ) {
139 $params['height'] = $params['physicalHeight'];
140 }
141
142
143 if ( !$this->validateThumbParams( $params['physicalWidth'],
144 $params['physicalHeight'], $srcWidth, $srcHeight, $mimeType ) ) {
145 return false;
146 }
147 return true;
148 }
149
150 /**
151 * Validate thumbnail parameters and fill in the correct height
152 *
153 * @param $width Integer: specified width (input/output)
154 * @param $height Integer: height (output only)
155 * @param $srcWidth Integer: width of the source image
156 * @param $srcHeight Integer: height of the source image
157 * @param $mimeType
158 * @return bool False to indicate that an error should be returned to the user.
159 */
160 function validateThumbParams( &$width, &$height, $srcWidth, $srcHeight, $mimeType ) {
161 $width = intval( $width );
162
163 # Sanity check $width
164 if( $width <= 0) {
165 wfDebug( __METHOD__.": Invalid destination width: $width\n" );
166 return false;
167 }
168 if ( $srcWidth <= 0 ) {
169 wfDebug( __METHOD__.": Invalid source width: $srcWidth\n" );
170 return false;
171 }
172
173 $height = File::scaleHeight( $srcWidth, $srcHeight, $width );
174 if ( $height == 0 ) {
175 # Force height to be at least 1 pixel
176 $height = 1;
177 }
178 return true;
179 }
180
181 /**
182 * @param $image File
183 * @param $script
184 * @param $params
185 * @return bool|ThumbnailImage
186 */
187 function getScriptedTransform( $image, $script, $params ) {
188 if ( !$this->normaliseParams( $image, $params ) ) {
189 return false;
190 }
191 $url = $script . '&' . wfArrayToCGI( $this->getScriptParams( $params ) );
192 $page = isset( $params['page'] ) ? $params['page'] : false;
193
194 if( $image->mustRender() || $params['width'] < $image->getWidth() ) {
195 return new ThumbnailImage( $image,
196 $url, $params['width'], $params['height'], false, $page );
197 }
198 }
199
200 function getImageSize( $image, $path ) {
201 wfSuppressWarnings();
202 $gis = getimagesize( $path );
203 wfRestoreWarnings();
204 return $gis;
205 }
206
207 /**
208 * @param $file File
209 * @return string
210 */
211 function getShortDesc( $file ) {
212 global $wgLang;
213 $nbytes = htmlspecialchars( $wgLang->formatSize( $file->getSize() ) );
214 $widthheight = wfMessage( 'widthheight' )->numParams( $file->getWidth(), $file->getHeight() )->escaped();
215
216 return "$widthheight ($nbytes)";
217 }
218
219 /**
220 * @param $file File
221 * @return string
222 */
223 function getLongDesc( $file ) {
224 global $wgLang;
225 $pages = $file->pageCount();
226 $size = htmlspecialchars( $wgLang->formatSize( $file->getSize() ) );
227 if ( $pages === false || $pages <= 1 ) {
228 $msg = wfMessage( 'file-info-size' )->numParams( $file->getWidth(),
229 $file->getHeight() )->params( $size,
230 $file->getMimeType() )->parse();
231 } else {
232 $msg = wfMessage( 'file-info-size-pages' )->numParams( $file->getWidth(),
233 $file->getHeight() )->params( $size,
234 $file->getMimeType() )->numParams( $pages )->parse();
235 }
236 return $msg;
237 }
238
239 /**
240 * @param $file File
241 * @return string
242 */
243 function getDimensionsString( $file ) {
244 $pages = $file->pageCount();
245 if ( $pages > 1 ) {
246 return wfMessage( 'widthheightpage' )->numParams( $file->getWidth(), $file->getHeight(), $pages )->text();
247 } else {
248 return wfMessage( 'widthheight' )->numParams( $file->getWidth(), $file->getHeight() )->text();
249 }
250 }
251 }