Initial commit.
This commit is contained in:
549
lib/php/monica/pic.inc.php
Normal file
549
lib/php/monica/pic.inc.php
Normal file
@@ -0,0 +1,549 @@
|
||||
<?php
|
||||
// File name: pic.inc.php
|
||||
// Description: PHP subroutines to manuplate pictures
|
||||
// Date: 2002-04-16
|
||||
// Author: imacat <imacat@pristine.com.tw>
|
||||
// Copyright: Copyright (C) 2002-2009 Pristine Communications
|
||||
|
||||
// Set the include path
|
||||
if (!defined("INCPATH_SET")) {
|
||||
require_once dirname(__FILE__) . "/incpath.inc.php";
|
||||
}
|
||||
// Referenced subroutines
|
||||
require_once "monica/chkfunc.inc.php";
|
||||
require_once "monica/gettext.inc.php";
|
||||
require_once "monica/htmlchar.inc.php";
|
||||
require_once "monica/newsn.inc.php";
|
||||
require_once "monica/requri.inc.php";
|
||||
require_once "monica/scptpriv.inc.php";
|
||||
require_once "monica/xfileio.inc.php";
|
||||
|
||||
// Settings
|
||||
if (!defined("PIC_MAX_WIDTH")) {
|
||||
define("PIC_MAX_WIDTH", 800);
|
||||
}
|
||||
if (!defined("PIC_MAX_HEIGHT")) {
|
||||
define("PIC_MAX_HEIGHT", 1024);
|
||||
}
|
||||
if (!defined("PIC_MAX_RATIO")) {
|
||||
define("PIC_MAX_RATIO", 9.99);
|
||||
}
|
||||
$PIC_VALID_TYPES = array("image/png", "image/jpeg", "image/gif");
|
||||
$PIC_VALID_SUFS = array("png", "jpg", "gif");
|
||||
$PIC_TYPESUF_MAP = array(
|
||||
"image/png" => "png",
|
||||
"image/jpeg" => "jpg",
|
||||
"image/gif" => "gif");
|
||||
$PIC_VALID_POS = array("L", "R");
|
||||
$PIC_POS_LABEL = array(
|
||||
"L" => N_("Left-aligned"),
|
||||
"R" => N_("Right-aligned"));
|
||||
$PIC_POS_CSS = array(
|
||||
"L" => "float: left;",
|
||||
"R" => "float: right;");
|
||||
if (!defined("PIC_POS_DEFAULT")) {
|
||||
define("PIC_POS_DEFAULT", "L");
|
||||
}
|
||||
if (!defined("SHOWPIC_SCRIPT")) {
|
||||
define("SHOWPIC_SCRIPT", "/admin/showpic.php");
|
||||
}
|
||||
if (!defined("SHOWPIC_PUBLIC_SCRIPT")) {
|
||||
define("SHOWPIC_PUBLIC_SCRIPT", "/showpic.php");
|
||||
}
|
||||
|
||||
// suspend_pic: Suspend a picture to $_SESSION
|
||||
function suspend_pic(&$pic)
|
||||
{
|
||||
$PICS =& pic_deposit();
|
||||
// Generate a new random picture ID
|
||||
$picid = new_sn_assoc($PICS);
|
||||
$pic["sn"] = $picid;
|
||||
// Save the current picture
|
||||
$PICS[$picid] =& $pic;
|
||||
// Return the picture ID
|
||||
return $picid;
|
||||
}
|
||||
|
||||
// check_picfile: Check the uploaded picture file
|
||||
function check_picfile($column = "picfile")
|
||||
{
|
||||
$picfile =& $_FILES[$column];
|
||||
// Check the file upload status
|
||||
switch ($picfile["error"]) {
|
||||
case UPLOAD_ERR_INI_SIZE:
|
||||
return array("msg"=>NC_("This picture file is too large (Max %s)."),
|
||||
"margs"=>array(get_cfg_var("upload_max_filesize")));
|
||||
case UPLOAD_ERR_FORM_SIZE:
|
||||
return array("msg"=>NC_("This picture file is too large (Max %s)."),
|
||||
"margs"=>array(UPLOAD_ERR_FORM_SIZE));
|
||||
case UPLOAD_ERR_PARTIAL:
|
||||
return array("msg"=>NC_("Upload not completed. Disk may be full or connection may be closed in the half. You may try to upload again, or contact the system administrator for this problem."));
|
||||
case UPLOAD_ERR_NO_FILE:
|
||||
return array("msg"=>NC_("Please upload the picture."));
|
||||
default:
|
||||
return array("msg"=>NC_("Upload failed with an unknown error (%d)."),
|
||||
"margs"=>array($picfile["error"]));
|
||||
case UPLOAD_ERR_OK:
|
||||
}
|
||||
|
||||
// Check the file type
|
||||
$picfile["type"] = check_mime_type($picfile["tmp_name"]);
|
||||
if (!in_array($picfile["type"], $GLOBALS["PIC_VALID_TYPES"])) {
|
||||
return array("msg"=>NC_("Please upload only PNG, JPEG or GIF files."));
|
||||
}
|
||||
// OK
|
||||
return null;
|
||||
}
|
||||
|
||||
// picurl: Get the picture display URL
|
||||
function picurl(&$pic, $ratio = null)
|
||||
{
|
||||
// Default ratio to the picture ratio
|
||||
if (is_null($ratio)) {
|
||||
// Set the default picture ratio to 1
|
||||
if (!array_key_exists("ratio", $pic)) {
|
||||
$pic["ration"] = 1;
|
||||
}
|
||||
$ratio = $pic["ratio"];
|
||||
}
|
||||
$ratio = sprintf("%0.13F", $ratio);
|
||||
$ratio = preg_replace("/(\.[0-9]*?)0+$/", "$1", $ratio);
|
||||
$ratio = preg_replace("/\.$/", "", $ratio);
|
||||
$showpic = is_admin_script()? SHOWPIC_SCRIPT: SHOWPIC_PUBLIC_SCRIPT;
|
||||
// Compose the fields list
|
||||
$cols = array();
|
||||
// Add the columns
|
||||
$cols[] = "sn=" . urlencode($pic["sn"]);
|
||||
$cols[] = "ratio=" . urlencode($ratio);
|
||||
return $showpic . "?" . implode("&", $cols);
|
||||
}
|
||||
|
||||
// pictype_from_content: Get the picture type from its octet content
|
||||
// Refer to the mime.magic file
|
||||
function pictype_from_content(&$content)
|
||||
{
|
||||
// PNG
|
||||
if (substr($content, 0, 4) == "\x89PNG") {
|
||||
return "image/png";
|
||||
}
|
||||
// JPEG
|
||||
if (substr($content, 0, 2) == "\xFF\xD8") {
|
||||
return "image/jpeg";
|
||||
}
|
||||
// GIF
|
||||
if (substr($content, 0, 4) == "GIF8") {
|
||||
return "image/gif";
|
||||
}
|
||||
// No other formats are supported now
|
||||
return null;
|
||||
}
|
||||
|
||||
// picinfo: Return the picture infomation
|
||||
function picinfo(&$pic, $ratio = 1)
|
||||
{
|
||||
// Original size not recorded yet
|
||||
if ( !array_key_exists("width", $pic)
|
||||
|| !array_key_exists("height", $pic)) {
|
||||
$img = imagecreatefromstring($pic["content"]);
|
||||
$pic["width"] = imagesx($img);
|
||||
$pic["height"] = imagesy($img);
|
||||
}
|
||||
$x = newpicx($pic, $ratio);
|
||||
$y = newpicy($pic, $ratio);
|
||||
return sprintf(C_("Width: %d, height: %d, ratio: %0.2f"), $x, $y, $ratio);
|
||||
}
|
||||
|
||||
// picstyle: Return the picture style
|
||||
function picstyle(&$pic, $ratio = 1)
|
||||
{
|
||||
// Original size not recorded yet
|
||||
if ( !array_key_exists("width", $pic)
|
||||
|| !array_key_exists("height", $pic)) {
|
||||
$img = imagecreatefromstring($pic["content"]);
|
||||
$pic["width"] = imagesx($img);
|
||||
$pic["height"] = imagesy($img);
|
||||
}
|
||||
$x = newpicx($pic, $ratio);
|
||||
$y = newpicy($pic, $ratio);
|
||||
return sprintf("height: %dpx; width: %dpx;", $y, $x);
|
||||
}
|
||||
|
||||
// check_pic_ratio: Check the sanity of the picture ratio
|
||||
function check_pic_ratio(&$pic, &$ratio)
|
||||
{
|
||||
// Check if the resize ratio is valid
|
||||
if (!is_numeric($ratio)) {
|
||||
return array("msg"=>NC_("Please specify a numeric ratio."));
|
||||
}
|
||||
settype($ratio, "float");
|
||||
if ($ratio <= 0) {
|
||||
return array("msg"=>NC_("Please specify a positive ratio."));
|
||||
}
|
||||
if ($ratio > PIC_MAX_RATIO) {
|
||||
return array("msg"=>NC_("Please specify a ratio less than or equal to %0.2f."),
|
||||
"margs"=>array(PIC_MAX_RATIO));
|
||||
}
|
||||
// The resulted picture is over the limit
|
||||
if ( newpicx($pic, $ratio) > PIC_MAX_WIDTH
|
||||
|| newpicy($pic, $ratio) > PIC_MAX_HEIGHT) {
|
||||
return array("msg"=>NC_("This image is too large to display."));
|
||||
}
|
||||
// OK
|
||||
return null;
|
||||
}
|
||||
|
||||
// best_pic_ratio: Get the best ratio of a picture
|
||||
function best_pic_ratio(&$pic)
|
||||
{
|
||||
// Cache the result
|
||||
static $cache;
|
||||
// Return the cache
|
||||
if (isset($cache)) {
|
||||
return $cache;
|
||||
}
|
||||
|
||||
// Original size not recorded yet
|
||||
if ( !array_key_exists("width", $pic)
|
||||
|| !array_key_exists("height", $pic)) {
|
||||
$img = imagecreatefromstring($pic["content"]);
|
||||
$pic["width"] = imagesx($img);
|
||||
$pic["height"] = imagesy($img);
|
||||
}
|
||||
// Good
|
||||
if ( PIC_MAX_RATIO >= 1
|
||||
&& $pic["width"] <= PIC_MAX_WIDTH
|
||||
&& $pic["height"] <= PIC_MAX_HEIGHT) {
|
||||
$cache = 1;
|
||||
return $cache;
|
||||
}
|
||||
// Too large
|
||||
// Find the largest proper ratio
|
||||
$rx = floor(PIC_MAX_WIDTH*100 / $pic["width"])/100;
|
||||
$ry = floor(PIC_MAX_HEIGHT*100 / $pic["height"])/100;
|
||||
// Use the smallest among them
|
||||
$cache = min($rx, $ry, PIC_MAX_RATIO);
|
||||
return $cache;
|
||||
}
|
||||
|
||||
// newpicx: Calculate the new picture x
|
||||
function newpicx(&$pic, $ratio = 1)
|
||||
{
|
||||
// Original size not recorded yet
|
||||
if (!array_key_exists("width", $pic)) {
|
||||
$img = imagecreatefromstring($pic["content"]);
|
||||
$pic["width"] = imagesx($img);
|
||||
}
|
||||
// No calculation needed
|
||||
if ($ratio == 1) {
|
||||
return $pic["width"];
|
||||
}
|
||||
$x = round($pic["width"] * $ratio);
|
||||
// Smallest 1
|
||||
if ($x == 0) {
|
||||
$x = 1;
|
||||
}
|
||||
return $x;
|
||||
}
|
||||
|
||||
// newpicy: Calculate the new picture y
|
||||
function newpicy(&$pic, $ratio = 1)
|
||||
{
|
||||
// Original size not recorded yet
|
||||
if (!array_key_exists("height", $pic)) {
|
||||
$img = imagecreatefromstring($pic["content"]);
|
||||
$pic["height"] = imagesy($img);
|
||||
}
|
||||
// No calculation needed
|
||||
if ($ratio == 1) {
|
||||
return $pic["height"];
|
||||
}
|
||||
$y = round($pic["height"] * $ratio);
|
||||
// Smallest 1
|
||||
if ($y == 0) {
|
||||
$y = 1;
|
||||
}
|
||||
return $y;
|
||||
}
|
||||
|
||||
// pic_exists: Check if a picture exists
|
||||
function pic_exists($sn)
|
||||
{
|
||||
// Check the validity of the serial number first
|
||||
if (!check_sn($sn)) {
|
||||
return false;
|
||||
}
|
||||
if (!array_key_exists($sn, pic_deposit())) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// echopic: Output a picture
|
||||
function echopic(&$pic, $alt, $ratio = null)
|
||||
{
|
||||
if (is_null($ratio)) {
|
||||
$ratio = best_pic_ratio($pic);
|
||||
} else {
|
||||
$error = check_pic_ratio($pic, $ratio);
|
||||
if (!is_null($error)) {
|
||||
$ratio = best_pic_ratio($pic);
|
||||
}
|
||||
}
|
||||
$style = picstyle($pic, $ratio);
|
||||
$picinfo = picinfo($pic, $ratio);
|
||||
?><img src="<?php echo h(picurl($pic, $ratio)); ?>"
|
||||
style="<?php echo h($style); ?>"
|
||||
alt="<?php echo h($alt); ?>" />
|
||||
<p class="picinfo"><?php echo h($picinfo); ?></p>
|
||||
<?php
|
||||
return;
|
||||
}
|
||||
|
||||
// echopic_thumbnail: Output an picture thumbnail
|
||||
function echopic_thumbnail(&$pic, $alt)
|
||||
{
|
||||
$url = picurl($pic, $pic["ratio"]);
|
||||
$style = picstyle($pic, $pic["ratio"]);
|
||||
?><img src="<?php echo h($url); ?>"
|
||||
style="<?php echo h($style); ?>"
|
||||
alt="<?php echo h($alt); ?>" /><?php
|
||||
return;
|
||||
}
|
||||
|
||||
// picpos_label: Output the label of a picture position
|
||||
function picpos_label($pos)
|
||||
{
|
||||
global $PIC_POS_LABEL;
|
||||
return C_($PIC_POS_LABEL[$pos]);
|
||||
}
|
||||
|
||||
// resize_pic: Resize a picture
|
||||
function &resize_pic(&$pic, $ratio)
|
||||
{
|
||||
// No need to resize it
|
||||
if ($ratio == 1) {
|
||||
return $pic;
|
||||
}
|
||||
$PICS =& pic_deposit();
|
||||
|
||||
// Initialize the cache base
|
||||
if (!array_key_exists("resized", $pic)) {
|
||||
$pic["resized"] = array();
|
||||
}
|
||||
// Return the cache
|
||||
$ratio_s = number_format($ratio, 2);
|
||||
if (array_key_exists($ratio_s, $pic["resized"])) {
|
||||
return $PICS[$pic["resized"][$ratio_s]];
|
||||
}
|
||||
|
||||
// Resize the picture
|
||||
$x = $pic["width"];
|
||||
$y = $pic["height"];
|
||||
$type = $pic["type"];
|
||||
$x1 = newpicx($pic, $ratio);
|
||||
$y1 = newpicy($pic, $ratio);
|
||||
|
||||
// Resize it
|
||||
$img = imagecreatefromstring($pic["content"]);
|
||||
if (imageistruecolor($img)) {
|
||||
$img1 = imagecreatetruecolor($x1, $y1);
|
||||
} else {
|
||||
$img1 = imagecreate($x1, $y1);
|
||||
}
|
||||
imagecopyresized($img1, $img, 0, 0, 0, 0, $x1, $y1, $x, $y);
|
||||
|
||||
// Build the new picture object
|
||||
$pic1 = array();
|
||||
$pic1["width"] = $x1;
|
||||
$pic1["height"] = $y1;
|
||||
$pic1["ratio"] = 1;
|
||||
// GIF not supported, and should be replaced with PNG
|
||||
$pic1["type"] = ($type == "image/gif")? "image/png": $type;
|
||||
|
||||
// Picture content
|
||||
ob_start();
|
||||
switch ($pic1["type"]) {
|
||||
case "image/png":
|
||||
imagepng($img1);
|
||||
break;
|
||||
case "image/jpeg":
|
||||
imagejpeg($img1);
|
||||
break;
|
||||
}
|
||||
$pic1["content"] = ob_get_contents();
|
||||
ob_end_clean();
|
||||
|
||||
// Save the result
|
||||
$sn1 = suspend_pic($pic1);
|
||||
$pic["resized"][$ratio_s] = $sn1;
|
||||
|
||||
return $pic1;
|
||||
}
|
||||
|
||||
// duppic: Duplicate a picture
|
||||
function duppic($sn)
|
||||
{
|
||||
if (!pic_exists($sn)) {
|
||||
return null;
|
||||
}
|
||||
$PICS =& pic_deposit();
|
||||
// Generate a new random picture ID
|
||||
$newsn = new_sn_assoc($PICS);
|
||||
$PICS[$newsn] = $PICS[$sn];
|
||||
$PICS[$newsn]["sn"] = $newsn;
|
||||
return $newsn;
|
||||
}
|
||||
|
||||
// pic_deposit: Return the picture deposit
|
||||
function &pic_deposit()
|
||||
{
|
||||
// Session in use
|
||||
if (isset($_SESSION)) {
|
||||
if (!array_key_exists("savepics", $_SESSION)) {
|
||||
$_SESSION["savepics"] = array();
|
||||
}
|
||||
return $_SESSION["savepics"];
|
||||
|
||||
// Session not in use
|
||||
} else {
|
||||
static $PICS = array();
|
||||
return $PICS;
|
||||
}
|
||||
}
|
||||
|
||||
// clear_pic_deposit: Clear the picture deposit
|
||||
function clear_pic_deposit()
|
||||
{
|
||||
$PICS =& pic_deposit();
|
||||
$PICS = array();
|
||||
return;
|
||||
}
|
||||
|
||||
// piccache: Return an appropriate picture cache
|
||||
function &piccache($table)
|
||||
{
|
||||
$PICS =& pic_deposit();
|
||||
// Package specified
|
||||
$package = defined("PACKAGE")? PACKAGE: REQUEST_HOST;
|
||||
if (!array_key_exists("_cache", $PICS)) {
|
||||
$PICS["_cache"] = array();
|
||||
}
|
||||
if (!array_key_exists($package, $PICS["_cache"])) {
|
||||
$PICS["_cache"][$package] = array();
|
||||
}
|
||||
if (!array_key_exists($table, $PICS["_cache"][$package])) {
|
||||
$PICS["_cache"][$package][$table] = array();
|
||||
}
|
||||
return $PICS["_cache"][$package][$table];
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////
|
||||
// Picture source operation in the SQL database
|
||||
/////////////////////////
|
||||
// readpic_content: Read a picture from its content into the picture deposit
|
||||
// and return the picid
|
||||
function readpic_content($data, $args, $sn, $table)
|
||||
{
|
||||
// Check the cache
|
||||
$PICS =& pic_deposit();
|
||||
$piccache =& piccache($table);
|
||||
|
||||
// Cached
|
||||
if ( array_key_exists($sn, $piccache)
|
||||
&& $data == $PICS[$piccache[$sn]]["content"]) {
|
||||
$picid = $piccache[$sn];
|
||||
$pic =& $PICS[$picid];
|
||||
|
||||
} else {
|
||||
// Create the picture
|
||||
$pic = array();
|
||||
$pic["content"] = $data;
|
||||
$pic["type"] = pictype_from_content($data);
|
||||
|
||||
// Set its width and height value
|
||||
$img = imagecreatefromstring($pic["content"]);
|
||||
$pic["width"] = imagesx($img);
|
||||
$pic["height"] = imagesy($img);
|
||||
|
||||
// Suspend the created picture
|
||||
$picid = suspend_pic($pic);
|
||||
$piccache[$sn] = $picid;
|
||||
}
|
||||
|
||||
// Check the wanted ratio
|
||||
$ratio = 1;
|
||||
if (is_null($args)) {
|
||||
} elseif (array_key_exists("ratio", $args)) {
|
||||
$ratio = $args["ratio"];
|
||||
} elseif (array_key_exists("width", $args)) {
|
||||
$ratio = $args["width"] / $pic["width"];
|
||||
} elseif (array_key_exists("height", $args)) {
|
||||
$ratio = $args["height"] / $pic["height"];
|
||||
} elseif (array_key_exists("max", $args)) {
|
||||
$ratio = $args["max"] / max($pic["width"], $pic["height"]);
|
||||
}
|
||||
|
||||
// Check the ratio
|
||||
// No ratio previously
|
||||
if (!array_key_exists("ratio", $pic)) {
|
||||
$pic["ratio"] = $ratio;
|
||||
return $picid;
|
||||
// Same ratio -- return the same picture
|
||||
} elseif($pic["ratio"] == $ratio) {
|
||||
return $picid;
|
||||
// Ratio changed
|
||||
} else {
|
||||
$newpicid = duppic($picid);
|
||||
$PICS[$newpicid]["ratio"] = $ratio;
|
||||
$piccache[$sn] = $newpicid;
|
||||
return $newpicid;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////
|
||||
// Picture source operation on the file system.
|
||||
// To be removed.
|
||||
/////////////////////////
|
||||
// readpic_pathprefix: Read a picture from a file into the picture deposit
|
||||
// and return the picid
|
||||
function readpic_pathprefix($prefix)
|
||||
{
|
||||
// Check each suffixes
|
||||
$found = false;
|
||||
foreach ($GLOBALS["PIC_VALID_SUFS"] as $suf) {
|
||||
// Check if file exists
|
||||
$file = "$prefix.$suf";
|
||||
if ( !file_exists($file)
|
||||
|| !is_readable($file)) {
|
||||
continue;
|
||||
}
|
||||
// Check the MIME type
|
||||
$type = check_mime_type($file);
|
||||
if (!in_array($type, $GLOBALS["PIC_VALID_TYPES"])) {
|
||||
continue;
|
||||
}
|
||||
// Found
|
||||
$found = true;
|
||||
break;
|
||||
}
|
||||
// Not found
|
||||
if (!$found) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Read the picture
|
||||
$pic = array();
|
||||
$pic["content"] = xfread($file);
|
||||
$pic["type"] = $type;
|
||||
$img = imagecreatefromstring($pic["content"]);
|
||||
$pic["width"] = imagesx($img);
|
||||
$pic["height"] = imagesy($img);
|
||||
$pic["ratio"] = 1;
|
||||
$picid = suspend_pic($pic);
|
||||
|
||||
return $picid;
|
||||
}
|
||||
|
||||
?>
|
||||
Reference in New Issue
Block a user