From 8f416baead93a48e5799e44b8bd2e2c4859f4e04 Mon Sep 17 00:00:00 2001 From: Pierre Schmitz Date: Fri, 14 Sep 2007 13:18:58 +0200 Subject: auf Version 1.11 aktualisiert; Login-Bug behoben --- includes/media/BMP.php | 10 +-- includes/media/Bitmap.php | 91 ++++++++++++++++++++--- includes/media/DjVu.php | 16 ++-- includes/media/Generic.php | 179 ++++++++++++++++++++++++++++++++++++--------- includes/media/SVG.php | 21 ++++-- 5 files changed, 255 insertions(+), 62 deletions(-) (limited to 'includes/media') diff --git a/includes/media/BMP.php b/includes/media/BMP.php index 9917856a..2f451b0a 100644 --- a/includes/media/BMP.php +++ b/includes/media/BMP.php @@ -1,8 +1,8 @@ +} \ No newline at end of file diff --git a/includes/media/Bitmap.php b/includes/media/Bitmap.php index 3f3aabbf..ca82aab0 100644 --- a/includes/media/Bitmap.php +++ b/includes/media/Bitmap.php @@ -51,17 +51,20 @@ class BitmapHandler extends ImageHandler { $srcWidth = $image->getWidth(); $srcHeight = $image->getHeight(); $mimeType = $image->getMimeType(); - $srcPath = $image->getImagePath(); + $srcPath = $image->getPath(); $retval = 0; wfDebug( __METHOD__.": creating {$physicalWidth}x{$physicalHeight} thumbnail at $dstPath\n" ); if ( $physicalWidth == $srcWidth && $physicalHeight == $srcHeight ) { # normaliseParams (or the user) wants us to return the unscaled image wfDebug( __METHOD__.": returning unscaled image\n" ); - return new ThumbnailImage( $image->getURL(), $clientWidth, $clientHeight, $srcPath ); + return new ThumbnailImage( $image, $image->getURL(), $clientWidth, $clientHeight, $srcPath ); } - if ( $wgUseImageMagick ) { + if ( !$dstPath ) { + // No output path available, client side scaling only + $scaler = 'client'; + } elseif ( $wgUseImageMagick ) { $scaler = 'im'; } elseif ( $wgCustomConvertCommand ) { $scaler = 'custom'; @@ -74,11 +77,11 @@ class BitmapHandler extends ImageHandler { if ( $scaler == 'client' ) { # Client-side image scaling, use the source URL # Using the destination URL in a TRANSFORM_LATER request would be incorrect - return new ThumbnailImage( $image->getURL(), $clientWidth, $clientHeight, $srcPath ); + return new ThumbnailImage( $image, $image->getURL(), $clientWidth, $clientHeight, $srcPath ); } if ( $flags & self::TRANSFORM_LATER ) { - return new ThumbnailImage( $dstUrl, $clientWidth, $clientHeight, $dstPath ); + return new ThumbnailImage( $image, $dstUrl, $clientWidth, $clientHeight, $dstPath ); } if ( !wfMkdirParents( dirname( $dstPath ) ) ) { @@ -164,9 +167,27 @@ class BitmapHandler extends ImageHandler { $src_image = call_user_func( $loader, $srcPath ); $dst_image = imagecreatetruecolor( $physicalWidth, $physicalHeight ); - imagecopyresampled( $dst_image, $src_image, - 0,0,0,0, - $physicalWidth, $physicalHeight, imagesx( $src_image ), imagesy( $src_image ) ); + + // Initialise the destination image to transparent instead of + // the default solid black, to support PNG and GIF transparency nicely + $background = imagecolorallocate( $dst_image, 0, 0, 0 ); + imagecolortransparent( $dst_image, $background ); + imagealphablending( $dst_image, false ); + + if( $colorStyle == 'palette' ) { + // Don't resample for paletted GIF images. + // It may just uglify them, and completely breaks transparency. + imagecopyresized( $dst_image, $src_image, + 0,0,0,0, + $physicalWidth, $physicalHeight, imagesx( $src_image ), imagesy( $src_image ) ); + } else { + imagecopyresampled( $dst_image, $src_image, + 0,0,0,0, + $physicalWidth, $physicalHeight, imagesx( $src_image ), imagesy( $src_image ) ); + } + + imagesavealpha( $dst_image, true ); + call_user_func( $saveType, $dst_image, $dstPath ); imagedestroy( $dst_image ); imagedestroy( $src_image ); @@ -180,7 +201,7 @@ class BitmapHandler extends ImageHandler { wfHostname(), $retval, trim($err), $cmd ) ); return new MediaTransformError( 'thumbnail_error', $clientWidth, $clientHeight, $err ); } else { - return new ThumbnailImage( $dstUrl, $clientWidth, $clientHeight, $dstPath ); + return new ThumbnailImage( $image, $dstUrl, $clientWidth, $clientHeight, $dstPath ); } } @@ -231,6 +252,56 @@ class BitmapHandler extends ImageHandler { return true; } + /** + * Get a list of EXIF metadata items which should be displayed when + * the metadata table is collapsed. + * + * @return array of strings + * @access private + */ + function visibleMetadataFields() { + $fields = array(); + $lines = explode( "\n", wfMsgForContent( 'metadata-fields' ) ); + foreach( $lines as $line ) { + $matches = array(); + if( preg_match( '/^\\*\s*(.*?)\s*$/', $line, $matches ) ) { + $fields[] = $matches[1]; + } + } + $fields = array_map( 'strtolower', $fields ); + return $fields; + } + + function formatMetadata( $image ) { + $result = array( + 'visible' => array(), + 'collapsed' => array() + ); + $metadata = $image->getMetadata(); + if ( !$metadata ) { + return false; + } + $exif = unserialize( $metadata ); + if ( !$exif ) { + return false; + } + unset( $exif['MEDIAWIKI_EXIF_VERSION'] ); + $format = new FormatExif( $exif ); + + $formatted = $format->getFormattedData(); + // Sort fields into visible and collapsed + $visibleFields = $this->visibleMetadataFields(); + foreach ( $formatted as $name => $value ) { + $tag = strtolower( $name ); + self::addMeta( $result, + in_array( $tag, $visibleFields ) ? 'visible' : 'collapsed', + 'exif', + $tag, + $value + ); + } + return $result; + } } -?> + diff --git a/includes/media/DjVu.php b/includes/media/DjVu.php index 3c053a0c..20e59d18 100644 --- a/includes/media/DjVu.php +++ b/includes/media/DjVu.php @@ -17,6 +17,13 @@ class DjVuHandler extends ImageHandler { function mustRender() { return true; } function isMultiPage() { return true; } + function getParamMap() { + return array( + 'img_width' => 'width', + 'img_page' => 'page', + ); + } + function validateParam( $name, $value ) { if ( in_array( $name, array( 'width', 'height', 'page' ) ) ) { if ( $value <= 0 ) { @@ -69,15 +76,14 @@ class DjVuHandler extends ImageHandler { } $width = $params['width']; $height = $params['height']; - $srcPath = $image->getImagePath(); + $srcPath = $image->getPath(); $page = $params['page']; - $pageCount = $this->pageCount( $image ); if ( $page > $this->pageCount( $image ) ) { return new MediaTransformError( 'thumbnail_error', $width, $height, wfMsg( 'djvu_page_error' ) ); } if ( $flags & self::TRANSFORM_LATER ) { - return new ThumbnailImage( $dstUrl, $width, $height, $dstPath ); + return new ThumbnailImage( $image, $dstUrl, $width, $height, $dstPath, $page ); } if ( !wfMkdirParents( dirname( $dstPath ) ) ) { @@ -104,7 +110,7 @@ class DjVuHandler extends ImageHandler { wfHostname(), $retval, trim($err), $cmd ) ); return new MediaTransformError( 'thumbnail_error', $width, $height, $err ); } else { - return new ThumbnailImage( $dstUrl, $width, $height, $dstPath ); + return new ThumbnailImage( $image, $dstUrl, $width, $height, $dstPath, $page ); } } @@ -203,4 +209,4 @@ class DjVuHandler extends ImageHandler { } } -?> + diff --git a/includes/media/Generic.php b/includes/media/Generic.php index 5254e0ea..c7ab7d81 100644 --- a/includes/media/Generic.php +++ b/includes/media/Generic.php @@ -36,6 +36,12 @@ abstract class MediaHandler { return self::$handlers[$class]; } + /** + * Get an associative array mapping magic word IDs to parameter names. + * Will be used by the parser to identify parameters. + */ + abstract function getParamMap(); + /* * Validate a thumbnail parameter at parse time. * Return true to accept the parameter, and false to reject it. @@ -126,20 +132,20 @@ abstract class MediaHandler { /** * True if the handled types can be transformed */ - function canRender() { return true; } + function canRender( $file ) { return true; } /** * True if handled types cannot be displayed directly in a browser * but can be rendered */ - function mustRender() { return false; } + function mustRender( $file ) { return false; } /** * True if the type has multi-page capabilities */ - function isMultiPage() { return false; } + function isMultiPage( $file ) { return false; } /** * Page count for a multi-page document, false if unsupported or unknown */ - function pageCount() { return false; } + function pageCount( $file ) { return false; } /** * False if the handler is disabled for all files */ @@ -152,12 +158,102 @@ abstract class MediaHandler { * Returns false if unknown or if the document is not multi-page. */ function getPageDimensions( $image, $page ) { - $gis = $this->getImageSize( $image, $image->getImagePath() ); + $gis = $this->getImageSize( $image, $image->getPath() ); return array( 'width' => $gis[0], 'height' => $gis[1] ); } + + /** + * Get an array structure that looks like this: + * + * array( + * 'visible' => array( + * 'Human-readable name' => 'Human readable value', + * ... + * ), + * 'collapsed' => array( + * 'Human-readable name' => 'Human readable value', + * ... + * ) + * ) + * The UI will format this into a table where the visible fields are always + * visible, and the collapsed fields are optionally visible. + * + * The function should return false if there is no metadata to display. + */ + + /** + * FIXME: I don't really like this interface, it's not very flexible + * I think the media handler should generate HTML instead. It can do + * all the formatting according to some standard. That makes it possible + * to do things like visual indication of grouped and chained streams + * in ogg container files. + */ + function formatMetadata( $image, $metadata ) { + return false; + } + + /** + * @fixme document this! + * 'value' thingy goes into a wikitext table; it used to be escaped but + * that was incompatible with previous practice of customized display + * with wikitext formatting via messages such as 'exif-model-value'. + * So the escaping is taken back out, but generally this seems a confusing + * interface. + */ + protected static function addMeta( &$array, $visibility, $type, $id, $value, $param = false ) { + $array[$visibility][] = array( + 'id' => "$type-$id", + 'name' => wfMsg( "$type-$id", $param ), + 'value' => $value + ); + } + + function getShortDesc( $file ) { + global $wgLang; + $nbytes = '(' . wfMsgExt( 'nbytes', array( 'parsemag', 'escape' ), + $wgLang->formatNum( $file->getSize() ) ) . ')'; + return "$nbytes"; + } + + function getLongDesc( $file ) { + global $wgUser; + $sk = $wgUser->getSkin(); + return wfMsg( 'file-info', $sk->formatSize( $file->getSize() ), $file->getMimeType() ); + } + + function getDimensionsString() { + return ''; + } + + /** + * Modify the parser object post-transform + */ + function parserTransformHook( $parser, $file ) {} + + /** + * Check for zero-sized thumbnails. These can be generated when + * no disk space is available or some other error occurs + * + * @param $dstPath The location of the suspect file + * @param $retval Return value of some shell process, file will be deleted if this is non-zero + * @return true if removed, false otherwise + */ + function removeBadFile( $dstPath, $retval = 0 ) { + if( file_exists( $dstPath ) ) { + $thumbstat = stat( $dstPath ); + if( $thumbstat['size'] == 0 || $retval != 0 ) { + wfDebugLog( 'thumbnail', + sprintf( 'Removing bad %d-byte thumbnail "%s"', + $thumbstat['size'], $dstPath ) ); + unlink( $dstPath ); + return true; + } + } + return false; + } } /** @@ -166,6 +262,18 @@ abstract class MediaHandler { * @addtogroup Media */ abstract class ImageHandler extends MediaHandler { + function canRender( $file ) { + if ( $file->getWidth() && $file->getHeight() ) { + return true; + } else { + return false; + } + } + + function getParamMap() { + return array( 'img_width' => 'width' ); + } + function validateParam( $name, $value ) { if ( in_array( $name, array( 'width', 'height' ) ) ) { if ( $value <= 0 ) { @@ -181,8 +289,10 @@ abstract class ImageHandler extends MediaHandler { function makeParamString( $params ) { if ( isset( $params['physicalWidth'] ) ) { $width = $params['physicalWidth']; - } else { + } elseif ( isset( $params['width'] ) ) { $width = $params['width']; + } else { + throw new MWException( 'No width specified to '.__METHOD__ ); } # Removed for ProofreadPage #$width = intval( $width ); @@ -218,7 +328,7 @@ abstract class ImageHandler extends MediaHandler { $params['width'] = wfFitBoxWidth( $srcWidth, $srcHeight, $params['height'] ); } } - $params['height'] = Image::scaleHeight( $srcWidth, $srcHeight, $params['width'] ); + $params['height'] = File::scaleHeight( $srcWidth, $srcHeight, $params['width'] ); if ( !$this->validateThumbParams( $params['width'], $params['height'], $srcWidth, $srcHeight, $mimeType ) ) { return false; } @@ -252,7 +362,7 @@ abstract class ImageHandler extends MediaHandler { return false; } - $height = Image::scaleHeight( $srcWidth, $srcHeight, $width ); + $height = File::scaleHeight( $srcWidth, $srcHeight, $width ); return true; } @@ -261,30 +371,8 @@ abstract class ImageHandler extends MediaHandler { return false; } $url = $script . '&' . wfArrayToCGI( $this->getScriptParams( $params ) ); - return new ThumbnailImage( $url, $params['width'], $params['height'] ); - } - - /** - * Check for zero-sized thumbnails. These can be generated when - * no disk space is available or some other error occurs - * - * @param $dstPath The location of the suspect file - * @param $retval Return value of some shell process, file will be deleted if this is non-zero - * @return true if removed, false otherwise - */ - function removeBadFile( $dstPath, $retval = 0 ) { - $removed = false; - if( file_exists( $dstPath ) ) { - $thumbstat = stat( $dstPath ); - if( $thumbstat['size'] == 0 || $retval != 0 ) { - wfDebugLog( 'thumbnail', - sprintf( 'Removing bad %d-byte thumbnail "%s"', - $thumbstat['size'], $dstPath ) ); - unlink( $dstPath ); - return true; - } - } - return false; + $page = isset( $params['page'] ) ? $params['page'] : false; + return new ThumbnailImage( $image, $url, $params['width'], $params['height'], $page ); } function getImageSize( $image, $path ) { @@ -293,6 +381,31 @@ abstract class ImageHandler extends MediaHandler { wfRestoreWarnings(); return $gis; } + + function getShortDesc( $file ) { + global $wgLang; + $nbytes = '(' . wfMsgExt( 'nbytes', array( 'parsemag', 'escape' ), + $wgLang->formatNum( $file->getSize() ) ) . ')'; + $widthheight = wfMsgHtml( 'widthheight', $file->getWidth(), $file->getHeight() ); + + return "$widthheight ($nbytes)"; + } + + function getLongDesc( $file ) { + global $wgLang; + return wfMsgHtml('file-info-size', $file->getWidth(), $file->getHeight(), + $wgLang->formatSize( $file->getSize() ), $file->getMimeType() ); + } + + function getDimensionsString( $file ) { + $pages = $file->pageCount(); + if ( $pages > 1 ) { + return wfMsg( 'widthheightpage', $file->getWidth(), $file->getHeight(), $pages ); + } else { + return wfMsg( 'widthheight', $file->getWidth(), $file->getHeight() ); + } + } } -?> + + diff --git a/includes/media/SVG.php b/includes/media/SVG.php index 5307e269..75d0ad3d 100644 --- a/includes/media/SVG.php +++ b/includes/media/SVG.php @@ -14,7 +14,7 @@ class SvgHandler extends ImageHandler { } } - function mustRender() { + function mustRender( $file ) { return true; } @@ -31,7 +31,7 @@ class SvgHandler extends ImageHandler { $srcWidth = $image->getWidth( $params['page'] ); $srcHeight = $image->getHeight( $params['page'] ); $params['physicalWidth'] = $wgSVGMaxSize; - $params['physicalHeight'] = Image::scaleHeight( $srcWidth, $srcHeight, $wgSVGMaxSize ); + $params['physicalHeight'] = File::scaleHeight( $srcWidth, $srcHeight, $wgSVGMaxSize ); } return true; } @@ -46,12 +46,10 @@ class SvgHandler extends ImageHandler { $clientHeight = $params['height']; $physicalWidth = $params['physicalWidth']; $physicalHeight = $params['physicalHeight']; - $srcWidth = $image->getWidth(); - $srcHeight = $image->getHeight(); - $srcPath = $image->getImagePath(); + $srcPath = $image->getPath(); if ( $flags & self::TRANSFORM_LATER ) { - return new ThumbnailImage( $dstUrl, $clientWidth, $clientHeight, $dstPath ); + return new ThumbnailImage( $image, $dstUrl, $clientWidth, $clientHeight, $dstPath ); } if ( !wfMkdirParents( dirname( $dstPath ) ) ) { @@ -82,7 +80,7 @@ class SvgHandler extends ImageHandler { wfHostname(), $retval, trim($err), $cmd ) ); return new MediaTransformError( 'thumbnail_error', $clientWidth, $clientHeight, $err ); } else { - return new ThumbnailImage( $dstUrl, $clientWidth, $clientHeight, $dstPath ); + return new ThumbnailImage( $image, $dstUrl, $clientWidth, $clientHeight, $dstPath ); } } @@ -93,5 +91,12 @@ class SvgHandler extends ImageHandler { function getThumbType( $ext, $mime ) { return array( 'png', 'image/png' ); } + + function getLongDesc( $file ) { + global $wgLang; + return wfMsg( 'svg-long-desc', $file->getWidth(), $file->getHeight(), + $wgLang->formatSize( $file->getSize() ) ); + } } -?> + + -- cgit v1.2.2