/** * */ protected function streamThumbnail() { global $wgVipsThumbnailerHost, $wgVipsTestExpiry; $request = $this->getRequest(); # Validate title and file existance $title = Title::makeTitleSafe( NS_FILE, $request->getText( 'thumb' ) ); if ( is_null( $title ) ) { $this->streamError( 404, "VipsScaler: invalid title\n" ); return; } $file = wfFindFile( $title ); if ( !$file || !$file->exists() ) { $this->streamError( 404, "VipsScaler: file not found\n" ); return; } # Check if vips can handle this file if ( VipsScaler::getVipsHandler( $file ) === false ) { $this->streamError( 500, "VipsScaler: VIPS cannot handle this file type\n" ); return; } # Validate param string $handler = $file->getHandler(); $params = array( 'width' => $request->getInt( 'width' ) ); if ( !$handler->normaliseParams( $file, $params ) ) { $this->streamError( 500, "VipsScaler: invalid parameters\n" ); return; } # Get the thumbnail if ( is_null( $wgVipsThumbnailerHost ) || $request->getBool( 'noproxy' ) ) { # No remote scaler, need to do it ourselves. # Emulate the BitmapHandlerTransform hook $dstPath = VipsCommand::makeTemp( $file->getExtension() ); $dstUrl = ''; wfDebug( __METHOD__ . ": Creating vips thumbnail at $dstPath\n" ); $scalerParams = array( # The size to which the image will be resized 'physicalWidth' => $params['physicalWidth'], 'physicalHeight' => $params['physicalHeight'], 'physicalDimensions' => "{$params['physicalWidth']}x{$params['physicalHeight']}", # The size of the image on the page 'clientWidth' => $params['width'], 'clientHeight' => $params['height'], # Comment as will be added to the EXIF of the thumbnail 'comment' => isset( $params['descriptionUrl'] ) ? "File source: {$params['descriptionUrl']}" : '', # Properties of the original image 'srcWidth' => $file->getWidth(), 'srcHeight' => $file->getHeight(), 'mimeType' => $file->getMimeType(), 'srcPath' => $file->getPath(), 'dstPath' => $dstPath, 'dstUrl' => $dstUrl, ); $options = array(); if ( $request->getBool( 'bilinear' ) ) { $options['bilinear'] = true; wfDebug( __METHOD__ . ": using bilinear scaling\n" ); } if ( $request->getVal( 'sharpen' ) && $request->getVal( 'sharpen' ) < 5 ) { # Limit sharpen sigma to 5, otherwise we have to write huge convolution matrices $options['sharpen'] = array( 'sigma' => floatval( $request->getVal( 'sharpen' ) ) ); wfDebug( __METHOD__ . ": sharpening with radius {$options['sharpen']}\n" ); } # Call the hook $mto = null; VipsScaler::doTransform( $handler, $file, $scalerParams, $options, $mto ); if ( $mto && !$mto->isError() ) { wfDebug( __METHOD__ . ": streaming thumbnail...\n" ); $this->getOutput()->disable(); StreamFile::stream( $dstPath, array( "Cache-Control: public, max-age=$wgVipsTestExpiry, s-maxage=$wgVipsTestExpiry", 'Expires: ' . gmdate( 'r ', time() + $wgVipsTestExpiry ) ) ); } else { $this->streamError( 500, $mto->getHtmlMsg() ); } # Cleanup the temporary file wfSuppressWarnings(); unlink( $dstPath ); wfRestoreWarnings(); } else { # Request the thumbnail at a remote scaler $url = wfExpandUrl( $request->getRequestURL(), PROTO_INTERNAL ); $url = wfAppendQuery( $url, array( 'noproxy' => '1' ) ); wfDebug( __METHOD__ . ": Getting vips thumb from remote url $url\n" ); $bits = IP::splitHostAndPort( $wgVipsThumbnailerHost ); if ( !$bits ) { throw new MWException( __METHOD__.': $wgVipsThumbnailerHost is not set to a valid host' ); } list( $host, $port ) = $bits; if ( $port === false ) { $port = 80; } $proxy = IP::combineHostAndPort( $host, $port ); $options = array( 'method' => 'GET', 'proxy' => $proxy, ); $req = MWHttpRequest::factory( $url, $options ); $status = $req->execute(); if ( $status->isOk() ) { # Disable output and stream the file $this->getOutput()->disable(); wfResetOutputBuffers(); header( 'Content-Type: ' . $file->getMimeType() ); header( 'Content-Length: ' . strlen( $req->getContent() ) ); header( "Cache-Control: public, max-age=$wgVipsTestExpiry, s-maxage=$wgVipsTestExpiry" ); header( 'Expires: ' . gmdate( 'r ', time() + $wgVipsTestExpiry ) ); print $req->getContent(); } elseif ( $status->hasMessage( 'http-bad-status' ) ) { $this->streamError( 500, $req->getContent() ); return; } else { global $wgOut; $this->streamError( 500, $wgOut->parse( $status->getWikiText() ) ); return; } } }
/** * @return int */ public function execute() { # Convert a 2D array into a space/newline separated matrix $convolutionMatrix = array_pop( $this->args ); $convolutionString = ''; foreach ( $convolutionMatrix as $row ) { $convolutionString .= implode( ' ', $row ) . "\n"; } # Save the matrix in a tempfile $convolutionFile = self::makeTemp( 'conv' ); file_put_contents( $convolutionFile, $convolutionString ); array_push( $this->args, $convolutionFile ); wfDebug( __METHOD__ . ": Convolving image [\n" . $convolutionString . "] \n" ); # Call the parent to actually execute the command $retval = parent::execute(); # Remove the temporary matrix file unlink( $convolutionFile ); return $retval; }