mirror of
https://github.com/gnosygnu/xowa.git
synced 2026-03-02 03:49:30 +00:00
Xomw: Move Mw_parse classes into separate project
This commit is contained in:
@@ -0,0 +1,304 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.xowa.mediawiki.includes.media; import gplx.*; import gplx.xowa.*; import gplx.xowa.mediawiki.*; import gplx.xowa.mediawiki.includes.*;
|
||||
import gplx.xowa.mediawiki.includes.filerepo.file.*; import gplx.xowa.mediawiki.includes.parsers.lnkis.*;
|
||||
import gplx.xowa.mediawiki.includes.utls.*;
|
||||
/* XO.TODO:
|
||||
* validateThumbParams
|
||||
*/
|
||||
// MEMORY:only one instance per wiki
|
||||
public abstract class Xomw_ImageHandler extends Xomw_MediaHandler { private final Xomw_param_map paramMap = new Xomw_param_map();
|
||||
public Xomw_ImageHandler(byte[] key) {super(key);
|
||||
paramMap.Add(Xomw_param_itm.Mw__img_width, Xomw_param_map.Type__handler, Xomw_param_itm.Name_bry__width);
|
||||
}
|
||||
/**
|
||||
* @param File file
|
||||
* @return boolean
|
||||
*/
|
||||
@Override public boolean canRender(Xomw_File file) {
|
||||
return (Php_utl_.istrue(file.getWidth()) && Php_utl_.istrue(file.getHeight()));
|
||||
}
|
||||
|
||||
@Override public Xomw_param_map getParamMap() {
|
||||
// XO.MW: defined above: "return [ 'img_width' => 'width' ];"
|
||||
return paramMap;
|
||||
}
|
||||
|
||||
@Override public boolean validateParam(int name_uid, byte[] val_bry, int val_int) {
|
||||
if (name_uid == Xomw_param_itm.Name__width || name_uid == Xomw_param_itm.Name__height) {
|
||||
if (val_int <= 0) {
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override public byte[] makeParamString(Xomw_params_handler handlerParams) {
|
||||
int width = 0;
|
||||
if (Php_utl_.isset(handlerParams.physicalWidth)) {
|
||||
width = handlerParams.physicalWidth;
|
||||
}
|
||||
else if (Php_utl_.isset(handlerParams.width)) {
|
||||
width = handlerParams.width;
|
||||
}
|
||||
else {
|
||||
throw Err_.new_wo_type("No width specified to makeParamString");
|
||||
}
|
||||
|
||||
// Removed for ProofreadPage
|
||||
// width = intval(width);
|
||||
return Bry_.Add(Int_.To_bry(width), Xomw_lnki_wkr.Bry__px);
|
||||
}
|
||||
|
||||
// public Xomw_param_map parseParamString(byte[] src) {
|
||||
// int len = src.length;
|
||||
// // XO.MW.REGEX: if (preg_match('/^(\d+)px/', str, m)) {
|
||||
// if ( len > 0 // at least one char
|
||||
// && Byte_ascii.Is_num(src[0])) // 1st char is numeric
|
||||
// {
|
||||
// pos = Bry_find_.Find_fwd_while_num(src, 1, len); // skip numeric
|
||||
// if (Bry_.Match(src, pos, len, Xomw_lnki_wkr.Bry__px)) { // matches "px"
|
||||
// Xomw_params_handler rv = new Xomw_params_handler();
|
||||
// rv.width = Bry_.To_int_or(src, 0, pos, Php_utl_.Null_int);
|
||||
// return rv;
|
||||
// }
|
||||
// }
|
||||
// return null;
|
||||
// }
|
||||
|
||||
// function getScriptParams(paramsVar) {
|
||||
// return [ 'width' => paramsVar['width'] ];
|
||||
// }
|
||||
|
||||
/**
|
||||
* @param File image
|
||||
* @param array paramsVar
|
||||
* @return boolean
|
||||
*/
|
||||
@Override public boolean normaliseParams(Xomw_File image, Xomw_params_handler handlerParams) {
|
||||
byte[] mimeType = image.getMimeType();
|
||||
|
||||
if (!Php_utl_.isset(handlerParams.width)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!Php_utl_.isset(handlerParams.page)) {
|
||||
handlerParams.page = 1;
|
||||
}
|
||||
else {
|
||||
// handlerParams.page = intval(handlerParams.page);
|
||||
// if (handlerParams.page > image.pageCount()) {
|
||||
// handlerParams.page = image.pageCount();
|
||||
// }
|
||||
//
|
||||
// if (handlerParams.page < 1) {
|
||||
// handlerParams.page = 1;
|
||||
// }
|
||||
}
|
||||
|
||||
int srcWidth = image.getWidth(handlerParams.page);
|
||||
int srcHeight = image.getHeight(handlerParams.page);
|
||||
|
||||
if (Php_utl_.isset(handlerParams.height) && handlerParams.height != -1) {
|
||||
// Height & width were both set
|
||||
if (handlerParams.width * srcHeight > handlerParams.height * srcWidth) {
|
||||
// Height is the relative smaller dimension, so scale width accordingly
|
||||
handlerParams.width = fitBoxWidth(srcWidth, srcHeight, handlerParams.height);
|
||||
|
||||
if (handlerParams.width == 0) {
|
||||
// Very small image, so we need to rely on client side scaling :(
|
||||
handlerParams.width = 1;
|
||||
}
|
||||
|
||||
handlerParams.physicalWidth = handlerParams.width;
|
||||
} else {
|
||||
// Height was crap, unset it so that it will be calculated later
|
||||
handlerParams.height = Php_utl_.Null_int;
|
||||
}
|
||||
}
|
||||
|
||||
if (!Php_utl_.isset(handlerParams.physicalWidth)) {
|
||||
// Passed all validations, so set the physicalWidth
|
||||
handlerParams.physicalWidth = handlerParams.width;
|
||||
}
|
||||
|
||||
// Because thumbs are only referred to by width, the height always needs
|
||||
// to be scaled by the width to keep the thumbnail sizes consistent,
|
||||
// even if it was set inside the if block above
|
||||
handlerParams.physicalHeight = Xomw_File.scaleHeight(srcWidth, srcHeight,
|
||||
handlerParams.physicalWidth);
|
||||
|
||||
// Set the height if it was not validated in the if block higher up
|
||||
if (!Php_utl_.isset(handlerParams.height) || handlerParams.height == -1) {
|
||||
handlerParams.height = handlerParams.physicalHeight;
|
||||
}
|
||||
|
||||
if (!this.validateThumbParams(handlerParams, srcWidth, srcHeight, mimeType)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate thumbnail parameters and fill in the correct height
|
||||
*
|
||||
* @param int width Specified width (input/output)
|
||||
* @param int height Height (output only)
|
||||
* @param int srcWidth Width of the source image
|
||||
* @param int srcHeight Height of the source image
|
||||
* @param String mimeType Unused
|
||||
* @return boolean False to indicate that an error should be returned to the user.
|
||||
*/
|
||||
// XO.MW.NOTE: MW passes w and h by ref, but only changes h; XO will pass handlerParams directly
|
||||
private boolean validateThumbParams(Xomw_params_handler handlerParams, int srcWidth, int srcHeight, byte[] mimeType) {
|
||||
int width = handlerParams.physicalWidth;
|
||||
int height = handlerParams.physicalHeight;
|
||||
// width = intval(width);
|
||||
|
||||
// Sanity check width
|
||||
if (width <= 0) {
|
||||
Gfo_usr_dlg_.Instance.Warn_many("", "", "validateThumbParams: Invalid destination width: width");
|
||||
|
||||
return false;
|
||||
}
|
||||
if (srcWidth <= 0) {
|
||||
Gfo_usr_dlg_.Instance.Warn_many("", "", "validateThumbParams: Invalid source width: srcWidth");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
height = Xomw_File.scaleHeight(srcWidth, srcHeight, width);
|
||||
if (height == 0) {
|
||||
// Force height to be at least 1 pixel
|
||||
height = 1;
|
||||
}
|
||||
handlerParams.height = height;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// /**
|
||||
// * @param File image
|
||||
// * @param String script
|
||||
// * @param array paramsVar
|
||||
// * @return boolean|MediaTransformOutput
|
||||
// */
|
||||
// function getScriptedTransform(image, script, paramsVar) {
|
||||
// if (!this.normaliseParams(image, paramsVar)) {
|
||||
// return false;
|
||||
// }
|
||||
// url = wfAppendQuery(script, this.getScriptParams(paramsVar));
|
||||
//
|
||||
// if (image.mustRender() || paramsVar['width'] < image.getWidth()) {
|
||||
// return new ThumbnailImage(image, url, false, paramsVar);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// function getImageSize(image, path) {
|
||||
// MediaWiki\suppressWarnings();
|
||||
// gis = getimagesize(path);
|
||||
// MediaWiki\restoreWarnings();
|
||||
//
|
||||
// return gis;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Function that returns the number of pixels to be thumbnailed.
|
||||
// * Intended for animated GIFs to multiply by the number of frames.
|
||||
// *
|
||||
// * If the file doesn't support a notion of "area" return 0.
|
||||
// *
|
||||
// * @param File image
|
||||
// * @return int
|
||||
// */
|
||||
// function getImageArea(image) {
|
||||
// return image.getWidth() * image.getHeight();
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * @param File file
|
||||
// * @return String
|
||||
// */
|
||||
// function getShortDesc(file) {
|
||||
// global wgLang;
|
||||
// nbytes = htmlspecialchars(wgLang.formatSize(file.getSize()));
|
||||
// widthheight = wfMessage('widthheight')
|
||||
// .numParams(file.getWidth(), file.getHeight()).escaped();
|
||||
//
|
||||
// return "widthheight (nbytes)";
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * @param File file
|
||||
// * @return String
|
||||
// */
|
||||
// function getLongDesc(file) {
|
||||
// global wgLang;
|
||||
// pages = file.pageCount();
|
||||
// size = htmlspecialchars(wgLang.formatSize(file.getSize()));
|
||||
// if (pages === false || pages <= 1) {
|
||||
// msg = wfMessage('file-info-size').numParams(file.getWidth(),
|
||||
// file.getHeight()).paramsVar(size,
|
||||
// '<span class="mime-type">' . file.getMimeType() . '</span>').parse();
|
||||
// } else {
|
||||
// msg = wfMessage('file-info-size-pages').numParams(file.getWidth(),
|
||||
// file.getHeight()).paramsVar(size,
|
||||
// '<span class="mime-type">' . file.getMimeType() . '</span>').numParams(pages).parse();
|
||||
// }
|
||||
//
|
||||
// return msg;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * @param File file
|
||||
// * @return String
|
||||
// */
|
||||
// function getDimensionsString(file) {
|
||||
// pages = file.pageCount();
|
||||
// if (pages > 1) {
|
||||
// return wfMessage('widthheightpage')
|
||||
// .numParams(file.getWidth(), file.getHeight(), pages).text();
|
||||
// } else {
|
||||
// return wfMessage('widthheight')
|
||||
// .numParams(file.getWidth(), file.getHeight()).text();
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// public function sanitizeParamsForBucketing(paramsVar) {
|
||||
// paramsVar = parent::sanitizeParamsForBucketing(paramsVar);
|
||||
//
|
||||
// // We unset the height parameters in order to let normaliseParams recalculate them
|
||||
// // Otherwise there might be a height discrepancy
|
||||
// if (isset(paramsVar['height'])) {
|
||||
// unset(paramsVar['height']);
|
||||
// }
|
||||
//
|
||||
// if (isset(paramsVar['physicalHeight'])) {
|
||||
// unset(paramsVar['physicalHeight']);
|
||||
// }
|
||||
//
|
||||
// return paramsVar;
|
||||
// }
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.xowa.mediawiki.includes.media; import gplx.*; import gplx.xowa.*; import gplx.xowa.mediawiki.*; import gplx.xowa.mediawiki.includes.*;
|
||||
import org.junit.*; import gplx.core.tests.*;
|
||||
import gplx.xowa.mediawiki.includes.utls.*;
|
||||
import gplx.xowa.mediawiki.includes.parsers.*; import gplx.xowa.mediawiki.includes.parsers.lnkis.*;
|
||||
import gplx.xowa.mediawiki.includes.filerepo.*; import gplx.xowa.mediawiki.includes.filerepo.file.*;
|
||||
public class Xomw_ImageHandler__tst {
|
||||
private final Xomw_ImageHandler__fxt fxt = new Xomw_ImageHandler__fxt();
|
||||
@Before public void init() {
|
||||
fxt.Init__file("A.png", 400, 200);
|
||||
}
|
||||
@Test public void normaliseParams() {
|
||||
// widthOnly; "Because thumbs are only referred to by width, the height always needs"
|
||||
fxt.Test__normaliseParams(fxt.Make__handlerParams(200), fxt.Make__handlerParams(200, 100, 200, 100));
|
||||
}
|
||||
}
|
||||
class Xomw_ImageHandler__fxt {
|
||||
private final Xomw_ImageHandler handler;
|
||||
private final Xomw_FileRepo repo = new Xomw_FileRepo(Bry_.new_a7("/orig"), Bry_.new_a7("/thumb"));
|
||||
private final Xomw_parser_env env = new Xomw_parser_env();
|
||||
private Xomw_File file;
|
||||
public Xomw_ImageHandler__fxt() {
|
||||
handler = new Xomw_TransformationalImageHandler(Bry_.new_a7("test_handler"));
|
||||
}
|
||||
public Xomw_params_handler Make__handlerParams(int w) {return Make__handlerParams(w, Php_utl_.Null_int, Php_utl_.Null_int, Php_utl_.Null_int);}
|
||||
public Xomw_params_handler Make__handlerParams(int w, int h, int phys_w, int phys_h) {
|
||||
Xomw_params_handler rv = new Xomw_params_handler();
|
||||
rv.width = w;
|
||||
rv.height = h;
|
||||
rv.physicalWidth = phys_w;
|
||||
rv.physicalHeight = phys_h;
|
||||
return rv;
|
||||
}
|
||||
public void Init__file(String title, int w, int h) {
|
||||
this.file = new Xomw_LocalFile(env, Bry_.new_u8(title), repo, w, h, Xomw_MediaHandlerFactory.Mime__image__png);
|
||||
}
|
||||
public void Test__normaliseParams(Xomw_params_handler prms, Xomw_params_handler expd) {
|
||||
// exec
|
||||
handler.normaliseParams(file, prms);
|
||||
|
||||
// test
|
||||
Gftest.Eq__int(expd.width, prms.width);
|
||||
Gftest.Eq__int(expd.height, prms.height);
|
||||
Gftest.Eq__int(expd.physicalWidth, prms.physicalWidth);
|
||||
Gftest.Eq__int(expd.physicalHeight, prms.physicalHeight);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,868 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.xowa.mediawiki.includes.media; import gplx.*; import gplx.xowa.*; import gplx.xowa.mediawiki.*; import gplx.xowa.mediawiki.includes.*;
|
||||
import gplx.xowa.mediawiki.includes.filerepo.file.*;
|
||||
import gplx.xowa.mediawiki.includes.parsers.lnkis.*;
|
||||
public abstract class Xomw_MediaHandler {
|
||||
public byte[] Key() {return key;} private byte[] key;
|
||||
public Xomw_MediaHandler(byte[] key) {
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
private static final int TRANSFORM_LATER = 1;
|
||||
// static final METADATA_GOOD = true;
|
||||
// static final METADATA_BAD = false;
|
||||
// static final METADATA_COMPATIBLE = 2; // for old but backwards compatible.
|
||||
// /**
|
||||
// * Max length of error logged by logErrorForExternalProcess()
|
||||
// */
|
||||
// static final MAX_ERR_LOG_SIZE = 65535;
|
||||
//
|
||||
// /**
|
||||
// * Get a MediaHandler for a given MIME type from the instance cache
|
||||
// *
|
||||
// * @param String $type
|
||||
// * @return MediaHandler|boolean
|
||||
// */
|
||||
// static function getHandler($type) {
|
||||
// return MediaWikiServices::getInstance()
|
||||
// ->getMediaHandlerFactory()->getHandler($type);
|
||||
// }
|
||||
|
||||
/**
|
||||
* Get an associative array mapping magic word IDs to parameter names.
|
||||
* Will be used by the parser to identify parameters.
|
||||
*/
|
||||
public abstract Xomw_param_map getParamMap();
|
||||
|
||||
/**
|
||||
* Validate a thumbnail parameter at parse time.
|
||||
* Return true to accept the parameter, and false to reject it.
|
||||
* If you return false, the parser will do something quiet and forgiving.
|
||||
*
|
||||
* @param String $name
|
||||
* @param mixed $value
|
||||
*/
|
||||
public abstract boolean validateParam(int name_uid, byte[] val_bry, int val_int);
|
||||
|
||||
/**
|
||||
* Merge a parameter array into a String appropriate for inclusion in filenames
|
||||
*
|
||||
* @param array paramsVar Array of parameters that have been through normaliseParams.
|
||||
* @return String
|
||||
*/
|
||||
public abstract byte[] makeParamString(Xomw_params_handler handlerParams);
|
||||
|
||||
// /**
|
||||
// * Parse a param String made with makeParamString back into an array
|
||||
// *
|
||||
// * @param String $str The parameter String without file name (e.g. 122px)
|
||||
// * @return array|boolean Array of parameters or false on failure.
|
||||
// */
|
||||
// abstract public function parseParamString($str);
|
||||
|
||||
/**
|
||||
* Changes the parameter array as necessary, ready for transformation.
|
||||
* Should be idempotent.
|
||||
* Returns false if the parameters are unacceptable and the transform should fail
|
||||
* @param File $image
|
||||
* @param array $paramsVar
|
||||
*/
|
||||
public abstract boolean normaliseParams(Xomw_File image, Xomw_params_handler handlerParams);
|
||||
|
||||
// /**
|
||||
// * Get an image size array like that returned by getimagesize(), or false if it
|
||||
// * can't be determined.
|
||||
// *
|
||||
// * This function is used for determining the width, height and bitdepth directly
|
||||
// * from an image. The results are stored in the database in the img_width,
|
||||
// * img_height, img_bits fields.
|
||||
// *
|
||||
// * @note If this is a multipage file, return the width and height of the
|
||||
// * first page.
|
||||
// *
|
||||
// * @param File|FSFile $image The image Object, or false if there isn't one.
|
||||
// * Warning, FSFile::getPropsFromPath might pass an FSFile instead of File (!)
|
||||
// * @param String $path The filename
|
||||
// * @return array|boolean Follow the format of PHP getimagesize() @gplx.Internal protected function.
|
||||
// * See https://secure.php.net/getimagesize. MediaWiki will only ever use the
|
||||
// * first two array keys (the width and height), and the 'bits' associative
|
||||
// * key. All other array keys are ignored. Returning a 'bits' key is optional
|
||||
// * as not all formats have a notion of "bitdepth". Returns false on failure.
|
||||
// */
|
||||
// abstract function getImageSize($image, $path);
|
||||
//
|
||||
// /**
|
||||
// * Get handler-specific metadata which will be saved in the img_metadata field.
|
||||
// *
|
||||
// * @param File|FSFile $image The image Object, or false if there isn't one.
|
||||
// * Warning, FSFile::getPropsFromPath might pass an FSFile instead of File (!)
|
||||
// * @param String $path The filename
|
||||
// * @return String A String of metadata in php serialized form (Run through serialize())
|
||||
// */
|
||||
// function getMetadata($image, $path) {
|
||||
// return '';
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Get metadata version.
|
||||
// *
|
||||
// * This is not used for validating metadata, this is used for the api when returning
|
||||
// * metadata, since api content formats should stay the same over time, and so things
|
||||
// * using ForeignApiRepo can keep backwards compatibility
|
||||
// *
|
||||
// * All core media handlers share a common version number, and extensions can
|
||||
// * use the GetMetadataVersion hook to append to the array (they should append a unique
|
||||
// * String so not to get confusing). If there was a media handler named 'foo' with metadata
|
||||
// * version 3 it might add to the end of the array the element 'foo=3'. if the core metadata
|
||||
// * version is 2, the end version String would look like '2;foo=3'.
|
||||
// *
|
||||
// * @return String Version String
|
||||
// */
|
||||
// static function getMetadataVersion() {
|
||||
// $version = [ '2' ]; // core metadata version
|
||||
// Hooks::run('GetMetadataVersion', [ &$version ]);
|
||||
//
|
||||
// return implode(';', $version);
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Convert metadata version.
|
||||
// *
|
||||
// * By default just returns $metadata, but can be used to allow
|
||||
// * media handlers to convert between metadata versions.
|
||||
// *
|
||||
// * @param String|array $metadata Metadata array (serialized if String)
|
||||
// * @param int $version Target version
|
||||
// * @return array Serialized metadata in specified version, or $metadata on fail.
|
||||
// */
|
||||
// function convertMetadataVersion($metadata, $version = 1) {
|
||||
// if (!is_array($metadata)) {
|
||||
//
|
||||
// // unserialize to keep return parameter consistent.
|
||||
// MediaWiki\suppressWarnings();
|
||||
// $ret = unserialize($metadata);
|
||||
// MediaWiki\restoreWarnings();
|
||||
//
|
||||
// return $ret;
|
||||
// }
|
||||
//
|
||||
// return $metadata;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Get a String describing the type of metadata, for display purposes.
|
||||
// *
|
||||
// * @note This method is currently unused.
|
||||
// * @param File $image
|
||||
// * @return String
|
||||
// */
|
||||
// function getMetadataType($image) {
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Check if the metadata String is valid for this handler.
|
||||
// * If it returns MediaHandler::METADATA_BAD (or false), Image
|
||||
// * will reload the metadata from the file and update the database.
|
||||
// * MediaHandler::METADATA_GOOD for if the metadata is a-ok,
|
||||
// * MediaHandler::METADATA_COMPATIBLE if metadata is old but backwards
|
||||
// * compatible (which may or may not trigger a metadata reload).
|
||||
// *
|
||||
// * @note Returning self::METADATA_BAD will trigger a metadata reload from
|
||||
// * file on page view. Always returning this from a broken file, or suddenly
|
||||
// * triggering as bad metadata for a large number of files can cause
|
||||
// * performance problems.
|
||||
// * @param File $image
|
||||
// * @param String $metadata The metadata in serialized form
|
||||
// * @return boolean
|
||||
// */
|
||||
// function isMetadataValid($image, $metadata) {
|
||||
// return self::METADATA_GOOD;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Get an array of standard (FormatMetadata type) metadata values.
|
||||
// *
|
||||
// * The returned data is largely the same as that from getMetadata(),
|
||||
// * but formatted in a standard, stable, handler-independent way.
|
||||
// * The idea being that some values like ImageDescription or Artist
|
||||
// * are universal and should be retrievable in a handler generic way.
|
||||
// *
|
||||
// * The specific properties are the type of properties that can be
|
||||
// * handled by the FormatMetadata class. These values are exposed to the
|
||||
// * user via the filemetadata parser function.
|
||||
// *
|
||||
// * Details of the response format of this function can be found at
|
||||
// * https://www.mediawiki.org/wiki/Manual:File_metadata_handling
|
||||
// * tl/dr: the response is an associative array of
|
||||
// * properties keyed by name, but the value can be complex. You probably
|
||||
// * want to call one of the FormatMetadata::flatten* functions on the
|
||||
// * property values before using them, or call
|
||||
// * FormatMetadata::getFormattedData() on the full response array, which
|
||||
// * transforms all values into prettified, human-readable text.
|
||||
// *
|
||||
// * Subclasses overriding this function must return a value which is a
|
||||
// * valid API response fragment (all associative array keys are valid
|
||||
// * XML tagnames).
|
||||
// *
|
||||
// * Note, if the file simply has no metadata, but the handler supports
|
||||
// * this interface, it should return an empty array, not false.
|
||||
// *
|
||||
// * @param File $file
|
||||
// * @return array|boolean False if interface not supported
|
||||
// * @since 1.23
|
||||
// */
|
||||
// public function getCommonMetaArray(File $file) {
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Get a MediaTransformOutput Object representing an alternate of the transformed
|
||||
// * output which will call an intermediary thumbnail assist script.
|
||||
// *
|
||||
// * Used when the repository has a thumbnailScriptUrl option configured.
|
||||
// *
|
||||
// * Return false to fall back to the regular getTransform().
|
||||
// * @param File $image
|
||||
// * @param String $script
|
||||
// * @param array $paramsVar
|
||||
// * @return boolean|ThumbnailImage
|
||||
// */
|
||||
// function getScriptedTransform($image, $script, $paramsVar) {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
/**
|
||||
* Get a MediaTransformOutput Object representing the transformed output. Does not
|
||||
* actually do the transform.
|
||||
*
|
||||
* @param File $image The image Object
|
||||
* @param String $dstPath Filesystem destination path
|
||||
* @param String $dstUrl Destination URL to use in output HTML
|
||||
* @param array $paramsVar Arbitrary set of parameters validated by $this->validateParam()
|
||||
* @return MediaTransformOutput
|
||||
*/
|
||||
public Xomw_MediaTransformOutput getTransform(Xomw_File image, byte[] dstPath, byte[] dstUrl, Xomw_params_handler handlerParams) {
|
||||
return this.doTransform(image, dstPath, dstUrl, handlerParams, TRANSFORM_LATER);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a MediaTransformOutput Object representing the transformed output. Does the
|
||||
* transform unless $flags contains self::TRANSFORM_LATER.
|
||||
*
|
||||
* @param File $image The image Object
|
||||
* @param String $dstPath Filesystem destination path
|
||||
* @param String $dstUrl Destination URL to use in output HTML
|
||||
* @param array $paramsVar Arbitrary set of parameters validated by $this->validateParam()
|
||||
* Note: These parameters have *not* gone through $this->normaliseParams()
|
||||
* @param int $flags A bitfield, may contain self::TRANSFORM_LATER
|
||||
* @return MediaTransformOutput
|
||||
*/
|
||||
public Xomw_MediaTransformOutput doTransform(Xomw_File image, byte[] dstPath, byte[] dstUrl, Xomw_params_handler handlerParams) {return doTransform(image, dstPath, dstUrl, handlerParams, 0);}
|
||||
public abstract Xomw_MediaTransformOutput doTransform(Xomw_File image, byte[] dstPath, byte[] dstUrl, Xomw_params_handler handlerParams, int flags);
|
||||
|
||||
// /**
|
||||
// * Get the thumbnail extension and MIME type for a given source MIME type
|
||||
// *
|
||||
// * @param String $ext Extension of original file
|
||||
// * @param String $mime MIME type of original file
|
||||
// * @param array $paramsVar Handler specific rendering parameters
|
||||
// * @return array Thumbnail extension and MIME type
|
||||
// */
|
||||
// function getThumbType($ext, $mime, $paramsVar = null) {
|
||||
// $magic = MimeMagic::singleton();
|
||||
// if (!$ext || $magic->isMatchingExtension($ext, $mime) === false) {
|
||||
// // The extension is not valid for this MIME type and we do
|
||||
// // recognize the MIME type
|
||||
// $extensions = $magic->getExtensionsForType($mime);
|
||||
// if ($extensions) {
|
||||
// return [ strtok($extensions, ' '), $mime ];
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// // The extension is correct (true) or the MIME type is unknown to
|
||||
// // MediaWiki (null)
|
||||
// return [ $ext, $mime ];
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Get useful response headers for GET/HEAD requests for a file with the given metadata
|
||||
// *
|
||||
// * @param mixed $metadata Result of the getMetadata() function of this handler for a file
|
||||
// * @return array
|
||||
// */
|
||||
// public function getStreamHeaders($metadata) {
|
||||
// return [];
|
||||
// }
|
||||
|
||||
/**
|
||||
* True if the handled types can be transformed
|
||||
*
|
||||
* @param File $file
|
||||
* @return boolean
|
||||
*/
|
||||
@gplx.Virtual public boolean canRender(Xomw_File file) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* True if handled types cannot be displayed directly in a browser
|
||||
* but can be rendered
|
||||
*
|
||||
* @param File $file
|
||||
* @return boolean
|
||||
*/
|
||||
public boolean mustRender(Xomw_File file) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// /**
|
||||
// * True if the type has multi-page capabilities
|
||||
// *
|
||||
// * @param File $file
|
||||
// * @return boolean
|
||||
// */
|
||||
// public function isMultiPage($file) {
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Page count for a multi-page document, false if unsupported or unknown
|
||||
// *
|
||||
// * @param File $file
|
||||
// * @return boolean
|
||||
// */
|
||||
// function pageCount(File $file) {
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * The material is vectorized and thus scaling is lossless
|
||||
// *
|
||||
// * @param File $file
|
||||
// * @return boolean
|
||||
// */
|
||||
// function isVectorized($file) {
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * The material is an image, and is animated.
|
||||
// * In particular, video material need not return true.
|
||||
// * @note Before 1.20, this was a method of ImageHandler only
|
||||
// *
|
||||
// * @param File $file
|
||||
// * @return boolean
|
||||
// */
|
||||
// function isAnimatedImage($file) {
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * If the material is animated, we can animate the thumbnail
|
||||
// * @since 1.20
|
||||
// *
|
||||
// * @param File $file
|
||||
// * @return boolean If material is not animated, handler may return any value.
|
||||
// */
|
||||
// function canAnimateThumbnail($file) {
|
||||
// return true;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * False if the handler is disabled for all files
|
||||
// * @return boolean
|
||||
// */
|
||||
// function isEnabled() {
|
||||
// return true;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Get an associative array of page dimensions
|
||||
// * Currently "width" and "height" are understood, but this might be
|
||||
// * expanded in the future.
|
||||
// * Returns false if unknown.
|
||||
// *
|
||||
// * It is expected that handlers for paged media (e.g. DjVuHandler)
|
||||
// * will override this method so that it gives the correct results
|
||||
// * for each specific page of the file, using the $page argument.
|
||||
// *
|
||||
// * @note For non-paged media, use getImageSize.
|
||||
// *
|
||||
// * @param File $image
|
||||
// * @param int $page What page to get dimensions of
|
||||
// * @return array|boolean
|
||||
// */
|
||||
// function getPageDimensions(File $image, $page) {
|
||||
// $gis = $this->getImageSize($image, $image->getLocalRefPath());
|
||||
// if ($gis) {
|
||||
// return [
|
||||
// 'width' => $gis[0],
|
||||
// 'height' => $gis[1]
|
||||
// ];
|
||||
// } else {
|
||||
// return false;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Generic getter for text layer.
|
||||
// * Currently overloaded by PDF and DjVu handlers
|
||||
// * @param File $image
|
||||
// * @param int $page Page number to get information for
|
||||
// * @return boolean|String Page text or false when no text found or if
|
||||
// * unsupported.
|
||||
// */
|
||||
// function getPageText(File $image, $page) {
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Get the text of the entire document.
|
||||
// * @param File $file
|
||||
// * @return boolean|String The text of the document or false if unsupported.
|
||||
// */
|
||||
// public function getEntireText(File $file) {
|
||||
// $numPages = $file->pageCount();
|
||||
// if (!$numPages) {
|
||||
// // Not a multipage document
|
||||
// return $this->getPageText($file, 1);
|
||||
// }
|
||||
// $document = '';
|
||||
// for ($i = 1; $i <= $numPages; $i++) {
|
||||
// $curPage = $this->getPageText($file, $i);
|
||||
// if (is_string($curPage)) {
|
||||
// $document .= $curPage . "\n";
|
||||
// }
|
||||
// }
|
||||
// if ($document !== '') {
|
||||
// return $document;
|
||||
// }
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Get an array structure that looks like this:
|
||||
// *
|
||||
// * [
|
||||
// * 'visible' => [
|
||||
// * 'Human-readable name' => 'Human readable value',
|
||||
// * ...
|
||||
// * ],
|
||||
// * 'collapsed' => [
|
||||
// * '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.
|
||||
// */
|
||||
//
|
||||
// /**
|
||||
// * @todo FIXME: This interface is not very flexible. 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.
|
||||
// * @param File $image
|
||||
// * @param boolean|IContextSource $context Context to use (optional)
|
||||
// * @return array|boolean
|
||||
// */
|
||||
// function formatMetadata($image, $context = false) {
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// /** sorts the visible/invisible field.
|
||||
// * Split off from ImageHandler::formatMetadata, as used by more than
|
||||
// * one type of handler.
|
||||
// *
|
||||
// * This is used by the media handlers that use the FormatMetadata class
|
||||
// *
|
||||
// * @param array $metadataArray Metadata array
|
||||
// * @param boolean|IContextSource $context Context to use (optional)
|
||||
// * @return array Array for use displaying metadata.
|
||||
// */
|
||||
// function formatMetadataHelper($metadataArray, $context = false) {
|
||||
// $result = [
|
||||
// 'visible' => [],
|
||||
// 'collapsed' => []
|
||||
// ];
|
||||
//
|
||||
// $formatted = FormatMetadata::getFormattedData($metadataArray, $context);
|
||||
// // 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;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Get a list of metadata items which should be displayed when
|
||||
// * the metadata table is collapsed.
|
||||
// *
|
||||
// * @return array Array of strings
|
||||
// */
|
||||
// protected function visibleMetadataFields() {
|
||||
// return FormatMetadata::getVisibleFields();
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * This is used to generate an array element for each metadata value
|
||||
// * That array is then used to generate the table of metadata values
|
||||
// * on the image page
|
||||
// *
|
||||
// * @param array &$array An array containing elements for each type of visibility
|
||||
// * and each of those elements being an array of metadata items. This function adds
|
||||
// * a value to that array.
|
||||
// * @param String $visibility ('visible' or 'collapsed') if this value is hidden
|
||||
// * by default.
|
||||
// * @param String $type Type of metadata tag (currently always 'exif')
|
||||
// * @param String $id The name of the metadata tag (like 'artist' for example).
|
||||
// * its name in the table displayed is the message "$type-$id" (Ex exif-artist).
|
||||
// * @param String $value Thingy goes into a wikitext table; it used to be escaped but
|
||||
// * that was incompatible with previous practise 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.
|
||||
// * @param boolean|String $param Value to pass to the message for the name of the field
|
||||
// * as $1. Currently this parameter doesn't seem to ever be used.
|
||||
// *
|
||||
// * Note, everything here is passed through the parser later on (!)
|
||||
// */
|
||||
// protected static function addMeta(&$array, $visibility, $type, $id, $value, $param = false) {
|
||||
// $msg = wfMessage("$type-$id", $param);
|
||||
// if ($msg->exists()) {
|
||||
// $name = $msg->text();
|
||||
// } else {
|
||||
// // This is for future compatibility when using instant commons.
|
||||
// // So as to not display as ugly a name if a new metadata
|
||||
// // property is defined that we don't know about
|
||||
// // (not a major issue since such a property would be collapsed
|
||||
// // by default).
|
||||
// wfDebug(__METHOD__ . ' Unknown metadata name: ' . $id . "\n");
|
||||
// $name = wfEscapeWikiText($id);
|
||||
// }
|
||||
// $array[$visibility][] = [
|
||||
// 'id' => "$type-$id",
|
||||
// 'name' => $name,
|
||||
// 'value' => $value
|
||||
// ];
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Short description. Shown on Special:Search results.
|
||||
// *
|
||||
// * @param File $file
|
||||
// * @return String
|
||||
// */
|
||||
// function getShortDesc($file) {
|
||||
// return self::getGeneralShortDesc($file);
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Long description. Shown under image on image description page surounded by ().
|
||||
// *
|
||||
// * @param File $file
|
||||
// * @return String
|
||||
// */
|
||||
// function getLongDesc($file) {
|
||||
// return self::getGeneralLongDesc($file);
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Used instead of getShortDesc if there is no handler registered for file.
|
||||
// *
|
||||
// * @param File $file
|
||||
// * @return String
|
||||
// */
|
||||
// static function getGeneralShortDesc($file) {
|
||||
// global $wgLang;
|
||||
//
|
||||
// return htmlspecialchars($wgLang->formatSize($file->getSize()));
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Used instead of getLongDesc if there is no handler registered for file.
|
||||
// *
|
||||
// * @param File $file
|
||||
// * @return String
|
||||
// */
|
||||
// static function getGeneralLongDesc($file) {
|
||||
// return wfMessage('file-info')->sizeParams($file->getSize())
|
||||
// ->paramsVar('<span class="mime-type">' . $file->getMimeType() . '</span>')->parse();
|
||||
// }
|
||||
|
||||
/**
|
||||
* Calculate the largest thumbnail width for a given original file size
|
||||
* such that the thumbnail's height is at most $maxHeight.
|
||||
* @param int $boxWidth Width of the thumbnail box.
|
||||
* @param int $boxHeight Height of the thumbnail box.
|
||||
* @param int $maxHeight Maximum height expected for the thumbnail.
|
||||
* @return int
|
||||
*/
|
||||
public static int fitBoxWidth(int boxWidth, int boxHeight, int maxHeight) {
|
||||
double idealWidth = boxWidth * maxHeight / boxHeight;
|
||||
int roundedUp = Math_.Ceil_as_int(idealWidth);
|
||||
if (Math_.Round(roundedUp * boxHeight / boxWidth, 0) > maxHeight) {
|
||||
return Math_.Floor_as_int(idealWidth);
|
||||
} else {
|
||||
return roundedUp;
|
||||
}
|
||||
}
|
||||
|
||||
// /**
|
||||
// * Shown in file history box on image description page.
|
||||
// *
|
||||
// * @param File $file
|
||||
// * @return String Dimensions
|
||||
// */
|
||||
// function getDimensionsString($file) {
|
||||
// return '';
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Modify the parser Object post-transform.
|
||||
// *
|
||||
// * This is often used to do $parser->addOutputHook(),
|
||||
// * in order to add some javascript to render a viewer.
|
||||
// * See TimedMediaHandler or OggHandler for an example.
|
||||
// *
|
||||
// * @param Parser $parser
|
||||
// * @param File $file
|
||||
// */
|
||||
// function parserTransformHook($parser, $file) {
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * File validation hook called on upload.
|
||||
// *
|
||||
// * If the file at the given local path is not valid, or its MIME type does not
|
||||
// * match the handler class, a Status Object should be returned containing
|
||||
// * relevant errors.
|
||||
// *
|
||||
// * @param String $fileName The local path to the file.
|
||||
// * @return Status
|
||||
// */
|
||||
// function verifyUpload($fileName) {
|
||||
// return Status::newGood();
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Check for zero-sized thumbnails. These can be generated when
|
||||
// * no disk space is available or some other error occurs
|
||||
// *
|
||||
// * @param String $dstPath The location of the suspect file
|
||||
// * @param int $retval Return value of some shell process, file will be deleted if this is non-zero
|
||||
// * @return boolean True if removed, false otherwise
|
||||
// */
|
||||
// function removeBadFile($dstPath, $retval = 0) {
|
||||
// if (file_exists($dstPath)) {
|
||||
// $thumbstat = stat($dstPath);
|
||||
// if ($thumbstat['size'] == 0 || $retval != 0) {
|
||||
// $result = unlink($dstPath);
|
||||
//
|
||||
// if ($result) {
|
||||
// wfDebugLog('thumbnail',
|
||||
// sprintf('Removing bad %d-byte thumbnail "%s". unlink() succeeded',
|
||||
// $thumbstat['size'], $dstPath));
|
||||
// } else {
|
||||
// wfDebugLog('thumbnail',
|
||||
// sprintf('Removing bad %d-byte thumbnail "%s". unlink() failed',
|
||||
// $thumbstat['size'], $dstPath));
|
||||
// }
|
||||
//
|
||||
// return true;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Remove files from the purge list.
|
||||
// *
|
||||
// * This is used by some video handlers to prevent ?action=purge
|
||||
// * from removing a transcoded video, which is expensive to
|
||||
// * regenerate.
|
||||
// *
|
||||
// * @see LocalFile::purgeThumbnails
|
||||
// *
|
||||
// * @param array $files
|
||||
// * @param array $options Purge options. Currently will always be
|
||||
// * an array with a single key 'forThumbRefresh' set to true.
|
||||
// */
|
||||
// public function filterThumbnailPurgeList(&$files, $options) {
|
||||
// // Do nothing
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * True if the handler can rotate the media
|
||||
// * @since 1.24 non-static. From 1.21-1.23 was static
|
||||
// * @return boolean
|
||||
// */
|
||||
// public function canRotate() {
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * On supporting image formats, try to read out the low-level orientation
|
||||
// * of the file and return the angle that the file needs to be rotated to
|
||||
// * be viewed.
|
||||
// *
|
||||
// * This information is only useful when manipulating the original file;
|
||||
// * the width and height we normally work with is logical, and will match
|
||||
// * any produced output views.
|
||||
// *
|
||||
// * For files we don't know, we return 0.
|
||||
// *
|
||||
// * @param File $file
|
||||
// * @return int 0, 90, 180 or 270
|
||||
// */
|
||||
// public function getRotation($file) {
|
||||
// return 0;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Log an error that occurred in an external process
|
||||
// *
|
||||
// * Moved from BitmapHandler to MediaHandler with MediaWiki 1.23
|
||||
// *
|
||||
// * @since 1.23
|
||||
// * @param int $retval
|
||||
// * @param String $err Error reported by command. Anything longer than
|
||||
// * MediaHandler::MAX_ERR_LOG_SIZE is stripped off.
|
||||
// * @param String $cmd
|
||||
// */
|
||||
// protected function logErrorForExternalProcess($retval, $err, $cmd) {
|
||||
// # Keep error output limited (bug 57985)
|
||||
// $errMessage = trim(substr($err, 0, self::MAX_ERR_LOG_SIZE));
|
||||
//
|
||||
// wfDebugLog('thumbnail',
|
||||
// sprintf('thumbnail failed on %s: error %d "%s" from "%s"',
|
||||
// wfHostname(), $retval, $errMessage, $cmd));
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Get list of languages file can be viewed in.
|
||||
// *
|
||||
// * @param File $file
|
||||
// * @return String[] Array of language codes, or empty array if unsupported.
|
||||
// * @since 1.23
|
||||
// */
|
||||
// public function getAvailableLanguages(File $file) {
|
||||
// return [];
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * On file types that support renderings in multiple languages,
|
||||
// * which language is used by default if unspecified.
|
||||
// *
|
||||
// * If getAvailableLanguages returns a non-empty array, this must return
|
||||
// * a valid language code. Otherwise can return null if files of this
|
||||
// * type do not support alternative language renderings.
|
||||
// *
|
||||
// * @param File $file
|
||||
// * @return String|null Language code or null if multi-language not supported for filetype.
|
||||
// * @since 1.23
|
||||
// */
|
||||
// public function getDefaultRenderLanguage(File $file) {
|
||||
// return null;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * If its an audio file, return the length of the file. Otherwise 0.
|
||||
// *
|
||||
// * File::getLength() existed for a long time, but was calling a method
|
||||
// * that only existed in some subclasses of this class (The TMH ones).
|
||||
// *
|
||||
// * @param File $file
|
||||
// * @return float length in seconds
|
||||
// * @since 1.23
|
||||
// */
|
||||
// public function getLength($file) {
|
||||
// return 0.0;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * True if creating thumbnails from the file is large or otherwise resource-intensive.
|
||||
// * @param File $file
|
||||
// * @return boolean
|
||||
// */
|
||||
// public function isExpensiveToThumbnail($file) {
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Returns whether or not this handler supports the chained generation of thumbnails according
|
||||
// * to buckets
|
||||
// * @return boolean
|
||||
// * @since 1.24
|
||||
// */
|
||||
// public function supportsBucketing() {
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Returns a normalised paramsVar array for which parameters have been cleaned up for bucketing
|
||||
// * purposes
|
||||
// * @param array $paramsVar
|
||||
// * @return array
|
||||
// */
|
||||
// public function sanitizeParamsForBucketing($paramsVar) {
|
||||
// return $paramsVar;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Gets configuration for the file warning message. Return value of
|
||||
// * the following structure:
|
||||
// * [
|
||||
// * // Required, module with messages loaded for the client
|
||||
// * 'module' => 'example.filewarning.messages',
|
||||
// * // Required, array of names of messages
|
||||
// * 'messages' => [
|
||||
// * // Required, main warning message
|
||||
// * 'main' => 'example-filewarning-main',
|
||||
// * // Optional, header for warning dialog
|
||||
// * 'header' => 'example-filewarning-header',
|
||||
// * // Optional, footer for warning dialog
|
||||
// * 'footer' => 'example-filewarning-footer',
|
||||
// * // Optional, text for more-information link (see below)
|
||||
// * 'info' => 'example-filewarning-info',
|
||||
// * ],
|
||||
// * // Optional, link for more information
|
||||
// * 'link' => 'http://example.com',
|
||||
// * ]
|
||||
// *
|
||||
// * Returns null if no warning is necessary.
|
||||
// * @param File $file
|
||||
// * @return array|null
|
||||
// */
|
||||
// public function getWarningConfig($file) {
|
||||
// return null;
|
||||
// }
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.xowa.mediawiki.includes.media; import gplx.*; import gplx.xowa.*; import gplx.xowa.mediawiki.*; import gplx.xowa.mediawiki.includes.*;
|
||||
// XO.MW:MW has registry and instance cache; XO only has instance
|
||||
// XO.MW:SYNC:1.29; DATE:2017-02-05
|
||||
public class Xomw_MediaHandlerFactory {
|
||||
private final Hash_adp_bry handlers = Hash_adp_bry.cs();
|
||||
|
||||
// XO.MW:SYNC:1.29; DATE:2017-02-05
|
||||
public Xomw_MediaHandlerFactory() {
|
||||
// Default, MediaWiki core media handlers
|
||||
// 'image/jpeg' => JpegHandler::class,
|
||||
handlers.Add(Mime__image__png, new Xomw_TransformationalImageHandler(Mime__image__png)); // PngHandler
|
||||
// 'image/gif' => GIFHandler::class,
|
||||
// 'image/tiff' => TiffHandler::class,
|
||||
// 'image/webp' => WebPHandler::class,
|
||||
// 'image/x-ms-bmp' => BmpHandler::class,
|
||||
// 'image/x-bmp' => BmpHandler::class,
|
||||
// 'image/x-xcf' => XCFHandler::class,
|
||||
// 'image/svg+xml' => SvgHandler::class, // official
|
||||
// 'image/svg' => SvgHandler::class, // compat
|
||||
// 'image/vnd.djvu' => DjVuHandler::class, // official
|
||||
// 'image/x.djvu' => DjVuHandler::class, // compat
|
||||
// 'image/x-djvu' => DjVuHandler::class, // compat
|
||||
|
||||
}
|
||||
|
||||
// XO.MW:SYNC:1.29; DATE:2017-02-05
|
||||
public Xomw_MediaHandler getHandler(byte[] type) {
|
||||
return (Xomw_MediaHandler)handlers.Get_by(type);
|
||||
}
|
||||
|
||||
public static byte[]
|
||||
Mime__image__jpeg = Bry_.new_a7("image/jpeg")
|
||||
, Mime__image__png = Bry_.new_a7("image/png")
|
||||
, Mime__image__gif = Bry_.new_a7("image/gif")
|
||||
, Mime__image__tiff = Bry_.new_a7("image/tiff")
|
||||
, Mime__image__webp = Bry_.new_a7("image/webp")
|
||||
, Mime__image__x_ms_bmp = Bry_.new_a7("image/x-ms-bmp")
|
||||
, Mime__image__x_bmp = Bry_.new_a7("image/x-bmp")
|
||||
, Mime__image__x_xcf = Bry_.new_a7("image/x-xcf")
|
||||
, Mime__image__svg_xml = Bry_.new_a7("image/svg+xml")
|
||||
, Mime__image__svg = Bry_.new_a7("image/svg")
|
||||
, Mime__image__vnd_djvu = Bry_.new_a7("image/vnd.djvu")
|
||||
, Mime__image__x_djvu_dot = Bry_.new_a7("image/x.djvu")
|
||||
, Mime__image__x_djvu_dash = Bry_.new_a7("image/x-djvu")
|
||||
;
|
||||
}
|
||||
@@ -0,0 +1,281 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.xowa.mediawiki.includes.media; import gplx.*; import gplx.xowa.*; import gplx.xowa.mediawiki.*; import gplx.xowa.mediawiki.includes.*;
|
||||
import gplx.langs.htmls.*;
|
||||
import gplx.xowa.mediawiki.includes.utls.*;
|
||||
import gplx.xowa.mediawiki.includes.parsers.lnkis.*;
|
||||
import gplx.xowa.mediawiki.includes.filerepo.file.*;
|
||||
public abstract class Xomw_MediaTransformOutput {
|
||||
public Xomw_MediaTransformOutput(Xomw_File file, byte[] url, byte[] path, int width, int height) {
|
||||
this.file = file;
|
||||
this.url = url;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
}
|
||||
// /** @var array Associative array mapping optional supplementary image files
|
||||
// * from pixel density (eg 1.5 or 2) to additional URLs.
|
||||
// */
|
||||
// public $responsiveUrls = [];
|
||||
|
||||
/** @var File */
|
||||
private final Xomw_File file;
|
||||
|
||||
/** @var int Image width */
|
||||
protected final int width;
|
||||
|
||||
/** @var int Image height */
|
||||
protected final int height;
|
||||
|
||||
/** @var String URL path to the thumb */
|
||||
protected final byte[] url;
|
||||
|
||||
// /** @var boolean|String */
|
||||
// protected $page;
|
||||
//
|
||||
// /** @var boolean|String Filesystem path to the thumb */
|
||||
// protected $path;
|
||||
//
|
||||
// /** @var boolean|String Language code, false if not set */
|
||||
// protected $lang;
|
||||
//
|
||||
// /** @var boolean|String Permanent storage path */
|
||||
// protected $storagePath = false;
|
||||
|
||||
|
||||
/**
|
||||
* @return int Width of the output box
|
||||
*/
|
||||
public int getWidth() {
|
||||
return this.width;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int Height of the output box
|
||||
*/
|
||||
public int getHeight() {
|
||||
return this.height;
|
||||
}
|
||||
|
||||
// /**
|
||||
// * @return File
|
||||
// */
|
||||
// public function getFile() {
|
||||
// return $this->file;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Get the final extension of the thumbnail.
|
||||
// * Returns false for scripted transformations.
|
||||
// * @return String|boolean
|
||||
// */
|
||||
// public function getExtension() {
|
||||
// return $this->path ? FileBackend::extensionFromPath( $this->path ) : false;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * @return String|boolean The thumbnail URL
|
||||
// */
|
||||
// public function getUrl() {
|
||||
// return $this->url;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * @return String|boolean The permanent thumbnail storage path
|
||||
// */
|
||||
// public function getStoragePath() {
|
||||
// return $this->storagePath;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * @param String $storagePath The permanent storage path
|
||||
// * @return void
|
||||
// */
|
||||
// public function setStoragePath( $storagePath ) {
|
||||
// $this->storagePath = $storagePath;
|
||||
// if ( $this->path === false ) {
|
||||
// $this->path = $storagePath;
|
||||
// }
|
||||
// }
|
||||
|
||||
/**
|
||||
* Fetch HTML for this transform output
|
||||
*
|
||||
* @param array $options Associative array of options. Boolean options
|
||||
* should be indicated with a value of true for true, and false or
|
||||
* absent for false.
|
||||
*
|
||||
* alt Alternate text or caption
|
||||
* desc-link Boolean, show a description link
|
||||
* file-link Boolean, show a file download link
|
||||
* custom-url-link Custom URL to link to
|
||||
* custom-title-link Custom Title Object to link to
|
||||
* valign vertical-align property, if the output is an inline element
|
||||
* img-class Class applied to the "<img>" tag, if there is such a tag
|
||||
*
|
||||
* For images, desc-link and file-link are implemented as a click-through. For
|
||||
* sounds and videos, they may be displayed in other ways.
|
||||
*
|
||||
* @return String
|
||||
*/
|
||||
public abstract void toHtml(Bry_bfr bfr, Bry_bfr tmp, Xomw_params_mto options);
|
||||
|
||||
// /**
|
||||
// * This will be overridden to return true in error classes
|
||||
// * @return boolean
|
||||
// */
|
||||
// public function isError() {
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Check if an output thumbnail file actually exists.
|
||||
// *
|
||||
// * This will return false if there was an error, the
|
||||
// * thumbnail is to be handled client-side only, or if
|
||||
// * transformation was deferred via TRANSFORM_LATER.
|
||||
// * This file may exist as a new file in /tmp, a file
|
||||
// * in permanent storage, or even refer to the original.
|
||||
// *
|
||||
// * @return boolean
|
||||
// */
|
||||
// public function hasFile() {
|
||||
// // If TRANSFORM_LATER, $this->path will be false.
|
||||
// // Note: a null path means "use the source file".
|
||||
// return ( !$this->isError() && ( $this->path || $this->path === null ) );
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Check if the output thumbnail is the same as the source.
|
||||
// * This can occur if the requested width was bigger than the source.
|
||||
// *
|
||||
// * @return boolean
|
||||
// */
|
||||
// public function fileIsSource() {
|
||||
// return ( !$this->isError() && $this->path === null );
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Get the path of a file system copy of the thumbnail.
|
||||
// * Callers should never write to this path.
|
||||
// *
|
||||
// * @return String|boolean Returns false if there isn't one
|
||||
// */
|
||||
// public function getLocalCopyPath() {
|
||||
// if ( $this->isError() ) {
|
||||
// return false;
|
||||
// } elseif ( $this->path === null ) {
|
||||
// return $this->file->getLocalRefPath(); // assume thumb was not scaled
|
||||
// } elseif ( FileBackend::isStoragePath( $this->path ) ) {
|
||||
// $be = $this->file->getRepo()->getBackend();
|
||||
// // The temp file will be process cached by FileBackend
|
||||
// $fsFile = $be->getLocalReference( [ 'src' => $this->path ] );
|
||||
//
|
||||
// return $fsFile ? $fsFile->getPath() : false;
|
||||
// } else {
|
||||
// return $this->path; // may return false
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Stream the file if there were no errors
|
||||
// *
|
||||
// * @param array $headers Additional HTTP headers to send on success
|
||||
// * @return Status
|
||||
// * @since 1.27
|
||||
// */
|
||||
// public function streamFileWithStatus( $headers = [] ) {
|
||||
// if ( !$this->path ) {
|
||||
// return Status::newFatal( 'backend-fail-stream', '<no path>' );
|
||||
// } elseif ( FileBackend::isStoragePath( $this->path ) ) {
|
||||
// $be = $this->file->getRepo()->getBackend();
|
||||
// return $be->streamFile( [ 'src' => $this->path, 'headers' => $headers ] );
|
||||
// } else { // FS-file
|
||||
// $success = StreamFile::stream( $this->getLocalCopyPath(), $headers );
|
||||
// return $success ? Status::newGood() : Status::newFatal( 'backend-fail-stream', $this->path );
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Stream the file if there were no errors
|
||||
// *
|
||||
// * @deprecated since 1.26, use streamFileWithStatus
|
||||
// * @param array $headers Additional HTTP headers to send on success
|
||||
// * @return boolean Success
|
||||
// */
|
||||
// public function streamFile( $headers = [] ) {
|
||||
// $this->streamFileWithStatus( $headers )->isOK();
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Wrap some XHTML text in an anchor tag with the given attributes
|
||||
// *
|
||||
// * @param array $linkAttribs
|
||||
// * @param String $contents
|
||||
// * @return String
|
||||
// */
|
||||
// protected function linkWrap( $linkAttribs, $contents ) {
|
||||
// if ( $linkAttribs ) {
|
||||
// return Xml::tags( 'a', $linkAttribs, $contents );
|
||||
// } else {
|
||||
// return $contents;
|
||||
// }
|
||||
// }
|
||||
|
||||
/**
|
||||
* @param String $title
|
||||
* @param String|array $prms Query parameters to add
|
||||
* @return array
|
||||
*/
|
||||
public void getDescLinkAttribs(List_adp attribs, byte[] title, List_adp prms) {
|
||||
// if ( is_array( prms ) ) {
|
||||
// $query = prms;
|
||||
// } else {
|
||||
// $query = [];
|
||||
// }
|
||||
// if ( $this->page && $this->page !== 1 ) {
|
||||
// $query['page'] = $this->page;
|
||||
// }
|
||||
// if ( $this->lang ) {
|
||||
// $query['lang'] = $this->lang;
|
||||
// }
|
||||
//
|
||||
// if ( is_string( prms ) && prms !== '' ) {
|
||||
// $query = prms . '&' . wfArrayToCgi( $query );
|
||||
// }
|
||||
|
||||
attribs.Clear();
|
||||
// 'href' => $this->file->getTitle()->getLocalURL( $query ),
|
||||
attribs.Add_many(Gfh_atr_.Bry__href, this.file.getTitle());
|
||||
attribs.Add_many(Gfh_atr_.Bry__class, Bry__class__image);
|
||||
if (title != null) {
|
||||
attribs.Add_many(Gfh_atr_.Bry__title, title);
|
||||
}
|
||||
}
|
||||
|
||||
// Wrap some XHTML text in an anchor tag with the given attributes
|
||||
// XO.MW:SYNC:1.29; DATE:2017-02-03
|
||||
protected void Link_wrap(Bry_bfr bfr, List_adp link_attribs, byte[] contents) {
|
||||
if (link_attribs != null) {
|
||||
Xomw_xml.Tags(bfr, Gfh_tag_.Bry__a, link_attribs, contents);
|
||||
}
|
||||
else {
|
||||
bfr.Add(contents);
|
||||
}
|
||||
}
|
||||
private static final byte[] Bry__class__image = Bry_.new_a7("image");
|
||||
}
|
||||
@@ -0,0 +1,214 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.xowa.mediawiki.includes.media; import gplx.*; import gplx.xowa.*; import gplx.xowa.mediawiki.*; import gplx.xowa.mediawiki.includes.*;
|
||||
import gplx.langs.htmls.*;
|
||||
import gplx.xowa.mediawiki.includes.utls.*;
|
||||
import gplx.xowa.mediawiki.includes.parsers.lnkis.*;
|
||||
import gplx.xowa.mediawiki.includes.filerepo.file.*;
|
||||
// Media transform output for images
|
||||
public class Xomw_ThumbnailImage extends Xomw_MediaTransformOutput { private final List_adp attribs = List_adp_.New(), link_attribs = List_adp_.New();
|
||||
public Xomw_ThumbnailImage(Xomw_File file, byte[] url, byte[] path, int w, int h) {super(file, url, path, w, h);
|
||||
}
|
||||
/**
|
||||
* Get a thumbnail Object from a file and parameters.
|
||||
* If path is set to null, the output file is treated as a source copy.
|
||||
* If path is set to false, no output file will be created.
|
||||
* parameters should include, as a minimum, (file) 'width' and 'height'.
|
||||
* It may also include a 'page' parameter for multipage files.
|
||||
*
|
||||
* @param File file
|
||||
* @param String url URL path to the thumb
|
||||
* @param String|boolean path Filesystem path to the thumb
|
||||
* @param array parameters Associative array of parameters
|
||||
*/
|
||||
public Xomw_ThumbnailImage(Xomw_File file, byte[] url, byte[] path, Xomw_params_handler parameters) {super(file, url, path, parameters.width, parameters.height);
|
||||
// defaults = [
|
||||
// 'page' => false,
|
||||
// 'lang' => false
|
||||
// ];
|
||||
//
|
||||
// if (is_array(parameters)) {
|
||||
// actualParams = parameters + defaults;
|
||||
// } else {
|
||||
// // Using old format, should convert. Later a warning could be added here.
|
||||
// numArgs = func_num_args();
|
||||
// actualParams = [
|
||||
// 'width' => path,
|
||||
// 'height' => parameters,
|
||||
// 'page' => (numArgs > 5) ? func_get_arg(5) : false
|
||||
// ] + defaults;
|
||||
// path = (numArgs > 4) ? func_get_arg(4) : false;
|
||||
// }
|
||||
|
||||
// this->file = file;
|
||||
// this->url = url;
|
||||
// this->path = path;
|
||||
|
||||
// These should be integers when they get here.
|
||||
// If not, there's a bug somewhere. But let's at
|
||||
// least produce valid HTML code regardless.
|
||||
// this->width = round(actualParams['width']);
|
||||
// this->height = round(actualParams['height']);
|
||||
|
||||
// this->page = actualParams['page'];
|
||||
// this->lang = actualParams['lang'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return HTML <img ... /> tag for the thumbnail, will include
|
||||
* width and height attributes and a blank alt text (as required).
|
||||
*
|
||||
* @param array options Associative array of options. Boolean options
|
||||
* should be indicated with a value of true for true, and false or
|
||||
* absent for false.
|
||||
*
|
||||
* alt HTML alt attribute
|
||||
* title HTML title attribute
|
||||
* desc-link Boolean, show a description link
|
||||
* file-link Boolean, show a file download link
|
||||
* valign vertical-align property, if the output is an inline element
|
||||
* img-class Class applied to the \<img\> tag, if there is such a tag
|
||||
* desc-query String, description link query prms
|
||||
* @Override width Override width attribute. Should generally not set
|
||||
* @Override height Override height attribute. Should generally not set
|
||||
* no-dimensions Boolean, skip width and height attributes (useful if
|
||||
* set in CSS)
|
||||
* custom-url-link Custom URL to link to
|
||||
* custom-title-link Custom Title Object to link to
|
||||
* custom target-link Value of the target attribute, for custom-target-link
|
||||
* parser-extlink-* Attributes added by parser for external links:
|
||||
* parser-extlink-rel: add rel="nofollow"
|
||||
* parser-extlink-target: link target, but overridden by custom-target-link
|
||||
*
|
||||
* For images, desc-link and file-link are implemented as a click-through. For
|
||||
* sounds and videos, they may be displayed in other ways.
|
||||
*
|
||||
* @throws MWException
|
||||
* @return String
|
||||
*/
|
||||
// Return HTML <img ... /> tag for the thumbnail, will include
|
||||
// width and height attributes and a blank alt text (as required).
|
||||
//
|
||||
// @param array options Associative array of options. Boolean options
|
||||
// should be indicated with a value of true for true, and false or
|
||||
// absent for false.
|
||||
//
|
||||
// alt HTML alt attribute
|
||||
// title HTML title attribute
|
||||
// desc-link Boolean, show a description link
|
||||
// file-link Boolean, show a file download link
|
||||
// valign vertical-align property, if the output is an inline element
|
||||
// img-class Class applied to the \<img\> tag, if there is such a tag
|
||||
// desc-query String, description link query prms
|
||||
// override-width Override width attribute. Should generally not set
|
||||
// override-height Override height attribute. Should generally not set
|
||||
// no-dimensions Boolean, skip width and height attributes (useful if
|
||||
// set in CSS)
|
||||
// custom-url-link Custom URL to link to
|
||||
// custom-title-link Custom Title Object to link to
|
||||
// custom target-link Value of the target attribute, for custom-target-link
|
||||
// parser-extlink-* Attributes added by parser for external links:
|
||||
// parser-extlink-rel: add rel="nofollow"
|
||||
// parser-extlink-target: link target, but overridden by custom-target-link
|
||||
//
|
||||
// For images, desc-link and file-link are implemented as a click-through. For
|
||||
// sounds and videos, they may be displayed in other ways.
|
||||
// XO.MW:SYNC:1.29; DATE:2017-02-03
|
||||
@Override public void toHtml(Bry_bfr bfr, Bry_bfr tmp, Xomw_params_mto options) {
|
||||
byte[] alt = options.alt;
|
||||
|
||||
// byte[] query = options.desc_query;
|
||||
|
||||
attribs.Clear();
|
||||
attribs.Add_many(Gfh_atr_.Bry__alt, alt);
|
||||
attribs.Add_many(Gfh_atr_.Bry__src, url);
|
||||
boolean link_attribs_is_null = false;
|
||||
if (!Php_utl_.empty(options.custom_url_link)) {
|
||||
link_attribs.Clear();
|
||||
link_attribs.Add_many(Gfh_atr_.Bry__href, options.custom_url_link);
|
||||
if (!Php_utl_.empty(options.title)) {
|
||||
link_attribs.Add_many(Gfh_atr_.Bry__title, options.title);
|
||||
}
|
||||
if (Php_utl_.empty(options.custom_target_link)) {
|
||||
link_attribs.Add_many(Gfh_atr_.Bry__target, options.custom_target_link);
|
||||
}
|
||||
else if (Php_utl_.empty(options.parser_extlink_target)) {
|
||||
link_attribs.Add_many(Gfh_atr_.Bry__target, options.parser_extlink_target);
|
||||
}
|
||||
if (Php_utl_.empty(options.parser_extlink_rel)) {
|
||||
link_attribs.Add_many(Gfh_atr_.Bry__rel, options.parser_extlink_rel);
|
||||
}
|
||||
}
|
||||
else if (!Php_utl_.empty(options.custom_title_link)) {
|
||||
// byte[] title = options.custom_title_link;
|
||||
// link_attribs.Clear();
|
||||
// link_attribs.Add_many(Gfh_atr_.Bry__href, title.Get_link_url());
|
||||
// byte[] options_title = options.title;
|
||||
// link_attribs.Add_many(Gfh_atr_.Bry__title, Php_utl_.empty(options_title) ? title.Get_full_text() : options_title);
|
||||
}
|
||||
else if (!Php_utl_.empty(options.desc_link)) {
|
||||
// link_attribs = this.getDescLinkAttribs(
|
||||
// empty(options['title']) ? null : options['title'],
|
||||
// $query
|
||||
// );
|
||||
link_attribs.Clear();
|
||||
this.getDescLinkAttribs(link_attribs,
|
||||
Php_utl_.empty(options.title) ? null : options.title,
|
||||
null);
|
||||
}
|
||||
else if (!Php_utl_.empty(options.file_link)) {
|
||||
// link_attribs.Clear();
|
||||
// link_attribs.Add_many(Gfh_atr_.Bry__href, file.Get_url());
|
||||
}
|
||||
else {
|
||||
link_attribs_is_null = true;
|
||||
if (!Php_utl_.empty(options.title)) {
|
||||
attribs.Add_many(Gfh_atr_.Bry__title, options.title);
|
||||
}
|
||||
}
|
||||
|
||||
if (!Php_utl_.empty(options.no_dimensions)) {
|
||||
attribs.Add_many(Gfh_atr_.Bry__width, Int_.To_bry(width));
|
||||
attribs.Add_many(Gfh_atr_.Bry__height, Int_.To_bry(height));
|
||||
}
|
||||
if (!Php_utl_.empty(options.valign)) {
|
||||
attribs.Add_many(Gfh_atr_.Bry__style, Bry_.Add(Bry__vertical_align, options.valign));
|
||||
}
|
||||
if (!Php_utl_.empty(options.img_cls)) {
|
||||
attribs.Add_many(Gfh_atr_.Bry__class, options.img_cls);
|
||||
}
|
||||
if (Php_utl_.isset(options.override_height)) {
|
||||
attribs.Add_many(Gfh_atr_.Bry__class, options.override_height);
|
||||
}
|
||||
if (Php_utl_.isset(options.override_width)) {
|
||||
attribs.Add_many(Gfh_atr_.Bry__width, options.override_height);
|
||||
}
|
||||
|
||||
// Additional densities for responsive images, if specified.
|
||||
// If any of these urls is the same as src url, it'll be excluded.
|
||||
// $responsiveUrls = array_diff(this.responsiveUrls, [ this.url ]);
|
||||
// if (!Php_utl_.empty($responsiveUrls)) {
|
||||
// $attribs['srcset'] = Html::srcSet($responsiveUrls);
|
||||
// }
|
||||
|
||||
// XO.MW.HOOK:ThumbnailBeforeProduceHTML
|
||||
Xomw_xml.Element(tmp, Gfh_tag_.Bry__img, attribs, Bry_.Empty, Bool_.Y);
|
||||
Link_wrap(bfr, link_attribs_is_null ? null : link_attribs, tmp.To_bry_and_clear());
|
||||
}
|
||||
private static final byte[] Bry__vertical_align = Bry_.new_a7("vertical-align: ");
|
||||
}
|
||||
@@ -0,0 +1,611 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.xowa.mediawiki.includes.media; import gplx.*; import gplx.xowa.*; import gplx.xowa.mediawiki.*; import gplx.xowa.mediawiki.includes.*;
|
||||
import gplx.xowa.mediawiki.includes.filerepo.file.*;
|
||||
import gplx.xowa.mediawiki.includes.parsers.lnkis.*;
|
||||
public class Xomw_TransformationalImageHandler extends Xomw_ImageHandler { public Xomw_TransformationalImageHandler(byte[] key) {super(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param File image
|
||||
* @param array paramsVar Transform parameters. Entries with the keys 'width'
|
||||
* and 'height' are the respective screen width and height, while the keys
|
||||
* 'physicalWidth' and 'physicalHeight' indicate the thumbnail dimensions.
|
||||
* @return boolean
|
||||
*/
|
||||
@Override public boolean normaliseParams(Xomw_File image, Xomw_params_handler prms) {
|
||||
if (!super.normaliseParams(image, prms)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Obtain the source, pre-rotation dimensions
|
||||
int srcWidth = image.getWidth(prms.page);
|
||||
int srcHeight = image.getHeight(prms.page);
|
||||
|
||||
// Don't make an image bigger than the source
|
||||
if (prms.physicalWidth >= srcWidth) {
|
||||
prms.physicalWidth = srcWidth;
|
||||
prms.physicalHeight = srcHeight;
|
||||
|
||||
// Skip scaling limit checks if no scaling is required
|
||||
// due to requested size being bigger than source.
|
||||
if (!image.mustRender()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// /**
|
||||
// * Extracts the width/height if the image will be scaled before rotating
|
||||
// *
|
||||
// * This will match the physical size/aspect ratio of the original image
|
||||
// * prior to application of the rotation -- so for a portrait image that's
|
||||
// * stored as raw landscape with 90-degress rotation, the resulting size
|
||||
// * will be wider than it is tall.
|
||||
// *
|
||||
// * @param array paramsVar Parameters as returned by normaliseParams
|
||||
// * @param int rotation The rotation angle that will be applied
|
||||
// * @return array (width, height) array
|
||||
// */
|
||||
// public function extractPreRotationDimensions(paramsVar, rotation) {
|
||||
// if (rotation == 90 || rotation == 270) {
|
||||
// // We'll resize before rotation, so swap the dimensions again
|
||||
// width = paramsVar['physicalHeight'];
|
||||
// height = paramsVar['physicalWidth'];
|
||||
// } else {
|
||||
// width = paramsVar['physicalWidth'];
|
||||
// height = paramsVar['physicalHeight'];
|
||||
// }
|
||||
//
|
||||
// return [ width, height ];
|
||||
// }
|
||||
//
|
||||
/**
|
||||
* Create a thumbnail.
|
||||
*
|
||||
* This sets up various parameters, and then calls a helper method
|
||||
* based on this.getScalerType in order to scale the image.
|
||||
*
|
||||
* @param File image
|
||||
* @param String dstPath
|
||||
* @param String dstUrl
|
||||
* @param array paramsVar
|
||||
* @param int flags
|
||||
* @return MediaTransformError|ThumbnailImage|TransformParameterError
|
||||
*/
|
||||
@Override public Xomw_MediaTransformOutput doTransform(Xomw_File image, byte[] dstPath, byte[] dstUrl, Xomw_params_handler prms, int flags) {
|
||||
// if (!this.normaliseParams(image, paramsVar)) {
|
||||
// return new TransformParameterError(paramsVar);
|
||||
// }
|
||||
//
|
||||
// // Create a parameter array to pass to the scaler
|
||||
Xomw_params_scalar scalerParams = new Xomw_params_scalar();
|
||||
// // The size to which the image will be resized
|
||||
scalerParams.physicalWidth = prms.physicalWidth;
|
||||
scalerParams.physicalHeight = prms.physicalHeight;
|
||||
// 'physicalDimensions' => "{paramsVar['physicalWidth']}x{paramsVar['physicalHeight']}",
|
||||
// The size of the image on the page
|
||||
scalerParams.clientWidth = prms.width;
|
||||
scalerParams.clientHeight = prms.height;
|
||||
// Comment as will be added to the Exif of the thumbnail
|
||||
// 'comment' => isset(paramsVar['descriptionUrl'])
|
||||
// ? "File source: {paramsVar['descriptionUrl']}"
|
||||
// : '',
|
||||
// Properties of the original image
|
||||
scalerParams.srcWidth = image.getWidth();
|
||||
scalerParams.srcHeight = image.getHeight();
|
||||
scalerParams.mimeType = image.getMimeType();
|
||||
scalerParams.dstPath = dstPath;
|
||||
scalerParams.dstUrl = dstUrl;
|
||||
// 'interlace' => isset(paramsVar['interlace']) ? paramsVar['interlace'] : false,
|
||||
|
||||
// if (isset(paramsVar['quality']) && paramsVar['quality'] === 'low') {
|
||||
// scalerParams['quality'] = 30;
|
||||
// }
|
||||
|
||||
// For subclasses that might be paged.
|
||||
// if (image.isMultipage() && isset(paramsVar['page'])) {
|
||||
// scalerParams['page'] = intval(paramsVar['page']);
|
||||
// }
|
||||
|
||||
// Determine scaler type
|
||||
// scaler = this.getScalerType(dstPath);
|
||||
//
|
||||
// if (is_array(scaler)) {
|
||||
// scalerName = get_class(scaler[0]);
|
||||
// } else {
|
||||
// scalerName = scaler;
|
||||
// }
|
||||
//
|
||||
// wfDebug(__METHOD__ . ": creating {scalerParams['physicalDimensions']} " .
|
||||
// "thumbnail at dstPath using scaler scalerName\n");
|
||||
|
||||
if (!image.mustRender() &&
|
||||
scalerParams.physicalWidth == scalerParams.srcWidth
|
||||
&& scalerParams.physicalHeight == scalerParams.srcHeight
|
||||
// && !isset(scalerParams['quality'])
|
||||
) {
|
||||
|
||||
// normaliseParams (or the user) wants us to return the unscaled image
|
||||
// wfDebug(__METHOD__ . ": returning unscaled image\n");
|
||||
|
||||
return this.getClientScalingThumbnailImage(image, scalerParams);
|
||||
}
|
||||
|
||||
// if (scaler == 'client') {
|
||||
// // Client-side image scaling, use the source URL
|
||||
// // Using the destination URL in a TRANSFORM_LATER request would be incorrect
|
||||
// return this.getClientScalingThumbnailImage(image, scalerParams);
|
||||
// }
|
||||
//
|
||||
// if (image.isTransformedLocally() && !this.isImageAreaOkForThumbnaling(image, paramsVar)) {
|
||||
// global wgMaxImageArea;
|
||||
// return new TransformTooBigImageAreaError(paramsVar, wgMaxImageArea);
|
||||
// }
|
||||
//
|
||||
// if (flags & self::TRANSFORM_LATER) {
|
||||
// wfDebug(__METHOD__ . ": Transforming later per flags.\n");
|
||||
// newParams = [
|
||||
// 'width' => scalerParams['clientWidth'],
|
||||
// 'height' => scalerParams['clientHeight']
|
||||
// ];
|
||||
// if (isset(paramsVar['quality'])) {
|
||||
// newParams['quality'] = paramsVar['quality'];
|
||||
// }
|
||||
// if (isset(paramsVar['page']) && paramsVar['page']) {
|
||||
// newParams['page'] = paramsVar['page'];
|
||||
// }
|
||||
// return new Xomw_ThumbnailImage(image, dstUrl, null, newParams);
|
||||
return new Xomw_ThumbnailImage(image, dstUrl, null, prms);
|
||||
// }
|
||||
//
|
||||
// // Try to make a target path for the thumbnail
|
||||
// if (!wfMkdirParents(dirname(dstPath), null, __METHOD__)) {
|
||||
// wfDebug(__METHOD__ . ": Unable to create thumbnail destination " .
|
||||
// "directory, falling back to client scaling\n");
|
||||
//
|
||||
// return this.getClientScalingThumbnailImage(image, scalerParams);
|
||||
// }
|
||||
//
|
||||
// // Transform functions and binaries need a FS source file
|
||||
// thumbnailSource = this.getThumbnailSource(image, paramsVar);
|
||||
//
|
||||
// // If the source isn't the original, disable EXIF rotation because it's already been applied
|
||||
// if (scalerParams['srcWidth'] != thumbnailSource['width']
|
||||
// || scalerParams['srcHeight'] != thumbnailSource['height']) {
|
||||
// scalerParams['disableRotation'] = true;
|
||||
// }
|
||||
//
|
||||
// scalerParams['srcPath'] = thumbnailSource['path'];
|
||||
// scalerParams['srcWidth'] = thumbnailSource['width'];
|
||||
// scalerParams['srcHeight'] = thumbnailSource['height'];
|
||||
//
|
||||
// if (scalerParams['srcPath'] === false) { // Failed to get local copy
|
||||
// wfDebugLog('thumbnail',
|
||||
// sprintf('Thumbnail failed on %s: could not get local copy of "%s"',
|
||||
// wfHostname(), image.getName()));
|
||||
//
|
||||
// return new MediaTransformError('thumbnail_error',
|
||||
// scalerParams['clientWidth'], scalerParams['clientHeight'],
|
||||
// wfMessage('filemissing')
|
||||
// );
|
||||
// }
|
||||
//
|
||||
// // Try a hook. Called "Bitmap" for historical reasons.
|
||||
// /** @var mto MediaTransformOutput */
|
||||
// mto = null;
|
||||
// Hooks::run('BitmapHandlerTransform', [ this, image, &scalerParams, &mto ]);
|
||||
// if (!is_null(mto)) {
|
||||
// wfDebug(__METHOD__ . ": Hook to BitmapHandlerTransform created an mto\n");
|
||||
// scaler = 'hookaborted';
|
||||
// }
|
||||
//
|
||||
// // scaler will return a MediaTransformError on failure, or false on success.
|
||||
// // If the scaler is succesful, it will have created a thumbnail at the destination
|
||||
// // path.
|
||||
// if (is_array(scaler) && is_callable(scaler)) {
|
||||
// // Allow subclasses to specify their own rendering methods.
|
||||
// err = call_user_func(scaler, image, scalerParams);
|
||||
// } else {
|
||||
// switch (scaler) {
|
||||
// case 'hookaborted':
|
||||
// // Handled by the hook above
|
||||
// err = mto.isError() ? mto : false;
|
||||
// break;
|
||||
// case 'im':
|
||||
// err = this.transformImageMagick(image, scalerParams);
|
||||
// break;
|
||||
// case 'custom':
|
||||
// err = this.transformCustom(image, scalerParams);
|
||||
// break;
|
||||
// case 'imext':
|
||||
// err = this.transformImageMagickExt(image, scalerParams);
|
||||
// break;
|
||||
// case 'gd':
|
||||
// default:
|
||||
// err = this.transformGd(image, scalerParams);
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// // Remove the file if a zero-byte thumbnail was created, or if there was an error
|
||||
// removed = this.removeBadFile(dstPath, (boolean)err);
|
||||
// if (err) {
|
||||
// // transform returned MediaTransforError
|
||||
// return err;
|
||||
// } elseif (removed) {
|
||||
// // Thumbnail was zero-byte and had to be removed
|
||||
// return new MediaTransformError('thumbnail_error',
|
||||
// scalerParams['clientWidth'], scalerParams['clientHeight'],
|
||||
// wfMessage('unknown-error')
|
||||
// );
|
||||
// } elseif (mto) {
|
||||
// return mto;
|
||||
// } else {
|
||||
// newParams = [
|
||||
// 'width' => scalerParams['clientWidth'],
|
||||
// 'height' => scalerParams['clientHeight']
|
||||
// ];
|
||||
// if (isset(paramsVar['quality'])) {
|
||||
// newParams['quality'] = paramsVar['quality'];
|
||||
// }
|
||||
// if (isset(paramsVar['page']) && paramsVar['page']) {
|
||||
// newParams['page'] = paramsVar['page'];
|
||||
// }
|
||||
// return new ThumbnailImage(image, dstUrl, dstPath, newParams);
|
||||
// }
|
||||
// return null;
|
||||
}
|
||||
|
||||
// /**
|
||||
// * Get the source file for the transform
|
||||
// *
|
||||
// * @param File file
|
||||
// * @param array paramsVar
|
||||
// * @return array Array with keys width, height and path.
|
||||
// */
|
||||
// protected function getThumbnailSource(file, paramsVar) {
|
||||
// return file.getThumbnailSource(paramsVar);
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Returns what sort of scaler type should be used.
|
||||
// *
|
||||
// * Values can be one of client, im, custom, gd, imext, or an array
|
||||
// * of Object, method-name to call that specific method.
|
||||
// *
|
||||
// * If specifying a custom scaler command with [ Obj, method ],
|
||||
// * the method in question should take 2 parameters, a File Object,
|
||||
// * and a scalerParams array with various options (See doTransform
|
||||
// * for what is in scalerParams). On error it should return a
|
||||
// * MediaTransformError Object. On success it should return false,
|
||||
// * and simply make sure the thumbnail file is located at
|
||||
// * scalerParams['dstPath'].
|
||||
// *
|
||||
// * If there is a problem with the output path, it returns "client"
|
||||
// * to do client side scaling.
|
||||
// *
|
||||
// * @param String dstPath
|
||||
// * @param boolean checkDstPath Check that dstPath is valid
|
||||
// * @return String|Callable One of client, im, custom, gd, imext, or a Callable array.
|
||||
// */
|
||||
// abstract protected function getScalerType(dstPath, checkDstPath = true);
|
||||
|
||||
/**
|
||||
* Get a ThumbnailImage that respresents an image that will be scaled
|
||||
* client side
|
||||
*
|
||||
* @param File image File associated with this thumbnail
|
||||
* @param array scalerParams Array with scaler paramsVar
|
||||
* @return ThumbnailImage
|
||||
*
|
||||
* @todo FIXME: No rotation support
|
||||
*/
|
||||
private Xomw_ThumbnailImage getClientScalingThumbnailImage(Xomw_File image, Xomw_params_scalar scalerParams) {
|
||||
Xomw_params_handler prms = new Xomw_params_handler();
|
||||
prms.width = scalerParams.clientWidth;
|
||||
prms.height = scalerParams.clientHeight;
|
||||
|
||||
return new Xomw_ThumbnailImage(image, image.getUrl(), null, prms);
|
||||
}
|
||||
|
||||
// /**
|
||||
// * Transform an image using ImageMagick
|
||||
// *
|
||||
// * This is a stub method. The real method is in BitmapHander.
|
||||
// *
|
||||
// * @param File image File associated with this thumbnail
|
||||
// * @param array paramsVar Array with scaler paramsVar
|
||||
// *
|
||||
// * @return MediaTransformError Error Object if error occurred, false (=no error) otherwise
|
||||
// */
|
||||
// protected function transformImageMagick(image, paramsVar) {
|
||||
// return this.getMediaTransformError(paramsVar, "Unimplemented");
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Transform an image using the Imagick PHP extension
|
||||
// *
|
||||
// * This is a stub method. The real method is in BitmapHander.
|
||||
// *
|
||||
// * @param File image File associated with this thumbnail
|
||||
// * @param array paramsVar Array with scaler paramsVar
|
||||
// *
|
||||
// * @return MediaTransformError Error Object if error occurred, false (=no error) otherwise
|
||||
// */
|
||||
// protected function transformImageMagickExt(image, paramsVar) {
|
||||
// return this.getMediaTransformError(paramsVar, "Unimplemented");
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Transform an image using a custom command
|
||||
// *
|
||||
// * This is a stub method. The real method is in BitmapHander.
|
||||
// *
|
||||
// * @param File image File associated with this thumbnail
|
||||
// * @param array paramsVar Array with scaler paramsVar
|
||||
// *
|
||||
// * @return MediaTransformError Error Object if error occurred, false (=no error) otherwise
|
||||
// */
|
||||
// protected function transformCustom(image, paramsVar) {
|
||||
// return this.getMediaTransformError(paramsVar, "Unimplemented");
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Get a MediaTransformError with error 'thumbnail_error'
|
||||
// *
|
||||
// * @param array paramsVar Parameter array as passed to the transform* functions
|
||||
// * @param String errMsg Error message
|
||||
// * @return MediaTransformError
|
||||
// */
|
||||
// public function getMediaTransformError(paramsVar, errMsg) {
|
||||
// return new MediaTransformError('thumbnail_error', paramsVar['clientWidth'],
|
||||
// paramsVar['clientHeight'], errMsg);
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Transform an image using the built in GD library
|
||||
// *
|
||||
// * This is a stub method. The real method is in BitmapHander.
|
||||
// *
|
||||
// * @param File image File associated with this thumbnail
|
||||
// * @param array paramsVar Array with scaler paramsVar
|
||||
// *
|
||||
// * @return MediaTransformError Error Object if error occurred, false (=no error) otherwise
|
||||
// */
|
||||
// protected function transformGd(image, paramsVar) {
|
||||
// return this.getMediaTransformError(paramsVar, "Unimplemented");
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Escape a String for ImageMagick's property input (e.g. -set -comment)
|
||||
// * See InterpretImageProperties() in magick/property.c
|
||||
// * @param String s
|
||||
// * @return String
|
||||
// */
|
||||
// function escapeMagickProperty(s) {
|
||||
// // Double the backslashes
|
||||
// s = str_replace('\\', '\\\\', s);
|
||||
// // Double the percents
|
||||
// s = str_replace('%', '%%', s);
|
||||
// // Escape initial - or @
|
||||
// if (strlen(s) > 0 && (s[0] === '-' || s[0] === '@')) {
|
||||
// s = '\\' . s;
|
||||
// }
|
||||
//
|
||||
// return s;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Escape a String for ImageMagick's input filenames. See ExpandFilenames()
|
||||
// * and GetPathComponent() in magick/utility.c.
|
||||
// *
|
||||
// * This won't work with an initial ~ or @, so input files should be prefixed
|
||||
// * with the directory name.
|
||||
// *
|
||||
// * Glob character unescaping is broken in ImageMagick before 6.6.1-5, but
|
||||
// * it's broken in a way that doesn't involve trying to convert every file
|
||||
// * in a directory, so we're better off escaping and waiting for the bugfix
|
||||
// * to filter down to users.
|
||||
// *
|
||||
// * @param String path The file path
|
||||
// * @param boolean|String scene The scene specification, or false if there is none
|
||||
// * @throws MWException
|
||||
// * @return String
|
||||
// */
|
||||
// function escapeMagickInput(path, scene = false) {
|
||||
// // Die on initial metacharacters (caller should prepend path)
|
||||
// firstChar = substr(path, 0, 1);
|
||||
// if (firstChar === '~' || firstChar === '@') {
|
||||
// throw new MWException(__METHOD__ . ': cannot escape this path name');
|
||||
// }
|
||||
//
|
||||
// // Escape glob chars
|
||||
// path = preg_replace('/[*?\[\]{}]/', '\\\\\0', path);
|
||||
//
|
||||
// return this.escapeMagickPath(path, scene);
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Escape a String for ImageMagick's output filename. See
|
||||
// * InterpretImageFilename() in magick/image.c.
|
||||
// * @param String path The file path
|
||||
// * @param boolean|String scene The scene specification, or false if there is none
|
||||
// * @return String
|
||||
// */
|
||||
// function escapeMagickOutput(path, scene = false) {
|
||||
// path = str_replace('%', '%%', path);
|
||||
//
|
||||
// return this.escapeMagickPath(path, scene);
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Armour a String against ImageMagick's GetPathComponent(). This is a
|
||||
// * helper function for escapeMagickInput() and escapeMagickOutput().
|
||||
// *
|
||||
// * @param String path The file path
|
||||
// * @param boolean|String scene The scene specification, or false if there is none
|
||||
// * @throws MWException
|
||||
// * @return String
|
||||
// */
|
||||
// protected function escapeMagickPath(path, scene = false) {
|
||||
// // Die on format specifiers (other than drive letters). The regex is
|
||||
// // meant to match all the formats you get from "convert -list format"
|
||||
// if (preg_match('/^([a-zA-Z0-9-]+):/', path, m)) {
|
||||
// if (wfIsWindows() && is_dir(m[0])) {
|
||||
// // OK, it's a drive letter
|
||||
// // ImageMagick has a similar exception, see IsMagickConflict()
|
||||
// } else {
|
||||
// throw new MWException(__METHOD__ . ': unexpected colon character in path name');
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// // If there are square brackets, add a do-nothing scene specification
|
||||
// // to force a literal interpretation
|
||||
// if (scene === false) {
|
||||
// if (strpos(path, '[') !== false) {
|
||||
// path .= '[0--1]';
|
||||
// }
|
||||
// } else {
|
||||
// path .= "[scene]";
|
||||
// }
|
||||
//
|
||||
// return path;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Retrieve the version of the installed ImageMagick
|
||||
// * You can use PHPs version_compare() to use this value
|
||||
// * Value is cached for one hour.
|
||||
// * @return String|boolean Representing the IM version; false on error
|
||||
// */
|
||||
// protected function getMagickVersion() {
|
||||
// cache = MediaWikiServices::getInstance().getLocalServerObjectCache();
|
||||
// method = __METHOD__;
|
||||
// return cache.getWithSetCallback(
|
||||
// 'imagemagick-version',
|
||||
// cache::TTL_HOUR,
|
||||
// function () use (method) {
|
||||
// global wgImageMagickConvertCommand;
|
||||
//
|
||||
// cmd = wfEscapeShellArg(wgImageMagickConvertCommand) . ' -version';
|
||||
// wfDebug(method . ": Running convert -version\n");
|
||||
// retval = '';
|
||||
// return = wfShellExec(cmd, retval);
|
||||
// x = preg_match(
|
||||
// '/Version: ImageMagick ([0-9]*\.[0-9]*\.[0-9]*)/', return, matches
|
||||
// );
|
||||
// if (x != 1) {
|
||||
// wfDebug(method . ": ImageMagick version check failed\n");
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// return matches[1];
|
||||
// }
|
||||
// );
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Returns whether the current scaler supports rotation.
|
||||
// *
|
||||
// * @since 1.24 No longer static
|
||||
// * @return boolean
|
||||
// */
|
||||
// public function canRotate() {
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Should we automatically rotate an image based on exif
|
||||
// *
|
||||
// * @since 1.24 No longer static
|
||||
// * @see wgEnableAutoRotation
|
||||
// * @return boolean Whether auto rotation is enabled
|
||||
// */
|
||||
// public function autoRotateEnabled() {
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Rotate a thumbnail.
|
||||
// *
|
||||
// * This is a stub. See BitmapHandler::rotate.
|
||||
// *
|
||||
// * @param File file
|
||||
// * @param array paramsVar Rotate parameters.
|
||||
// * 'rotation' clockwise rotation in degrees, allowed are multiples of 90
|
||||
// * @since 1.24 Is non-static. From 1.21 it was static
|
||||
// * @return boolean|MediaTransformError
|
||||
// */
|
||||
// public function rotate(file, paramsVar) {
|
||||
// return new MediaTransformError('thumbnail_error', 0, 0,
|
||||
// get_class(this) . ' rotation not implemented');
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Returns whether the file needs to be rendered. Returns true if the
|
||||
// * file requires rotation and we are able to rotate it.
|
||||
// *
|
||||
// * @param File file
|
||||
// * @return boolean
|
||||
// */
|
||||
// public function mustRender(file) {
|
||||
// return this.canRotate() && this.getRotation(file) != 0;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Check if the file is smaller than the maximum image area for thumbnailing.
|
||||
// *
|
||||
// * Runs the 'BitmapHandlerCheckImageArea' hook.
|
||||
// *
|
||||
// * @param File file
|
||||
// * @param array paramsVar
|
||||
// * @return boolean
|
||||
// * @since 1.25
|
||||
// */
|
||||
// public function isImageAreaOkForThumbnaling(file, ¶msVar) {
|
||||
// global wgMaxImageArea;
|
||||
//
|
||||
// // For historical reasons, hook starts with BitmapHandler
|
||||
// checkImageAreaHookResult = null;
|
||||
// Hooks::run(
|
||||
// 'BitmapHandlerCheckImageArea',
|
||||
// [ file, ¶msVar, &checkImageAreaHookResult ]
|
||||
// );
|
||||
//
|
||||
// if (!is_null(checkImageAreaHookResult)) {
|
||||
// // was set by hook, so return that value
|
||||
// return (boolean)checkImageAreaHookResult;
|
||||
// }
|
||||
//
|
||||
// srcWidth = file.getWidth(paramsVar['page']);
|
||||
// srcHeight = file.getHeight(paramsVar['page']);
|
||||
//
|
||||
// if (srcWidth * srcHeight > wgMaxImageArea
|
||||
// && !(file.getMimeType() == 'image/jpeg'
|
||||
// && this.getScalerType(false, false) == 'im')
|
||||
// ) {
|
||||
// // Only ImageMagick can efficiently downsize jpg images without loading
|
||||
// // the entire file in memory
|
||||
// return false;
|
||||
// }
|
||||
// return true;
|
||||
// }
|
||||
}
|
||||
Reference in New Issue
Block a user