521 lines
18 KiB
PHP
521 lines
18 KiB
PHP
<?php
|
|
/*
|
|
************************************************************************
|
|
**
|
|
** Copyright (c) 2009..2013 by
|
|
** Core|Vision B.V.
|
|
** Hambakenwetering 1
|
|
** 5231 DD 's-Hertogenbosch
|
|
** The Netherlands
|
|
**
|
|
** All Rights Reserved
|
|
**
|
|
************************************************************************
|
|
*/
|
|
/*
|
|
************************************************************************
|
|
**
|
|
** Project name: Dual Inventive: MTinfo Support Scripts
|
|
** Filename: plot-samples.php
|
|
** Author: Jack Weeland
|
|
** Date: February 12, 2009
|
|
** File version: $Revision: 1.16 $
|
|
** $Date: 2013/10/30 17:22:36 $
|
|
**
|
|
************************************************************************
|
|
*/
|
|
/*
|
|
************************************************************************
|
|
**
|
|
** Display a measurement in a graph.
|
|
**
|
|
** Mandatory parameters, via "GET", all of which are retrieved from
|
|
** the database
|
|
** zkl - database ID of the ZKL to query
|
|
** Optional input parameters
|
|
** plot - comma separated list of database IDs (in
|
|
** log_zkl/log_samples) of the data to plot;
|
|
** the data is read directly from the device
|
|
** when not specified
|
|
** Optional output options:
|
|
** w - width of the output image
|
|
** h - height of the output image
|
|
** scale - scale the Y axis (amplitude) - floating point number
|
|
** colors - comma separated list of colors (hex RGB numbers),
|
|
** for each item in 'plot'; must contains the same
|
|
** number of items as 'plot' too
|
|
** defaults to "0000E0,000060,E00000,600000"
|
|
** hide-info - don't show the info block
|
|
** show - only show those channels (comma separated list)
|
|
** 0: raw v_reference
|
|
** 1: raw v_measure
|
|
** 2: filtered v_reference
|
|
** 3: filtered v_measure
|
|
**
|
|
************************************************************************
|
|
*/
|
|
|
|
//
|
|
// Check inputs for SQL statement injection and such.
|
|
// Items not tested below are not vulnerable for SQL statement injection, e.g.
|
|
// a time is always converted using 'strtotime()' and other items are only
|
|
// used in the PHP but never in the composition of an SQL statement
|
|
// [security audit 2013-10-23]
|
|
//
|
|
if(
|
|
(isset($_GET['zkl']) && !is_numeric($_GET['zkl'])) ||
|
|
(isset($_GET['db']) && dirname($_GET['db']) != ".")
|
|
) {
|
|
// don't do anything fancy or interruptive as fiddling with the GET parameters
|
|
// is intended by the author
|
|
die("Parameter error");
|
|
}
|
|
|
|
require_once("../include/graphics.php");
|
|
require_once("../include/i18n.php");
|
|
require_once("../include/cp3000-tcpclient.php");
|
|
require_once("../include/utilities.php");
|
|
require_once("support.inc.php");
|
|
|
|
// read the database information
|
|
if( isset($_GET['db']) ) $db_info = read_database(DBCONFIG_DIR, $_GET['db']);
|
|
else $db_info = array();
|
|
if( !isset($db_info['host']) ) $db_info['host'] = "localhost";
|
|
if( !isset($db_info['user']) ) $db_info['user'] = "root";
|
|
if( !isset($db_info['passwd']) ) $db_info['passwd'] = "";
|
|
if( !isset($db_info['db']) ) $db_info['db'] = "di_zkl";
|
|
|
|
// open the database
|
|
$db_data_handle = mysql_connect($db_info['host'], $db_info['user'], $db_info['passwd']);
|
|
if( $db_data_handle === FALSE ) {
|
|
echo mysql_error();
|
|
exit(1);
|
|
}
|
|
mysql_select_db($db_info['database'], $db_data_handle);
|
|
if( $db_info['main'] ) {
|
|
$db_main_info = read_database(DBCONFIG_DIR, $db_info['main']);
|
|
$db_main_handle = mysql_connect($db_main_info['host'], $db_main_info['user'], $db_main_info['passwd'], true);
|
|
if( $db_main_handle === FALSE ) {
|
|
echo mysql_error();
|
|
exit(1);
|
|
}
|
|
mysql_select_db($db_main_info['database'], $db_main_handle);
|
|
}
|
|
else {
|
|
$db_main_handle = $db_data_handle;
|
|
$db_main_info = $db_info;
|
|
}
|
|
|
|
// determine width and height
|
|
$width = $_GET['w'];
|
|
$height = $_GET['h'];
|
|
if( !$width ) $width = 640;
|
|
if( !$height ) $height = 480;
|
|
|
|
if( !($scale = $_GET['scale']) ) $scale = 1.0;
|
|
|
|
// get information about the device
|
|
$query = "SELECT zkl.serienr,zkl.idcode,zkl.mcu_versie,zkl.wcpu_versie,IFNULL(zkl.gebruiker,zkl.eigenaar) AS gebruiker,server.adres AS tcp_server,server.adres_ssl AS stcp_server ";
|
|
$query .= "FROM zkl,server ";
|
|
$query .= "WHERE ";
|
|
$query .= " zkl.id=" . $_GET['zkl'] . " AND ";
|
|
$query .= " server.id=zkl.tcp_server";
|
|
$result = mysql_run($query, $db_main_handle);
|
|
$zkl_info = mysql_fetch_assoc($result);
|
|
if( $zkl_info['gebruiker'] ) {
|
|
$query = "SELECT tz,i18n FROM klant WHERE id=" . $zkl_info['gebruiker'];
|
|
$result = mysql_run($query, $db_main_handle);
|
|
$tz_info = mysql_fetch_assoc($result);
|
|
}
|
|
else {
|
|
$tz_info = array( 'tz' => date("e"), 'i18n' => "nl" );
|
|
}
|
|
if( $_GET['tz'] ) $tz_info['tz'] = $_GET['tz'];
|
|
if( $_GET['lc'] ) $tz_info['i18n'] = $_GET['lc'];
|
|
$zkl_info['tz'] = $tz_info['tz'];
|
|
$zkl_info['i18n'] = $tz_info['i18n'];
|
|
$zkl_info['firmware']['mcu'] = zkl_get_fw_version($zkl_info['mcu_versie']);
|
|
$zkl_info['firmware']['wcpu'] = zkl_get_fw_version($zkl_info['wcpu_versie']);
|
|
|
|
putenv("TZ=" . $zkl_info['tz']);
|
|
if( isset($_GET['lc']) ) {
|
|
i18n_settext_language($_GET['lc']);
|
|
setlocale(LC_ALL, $_GET['lc']);
|
|
}
|
|
else {
|
|
i18n_settext_language('nl');
|
|
setlocale(LC_ALL, "nl");
|
|
}
|
|
|
|
//
|
|
// Draw the graph
|
|
//
|
|
|
|
header("Content-type: image/png");
|
|
if( isset($_GET['plot']) ) {
|
|
// database data: can be cached
|
|
header('Cache-Control: public');
|
|
header('Expires: ');
|
|
}
|
|
else {
|
|
// live data: do not cache
|
|
header('Pragma: no-cache');
|
|
header('Expires: ' . date("r", strtotime("+1 year")));
|
|
}
|
|
|
|
// error message
|
|
global $error_str;
|
|
$error_str = NULL;
|
|
|
|
// create the image
|
|
$im = imagecreatetruecolor($width,$height);
|
|
if( function_exists("imageantialias") )
|
|
imageantialias($im, true);
|
|
$black = imagecolorallocate($im, 0, 0, 0);
|
|
$white = imagecolorallocate($im, 255, 255, 255);
|
|
$grey = imagecolorallocate($im, 192, 192, 192);
|
|
$lgrey = imagecolorallocate($im, 240, 240, 240);
|
|
$green = imagecolorallocate($im, 0, 192, 0);
|
|
$red = imagecolorallocate($im, 255, 0, 0);
|
|
$dred = imagecolorallocate($im, 160, 0, 0);
|
|
$blue = imagecolorallocate($im, 0, 0, 192);
|
|
$font = 2; // 6x13
|
|
$bfont = 3; // 7x13 medium bold
|
|
$tfont = 1; // 5x8
|
|
|
|
// colors and font to use
|
|
$bgcolor = imagecolorallocatealpha($im, 255, 255, 255, $_GET['transparent'] ? 127 : 0);
|
|
$bgcolor_transp = imagecolorallocatealpha($im, 255, 255, 255, 96);
|
|
$gridcolor = $black;
|
|
if( $width <= 320 || $height <= 240 )
|
|
$labelfont = 1;
|
|
else
|
|
$labelfont = 2;
|
|
if( isset($_GET['colors']) ) {
|
|
$colors = explode(',', $_GET['colors']);
|
|
for( $i = 0; $i < count($colors); $i++ )
|
|
$linecolor[$i] = imagecolorallocate($im,
|
|
intval(substr($colors[$i], 0, 2), 16),
|
|
intval(substr($colors[$i], 2, 2), 16),
|
|
intval(substr($colors[$i], 4, 2), 16)
|
|
);
|
|
}
|
|
else {
|
|
$linecolor = array(
|
|
imagecolorallocate($im, 0, 0, 224),
|
|
imagecolorallocate($im, 224, 0, 0),
|
|
imagecolorallocate($im, 0, 0, 96),
|
|
imagecolorallocate($im, 96, 0, 0)
|
|
);
|
|
}
|
|
|
|
// white background
|
|
imagefill($im, 0, 0, $white);
|
|
|
|
// plot data
|
|
if( isset($_GET['plot']) ) {
|
|
$plot = explode(',', $_GET['plot']);
|
|
|
|
$samples = array();
|
|
$samples['count'] = 0;
|
|
foreach( $plot as $id_to_plot ) {
|
|
$query = "SELECT * FROM log_samples WHERE id=" . $id_to_plot;
|
|
$result = mysql_run($query, $db_data_handle);
|
|
if( $result ) {
|
|
$row = mysql_fetch_assoc($result);
|
|
|
|
if( $row['count'] > $samples['count'] ) $samples['count'] = $row['count'];
|
|
|
|
// collect the samples
|
|
$sample_array = array();
|
|
$buffer_ptr = 0;
|
|
for( $sample = 0; $sample < $row['count']; $sample++ ) {
|
|
$val =
|
|
intval(substr($row['samples'], $buffer_ptr , 2), 16) +
|
|
(intval(substr($row['samples'], $buffer_ptr + 2, 2), 16) << 8);
|
|
$buffer_ptr += 4;
|
|
if( $val & 0x8000 ) {
|
|
// 2's complement negative number
|
|
$val -= 0x10000;
|
|
}
|
|
array_push($sample_array, $val);
|
|
}
|
|
array_push($samples, $sample_array);
|
|
}
|
|
else array_push($samples, array());
|
|
}
|
|
|
|
// timestamps should be the same
|
|
$query = "SELECT t,sdcard,rpgmcount,startup FROM log_zkl WHERE id=" . $plot[0];
|
|
$result = mysql_run($query, $db_data_handle);
|
|
$log_info = mysql_fetch_assoc($result);
|
|
$time = $log_info['t'];
|
|
|
|
// get environmental information, if requested
|
|
if( !$_GET['hide-info']) {
|
|
$status = array();
|
|
|
|
// get last temperature logged before the samples
|
|
$query = "SELECT temp FROM log_temp WHERE id=";
|
|
$query .= "(";
|
|
$query .= "SELECT MAX(id) FROM log_zkl WHERE ";
|
|
$query .= "zkl=" . $_GET['zkl'] . " AND ";
|
|
$query .= "id < " . $plot[0] . " AND ";
|
|
$query .= "sdcard=" . $log_info['sdcard'] . " AND ";
|
|
$query .= "rpgmcount=" . $log_info['rpgmcount'] . " AND ";
|
|
$query .= "startup=" . $log_info['startup'] . " AND ";
|
|
$query .= "major=0xD AND minor=0x40";
|
|
$query .= ")";
|
|
$result = mysql_run($query, $db_data_handle);
|
|
$row = mysql_fetch_array($result);
|
|
$status['temp']['on-board'] = $row[0];
|
|
|
|
// re-calculate b/a
|
|
$query = "SELECT v_reference,v_measure ";
|
|
$query .= "FROM log_meting_detail ";
|
|
$query .= "WHERE id =";
|
|
$query .= "(";
|
|
$query .= "SELECT MIN(id) FROM log_zkl WHERE ";
|
|
$query .= "zkl=" . $_GET['zkl'] . " AND ";
|
|
$query .= "id BETWEEN " . $plot[0] . " AND " . $plot[count($plot) - 1] . " AND ";
|
|
$query .= "sdcard=" . $log_info['sdcard'] . " AND ";
|
|
$query .= "rpgmcount=" . $log_info['rpgmcount'] . " AND ";
|
|
$query .= "startup=" . $log_info['startup'] . " AND ";
|
|
$query .= "major=0x5 AND minor=0x12";
|
|
$query .= ")";
|
|
$result = mysql_run($query, $db_data_handle);
|
|
if( $result ) {
|
|
// calculate b/a
|
|
$row = mysql_fetch_assoc($result);
|
|
$status['detection']['b/a'] = $row['v_measure'] / $row['v_reference'];
|
|
|
|
// get rms
|
|
$query = "SELECT v_reference,v_measure ";
|
|
$query .= "FROM log_meting_detail ";
|
|
$query .= "WHERE id =";
|
|
$query .= "(";
|
|
$query .= "SELECT MIN(id) FROM log_zkl WHERE ";
|
|
$query .= "zkl=" . $_GET['zkl'] . " AND ";
|
|
$query .= "id BETWEEN " . $plot[0] . " AND " . $plot[count($plot) - 1] . " AND ";
|
|
$query .= "sdcard=" . $log_info['sdcard'] . " AND ";
|
|
$query .= "rpgmcount=" . $log_info['rpgmcount'] . " AND ";
|
|
$query .= "startup=" . $log_info['startup'] . " AND ";
|
|
$query .= "major=0x5 AND minor=0x16";
|
|
$query .= ")";
|
|
$result = mysql_run($query, $db_data_handle);
|
|
$row = mysql_fetch_assoc($result);
|
|
$status['detection']['rms'] = $row['v_reference'];
|
|
}
|
|
else {
|
|
// for new firmware, this will find the average b/a and not the last b/a, so
|
|
// it is only used as a fall-back
|
|
$query = "SELECT rms,b_a FROM log_meting WHERE id=";
|
|
$query .= "(";
|
|
$query .= "SELECT MIN(id) FROM log_zkl WHERE ";
|
|
$query .= "zkl=" . $_GET['zkl'] . " AND ";
|
|
$query .= "id > " . $plot[count($plot) - 1] . " AND ";
|
|
$query .= "sdcard=" . $log_info['sdcard'] . " AND ";
|
|
$query .= "rpgmcount=" . $log_info['rpgmcount'] . " AND ";
|
|
$query .= "startup=" . $log_info['startup'] . " AND ";
|
|
$query .= "major=0x5 AND (minor=0x10 OR minor=0x90)";
|
|
$query .= ")";
|
|
$result = mysql_run($query, $db_data_handle);
|
|
if( $result ) {
|
|
$row = mysql_fetch_assoc($result);
|
|
$status['detection']['rms'] = $row['rms'];
|
|
$status['detection']['b/a'] = $row['b_a'];
|
|
}
|
|
}
|
|
|
|
// get last PWM frequency logged before the samples
|
|
$query = "SELECT freq,b_a FROM log_calibratie WHERE id=";
|
|
$query .= "(";
|
|
$query .= "SELECT MAX(id) FROM log_zkl WHERE ";
|
|
$query .= "zkl=" . $_GET['zkl'] . " AND ";
|
|
$query .= "id < " . $plot[0] . " AND ";
|
|
$query .= "sdcard=" . $log_info['sdcard'] . " AND ";
|
|
$query .= "rpgmcount=" . $log_info['rpgmcount'] . " AND ";
|
|
$query .= "startup=" . $log_info['startup'] . " AND ";
|
|
$query .= "major=0x5 AND (minor=0x18 OR minor=0x24)";
|
|
$query .= ")";
|
|
$result = mysql_run($query, $db_data_handle);
|
|
if( $result ) {
|
|
$row = mysql_fetch_array($result);
|
|
$status['detection']['freq'] = $row[0];
|
|
$status['detection']['quality'] = zkl_measurement_quality($status['detection']['b/a'], $row['b_a']);
|
|
}
|
|
}
|
|
|
|
// time of one sampling+conversion sequence (this is a fixed value in ns)
|
|
$samples['t_seq'] = 9769.2;
|
|
}
|
|
else {
|
|
// login with the TCP-server
|
|
if( FALSE ) {//isset($zkl_info['stcp_server']) ) {
|
|
$server = $zkl_info['stcp_server'];
|
|
zkl_set_private_key(
|
|
"cert/private/mtinfo.key",
|
|
"cert/private/passphrase"
|
|
);
|
|
zkl_set_public_key(
|
|
"cert/public/mtinfo.crt",
|
|
"cert/public/di-ca.crt"
|
|
);
|
|
}
|
|
else $server = $zkl_info['tcp_server'];
|
|
|
|
if(
|
|
($tcp_channel = zkl_tcplogin($_GET['zkl'], $server)) === FALSE
|
|
) {
|
|
global $error_str;
|
|
if( !$_GET['zkl'] || !$server )
|
|
$error_str = "Invalid parameters";
|
|
else
|
|
$error_str = sprintf("%02X: %s", $zkl_status, $zkl_error);
|
|
error_log("plot-samples: log-in with " . $server . " failed: " . $error_str);
|
|
imagestringalign($im, $font, $width / 2, $height / 2, $error_str, $dred, AL_CENTERED);
|
|
imagepng($im);
|
|
imagedestroy($im);
|
|
exit(1);
|
|
}
|
|
|
|
// get the measurement samples
|
|
$samples = zkl_get_measurement($tcp_channel, 10.0);
|
|
if( $samples === FALSE ) {
|
|
global $error_str;
|
|
if( !$_GET['zkl'] || !$server )
|
|
$error_str = "Invalid parameters";
|
|
else
|
|
$error_str = sprintf(_("Error code") . " %02X: %s", $zkl_status, $zkl_error);
|
|
error_log("plot-samples: read from " . $server . " failed: " . $error_str);
|
|
}
|
|
$time = time();
|
|
$samples[0] = $samples['v_ref']['raw'];
|
|
$samples[1] = $samples['v_meas']['raw'];
|
|
$samples[2] = $samples['v_ref']['filtered'];
|
|
$samples[3] = $samples['v_meas']['filtered'];
|
|
|
|
// extra info wanted?
|
|
if( !$_GET['hide-info'] ) {
|
|
$status = zkl_get_status($tcp_channel, 3.0);
|
|
}
|
|
|
|
// close connection to TCP server
|
|
zkl_tcplogout($tcp_channel);
|
|
}
|
|
if( isset($_GET['show']) ) $channels = explode(",", $_GET['show']);
|
|
|
|
// sanity check
|
|
if( $error_str ) {
|
|
imagestringalign($im, $labelfont, $width >> 1, 0, sprintf("%s - %s - %s", $zkl_info['idcode'], strftime("%c %z", $time), $error_str), $gridcolor, ALV_TOP | ALH_CENTER);
|
|
|
|
// output the final image
|
|
imagepng($im);
|
|
imagedestroy($im);
|
|
|
|
exit(1);
|
|
}
|
|
else if( $samples['count'] == 0 ) {
|
|
error_log("plot-samples: no data in plot=" . $_GET['plot']);
|
|
|
|
imagestringalign($im, $labelfont, $width >> 1, 0, sprintf("%s - %s - %s", $zkl_info['idcode'], strftime("%c %z", $time), _("Geen samples")), $gridcolor, ALV_TOP | ALH_CENTER);
|
|
|
|
// output the final image
|
|
imagepng($im);
|
|
imagedestroy($im);
|
|
|
|
exit(1);
|
|
}
|
|
|
|
// offsets with the drawing grid
|
|
// largest string: -1.00
|
|
$x_off = 5 * imagefontwidth($labelfont) + 2;
|
|
$x_ext = $width - $x_off - 3 * imagefontwidth($labelfont); // " ms"
|
|
$y_off = ($height - imagefontheight($labelfont)) >> 1;
|
|
$y_ext = (($height >> 1) - imagefontheight($labelfont)) * $scale;
|
|
|
|
//
|
|
// The grid is drawn _under_ the lines and ornaments like the title etc
|
|
//
|
|
// X tick marks
|
|
if( $samples['t_seq'] ) {
|
|
$duration = ($samples['count'] * $samples['t_seq']) / 1000.0;
|
|
$x_tick_val = 0;
|
|
$x_tick_off = 250;
|
|
$x_tick_step = ($x_ext * $x_tick_off) / $duration;
|
|
if( $x_tick_step > 0 ) for( $x = 0; $x <= $x_ext; $x += $x_tick_step) {
|
|
imageline($im, $x_off + $x, $y_off - $y_ext, $x_off + $x, $y_off + $y_ext + 1, $lgrey);
|
|
imageline($im, $x_off + $x, $y_off + 2, $x_off + $x, $y_off, $black);
|
|
imagestringupalign($im, $labelfont, $x_off + $x, $y_off + 2, sprintf("%.3f", (float)$x_tick_val / 1000.0), $gridcolor, ALV_TOP | ALH_CENTER);
|
|
$x_tick_val += $x_tick_off;
|
|
}
|
|
else imagestringalign($im, $labelfont, $x_off, $y_off + 2, sprintf("step: %.6f", $x_tick_step, $duration), $gridcolor, ALV_TOP | ALH_LEFT);
|
|
imagestringalign($im, $labelfont, $width, $y_off + 2, "ms", $gridcolor, ALV_TOP | ALH_RIGHT);
|
|
}
|
|
// Y tick marks every 25%; label "amp" between 0.0 and 0.25
|
|
for( $y = -$y_ext; $y <= $y_ext; $y += ($y_ext / 4) ) {
|
|
imageline($im, $x_off - 2, $y_off + $y, $x_off, $y_off + $y, $gridcolor);
|
|
imagestringalign($im, $labelfont, $x_off - 2, $y_off + $y, sprintf("%.2f", -$y / $y_ext), $gridcolor, ALV_MIDDLE | ALH_RIGHT);
|
|
}
|
|
// draw legend
|
|
imageline($im, $x_off, $y_off - $y_ext, $x_off, $y_off + $y_ext + 1, $gridcolor);
|
|
imageline($im, $x_off, $y_off, $x_off + $x_ext, $y_off, $gridcolor);
|
|
|
|
//
|
|
// Draw the graph
|
|
//
|
|
$count = 0;
|
|
for( $i = 0; $i < count($samples); $i++ )
|
|
if( count($samples[$i]) > $count )
|
|
$count = count($samples[$i]);
|
|
for( $i = 0; $i < count($samples); $i++ )
|
|
if( !isset($channels) || in_array($i, $channels) )
|
|
draw_samples($im, $x_off, $y_off, $x_ext, $y_ext, 0.0, $count, $samples[$i], $linecolor[$i]);
|
|
|
|
//
|
|
// Ornaments (labels, title, etc) are drawn _over_ the graph
|
|
//
|
|
// show extra info
|
|
if( !$_GET['hide-info'] ) {
|
|
$y = 0;
|
|
imagestringborderalign($im, $labelfont, $width, $y, sprintf("T = %3u\xB0C", $status['temp']['on-board']['C']), $gridcolor, $bgcolor_transp, ALV_TOP | ALH_RIGHT);
|
|
$y += imagefontheight($labelfont);
|
|
imagestringborderalign($im, $labelfont, $width, $y, sprintf("Q = %4u%%", $status['detection']['quality']), $gridcolor, $bgcolor_transp, ALV_TOP | ALH_RIGHT);
|
|
$y += imagefontheight($labelfont) + 4;
|
|
imagestringborderalign($im, $labelfont, $width, $y, sprintf("rms = %5u", $status['detection']['rms']), $gridcolor, $bgcolor_transp, ALV_TOP | ALH_RIGHT);
|
|
$y += imagefontheight($labelfont);
|
|
imagestringborderalign($im, $labelfont, $width, $y, sprintf("b/a = %.3f", $status['detection']['b/a']), $gridcolor, $bgcolor_transp, ALV_TOP | ALH_RIGHT);
|
|
$y += imagefontheight($labelfont);
|
|
imagestringborderalign($im, $labelfont, $width, $y, sprintf("f = %4u Hz", $status['detection']['freq']), $gridcolor, $bgcolor_transp, ALV_TOP | ALH_RIGHT);
|
|
}
|
|
|
|
// finally the title, on top of everything else
|
|
imagestringborderalign($im, $labelfont, $width >> 1, 0, sprintf("%s - %s", $zkl_info['idcode'], strftime("%c", $time)), $gridcolor, $bgcolor_transp, ALV_TOP | ALH_CENTER);
|
|
|
|
// output the final image
|
|
imagepng($im);
|
|
imagedestroy($im);
|
|
|
|
//
|
|
// Draw the samples
|
|
//
|
|
function draw_samples($im, $x_off, $y_off, $x_ext, $y_ext, $x_shift, $n, $samples, $color)
|
|
{
|
|
if( $n == 0 ) return FALSE;
|
|
|
|
$x_step = $x_ext / $n;
|
|
$x = $x_prev = $x_off + $x_shift * $x_step;
|
|
$y = $y_prev = $y_off + ($samples[0] / 32768.0) * $y_ext;
|
|
for( $i = 1; $i < $n; $i++ ) {
|
|
$x += $x_step;
|
|
$y = $y_off + ($samples[$i] / 32768.0) * $y_ext;
|
|
|
|
imageline($im, $x_prev, $y_prev, $x, $y, $color);
|
|
|
|
$x_prev = $x;
|
|
$y_prev = $y;
|
|
}
|
|
}
|
|
|
|
?>
|