Merge branch 'master' of github.com:/ZoneMinder/zoneminder

pull/2993/head
Isaac Connor 2020-07-23 12:05:32 -04:00
commit 7aa46df50f
11 changed files with 376 additions and 227 deletions

View File

@ -4,13 +4,13 @@
"Jan Hochstein"
],
"dynamic_config" : 0,
"generated_by" : "ExtUtils::MakeMaker version 7.34, CPAN::Meta::Converter version 2.150010",
"generated_by" : "ExtUtils::MakeMaker version 7.24, CPAN::Meta::Converter version 2.150010",
"license" : [
"unknown"
],
"meta-spec" : {
"url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec",
"version" : 2
"version" : "2"
},
"name" : "ONVIF",
"no_index" : {
@ -36,5 +36,5 @@
},
"release_status" : "stable",
"version" : "",
"x_serialization_backend" : "JSON::PP version 4.02"
"x_serialization_backend" : "JSON::PP version 2.27400_02"
}

View File

@ -7,7 +7,7 @@ build_requires:
configure_requires:
ExtUtils::MakeMaker: '0'
dynamic_config: 0
generated_by: 'ExtUtils::MakeMaker version 7.34, CPAN::Meta::Converter version 2.150010'
generated_by: 'ExtUtils::MakeMaker version 7.24, CPAN::Meta::Converter version 2.150010'
license: unknown
meta-spec:
url: http://module-build.sourceforge.net/META-spec-v1.4.html

View File

@ -4,13 +4,13 @@
"Jan Hochstein"
],
"dynamic_config" : 0,
"generated_by" : "ExtUtils::MakeMaker version 7.34, CPAN::Meta::Converter version 2.150010",
"generated_by" : "ExtUtils::MakeMaker version 7.24, CPAN::Meta::Converter version 2.150010",
"license" : [
"unknown"
],
"meta-spec" : {
"url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec",
"version" : 2
"version" : "2"
},
"name" : "ONVIF",
"no_index" : {
@ -36,5 +36,5 @@
},
"release_status" : "stable",
"version" : "",
"x_serialization_backend" : "JSON::PP version 4.02"
"x_serialization_backend" : "JSON::PP version 2.27400_02"
}

View File

@ -7,7 +7,7 @@ build_requires:
configure_requires:
ExtUtils::MakeMaker: '0'
dynamic_config: 0
generated_by: 'ExtUtils::MakeMaker version 7.34, CPAN::Meta::Converter version 2.150010'
generated_by: 'ExtUtils::MakeMaker version 7.24, CPAN::Meta::Converter version 2.150010'
license: unknown
meta-spec:
url: http://module-build.sourceforge.net/META-spec-v1.4.html

View File

@ -607,7 +607,7 @@ void Event::AddFrame(Image *image, struct timeval timestamp, int score, Image *a
if ( monitor->GetOptSaveJPEGs() & 1 ) {
std::string event_file = stringtf(staticConfig.capture_file_format, path.c_str(), frames);
Debug(1, "Writing capture frame %d to %s using %s %d %s", frames, event_file.c_str());
Debug(1, "Writing capture frame %d to %s", frames, event_file.c_str());
if ( !WriteFrameImage(image, timestamp, event_file.c_str()) ) {
Error("Failed to write frame image");
}

View File

@ -122,7 +122,7 @@ Image::Image() {
blend = fptr_blend;
}
Image::Image( const char *filename ) {
Image::Image(const char *filename) {
if ( !initialised )
Initialise();
width = 0;
@ -141,7 +141,7 @@ Image::Image( const char *filename ) {
update_function_pointers();
}
Image::Image( int p_width, int p_height, int p_colours, int p_subpixelorder, uint8_t *p_buffer, unsigned int p_padding) {
Image::Image(int p_width, int p_height, int p_colours, int p_subpixelorder, uint8_t *p_buffer, unsigned int p_padding) {
if ( !initialised )
Initialise();
width = p_width;
@ -166,7 +166,7 @@ Image::Image( int p_width, int p_height, int p_colours, int p_subpixelorder, uin
update_function_pointers();
}
Image::Image( int p_width, int p_linesize, int p_height, int p_colours, int p_subpixelorder, uint8_t *p_buffer, unsigned int p_padding) {
Image::Image(int p_width, int p_linesize, int p_height, int p_colours, int p_subpixelorder, uint8_t *p_buffer, unsigned int p_padding) {
if ( !initialised )
Initialise();
width = p_width;
@ -337,7 +337,7 @@ void Image::Initialise() {
(*fptr_blend)(blend1,blend2,blendres,128,12.0);
/* Compare results with expected results */
for ( int i=0; i < 128; i ++ ) {
for ( int i=0; i < 128; i++ ) {
if ( abs(blendexp[i] - blendres[i]) > 3 ) {
Panic("Blend function failed self-test: Results differ from the expected results. Column %u Expected %u Got %u",i,blendexp[i],blendres[i]);
}
@ -437,7 +437,7 @@ void Image::Initialise() {
}
/* Run the delta8 RGBA function */
(*fptr_delta8_rgba)(delta8_1,delta8_2,delta8_rgba_res,32);
(*fptr_delta8_rgba)(delta8_1,delta8_2,delta8_rgba_res, 32);
/* Compare results with expected results */
for ( int i=0; i < 32; i++ ) {
@ -483,9 +483,17 @@ void Image::Initialise() {
}
/* Requests a writeable buffer to the image. This is safer than buffer() because this way we can guarantee that a buffer of required size exists */
uint8_t* Image::WriteBuffer(const unsigned int p_width, const unsigned int p_height, const unsigned int p_colours, const unsigned int p_subpixelorder) {
uint8_t* Image::WriteBuffer(
const unsigned int p_width,
const unsigned int p_height,
const unsigned int p_colours,
const unsigned int p_subpixelorder) {
if ( p_colours != ZM_COLOUR_GRAY8 && p_colours != ZM_COLOUR_RGB24 && p_colours != ZM_COLOUR_RGB32 ) {
if ( p_colours != ZM_COLOUR_GRAY8
&&
p_colours != ZM_COLOUR_RGB24
&&
p_colours != ZM_COLOUR_RGB32 ) {
Error("WriteBuffer called with unexpected colours: %d", p_colours);
return NULL;
}
@ -597,7 +605,13 @@ void Image::AssignDirect(
}
}
void Image::Assign(const unsigned int p_width, const unsigned int p_height, const unsigned int p_colours, const unsigned int p_subpixelorder, const uint8_t* new_buffer, const size_t buffer_size) {
void Image::Assign(
const unsigned int p_width,
const unsigned int p_height,
const unsigned int p_colours,
const unsigned int p_subpixelorder,
const uint8_t* new_buffer,
const size_t buffer_size) {
unsigned int new_size = (p_width * p_height) * p_colours;
if ( new_buffer == NULL ) {
@ -644,24 +658,30 @@ void Image::Assign(const unsigned int p_width, const unsigned int p_height, cons
if ( new_buffer != buffer )
(*fptr_imgbufcpy)(buffer, new_buffer, size);
Debug(1,"Assign");
}
void Image::Assign( const Image &image ) {
unsigned int new_size = (image.width * image.height) * image.colours;
void Image::Assign(const Image &image) {
unsigned int new_size = image.height * image.linesize;
if ( image.buffer == NULL ) {
Error("Attempt to assign image with an empty buffer");
return;
}
if ( image.colours != ZM_COLOUR_GRAY8 && image.colours != ZM_COLOUR_RGB24 && image.colours != ZM_COLOUR_RGB32 ) {
Error("Attempt to assign image with unexpected colours per pixel: %d",image.colours);
if ( image.colours != ZM_COLOUR_GRAY8
&&
image.colours != ZM_COLOUR_RGB24
&&
image.colours != ZM_COLOUR_RGB32 ) {
Error("Attempt to assign image with unexpected colours per pixel: %d", image.colours);
return;
}
if ( !buffer || image.width != width || image.height != height
|| image.colours != colours || image.subpixelorder != subpixelorder) {
if ( !buffer
|| image.width != width || image.height != height
|| image.colours != colours || image.subpixelorder != subpixelorder
|| image.linesize != linesize
) {
if ( holdbuffer && buffer ) {
if ( new_size > allocation ) {
@ -681,13 +701,19 @@ void Image::Assign( const Image &image ) {
colours = image.colours;
subpixelorder = image.subpixelorder;
size = new_size;
linesize = image.linesize;
}
if ( image.buffer != buffer )
(*fptr_imgbufcpy)(buffer, image.buffer, size);
}
Image *Image::HighlightEdges( Rgb colour, unsigned int p_colours, unsigned int p_subpixelorder, const Box *limits ) {
Image *Image::HighlightEdges(
Rgb colour,
unsigned int p_colours,
unsigned int p_subpixelorder,
const Box *limits
) {
if ( colours != ZM_COLOUR_GRAY8 ) {
Panic("Attempt to highlight image edges when colours = %d", colours);
}
@ -696,7 +722,7 @@ Image *Image::HighlightEdges( Rgb colour, unsigned int p_colours, unsigned int p
colour = rgb_convert(colour, p_subpixelorder);
/* Create a new image of the target format */
Image *high_image = new Image( width, height, p_colours, p_subpixelorder );
Image *high_image = new Image(width, height, p_colours, p_subpixelorder);
uint8_t* high_buff = high_image->WriteBuffer(width, height, p_colours, p_subpixelorder);
/* Set image to all black */
@ -714,10 +740,13 @@ Image *Image::HighlightEdges( Rgb colour, unsigned int p_colours, unsigned int p
for ( unsigned int x = lo_x; x <= hi_x; x++, p++, phigh++ ) {
bool edge = false;
if ( *p ) {
edge = (x > 0 && !*(p-1)) || (x < (width-1) && !*(p+1)) || (y > 0 && !*(p-width)) || (y < (height-1) && !*(p+width));
#if 0
if ( !edge && x > 0 && !*(p-1) ) edge = true;
if ( !edge && x < (width-1) && !*(p+1) ) edge = true;
if ( !edge && y > 0 && !*(p-width) ) edge = true;
if ( !edge && y < (height-1) && !*(p+width) ) edge = true;
#endif
}
if ( edge ) {
*phigh = colour;
@ -731,10 +760,13 @@ Image *Image::HighlightEdges( Rgb colour, unsigned int p_colours, unsigned int p
for ( unsigned int x = lo_x; x <= hi_x; x++, p++, phigh += 3 ) {
bool edge = false;
if ( *p ) {
edge = (x > 0 && !*(p-1)) || (x < (width-1) && !*(p+1)) || (y > 0 && !*(p-width)) || (y < (height-1) && !*(p+width));
#if 0
if ( !edge && x > 0 && !*(p-1) ) edge = true;
if ( !edge && x < (width-1) && !*(p+1) ) edge = true;
if ( !edge && y > 0 && !*(p-width) ) edge = true;
if ( !edge && y < (height-1) && !*(p+width) ) edge = true;
#endif
}
if ( edge ) {
RED_PTR_RGBA(phigh) = RED_VAL_RGBA(colour);
@ -750,10 +782,13 @@ Image *Image::HighlightEdges( Rgb colour, unsigned int p_colours, unsigned int p
for ( unsigned int x = lo_x; x <= hi_x; x++, p++, phigh++ ) {
bool edge = false;
if ( *p ) {
edge = (x > 0 && !*(p-1)) || (x < (width-1) && !*(p+1)) || (y > 0 && !*(p-width)) || (y < (height-1) && !*(p+width));
#if 0
if ( !edge && x > 0 && !*(p-1) ) edge = true;
if ( !edge && x < (width-1) && !*(p+1) ) edge = true;
if ( !edge && y > 0 && !*(p-width) ) edge = true;
if ( !edge && y < (height-1) && !*(p+width) ) edge = true;
#endif
}
if ( edge ) {
*phigh = colour;
@ -765,9 +800,9 @@ Image *Image::HighlightEdges( Rgb colour, unsigned int p_colours, unsigned int p
return high_image;
}
bool Image::ReadRaw( const char *filename ) {
bool Image::ReadRaw(const char *filename) {
FILE *infile;
if ( (infile = fopen( filename, "rb" )) == NULL ) {
if ( (infile = fopen(filename, "rb")) == NULL ) {
Error("Can't open %s: %s", filename, strerror(errno));
return false;
}
@ -1748,7 +1783,7 @@ Image *Image::Highlight( unsigned int n_images, Image *images[], const Rgb thres
return result;
}
/* New function to allow buffer re-using instead of allocationg memory for the delta image every time */
/* New function to allow buffer re-using instead of allocating memory for the delta image every time */
void Image::Delta( const Image &image, Image* targetimage) const {
#ifdef ZM_IMAGE_PROFILING
struct timespec start,end,diff;
@ -3458,7 +3493,7 @@ __attribute__((noinline)) void fast_delta8_bgr(const uint8_t* col1, const uint8_
int r,g,b;
const uint8_t* const max_ptr = result + count;
while(result < max_ptr) {
while (result < max_ptr) {
b = abs(col1[0] - col2[0]);
g = abs(col1[1] - col2[1]);
r = abs(col1[2] - col2[2]);
@ -3487,7 +3522,7 @@ __attribute__((noinline)) void std_delta8_bgr(const uint8_t* col1, const uint8_t
int r,g,b;
const uint8_t* const max_ptr = result + count;
while(result < max_ptr) {
while (result < max_ptr) {
b = abs(col1[0] - col2[0]);
g = abs(col1[1] - col2[1]);
r = abs(col1[2] - col2[2]);
@ -3505,7 +3540,7 @@ __attribute__((noinline)) void fast_delta8_rgba(const uint8_t* col1, const uint8
int r,g,b;
const uint8_t* const max_ptr = result + count;
while(result < max_ptr) {
while (result < max_ptr) {
r = abs(col1[0] - col2[0]);
g = abs(col1[1] - col2[1]);
b = abs(col1[2] - col2[2]);
@ -3534,7 +3569,7 @@ __attribute__((noinline)) void std_delta8_rgba(const uint8_t* col1, const uint8_
int r,g,b;
const uint8_t* const max_ptr = result + count;
while(result < max_ptr) {
while (result < max_ptr) {
r = abs(col1[0] - col2[0]);
g = abs(col1[1] - col2[1]);
b = abs(col1[2] - col2[2]);
@ -3552,7 +3587,7 @@ __attribute__((noinline)) void fast_delta8_bgra(const uint8_t* col1, const uint8
int r,g,b;
const uint8_t* const max_ptr = result + count;
while(result < max_ptr) {
while (result < max_ptr) {
b = abs(col1[0] - col2[0]);
g = abs(col1[1] - col2[1]);
r = abs(col1[2] - col2[2]);
@ -3580,7 +3615,7 @@ __attribute__((noinline)) void std_delta8_bgra(const uint8_t* col1, const uint8_
int r,g,b;
const uint8_t* const max_ptr = result + count;
while(result < max_ptr) {
while (result < max_ptr) {
b = abs(col1[0] - col2[0]);
g = abs(col1[1] - col2[1]);
r = abs(col1[2] - col2[2]);
@ -3598,7 +3633,7 @@ __attribute__((noinline)) void fast_delta8_argb(const uint8_t* col1, const uint8
int r,g,b;
const uint8_t* const max_ptr = result + count;
while(result < max_ptr) {
while (result < max_ptr) {
r = abs(col1[1] - col2[1]);
g = abs(col1[2] - col2[2]);
b = abs(col1[3] - col2[3]);
@ -3621,12 +3656,13 @@ __attribute__((noinline)) void fast_delta8_argb(const uint8_t* col1, const uint8
result += 4;
}
}
__attribute__((noinline)) void std_delta8_argb(const uint8_t* col1, const uint8_t* col2, uint8_t* result, unsigned long count) {
/* Loop unrolling is used to work on 16 bytes (4 rgb32 pixels) at a time */
int r,g,b;
const uint8_t* const max_ptr = result + count;
while(result < max_ptr) {
while (result < max_ptr) {
r = abs(col1[1] - col2[1]);
g = abs(col1[2] - col2[2]);
b = abs(col1[3] - col2[3]);
@ -3644,7 +3680,7 @@ __attribute__((noinline)) void fast_delta8_abgr(const uint8_t* col1, const uint8
int r,g,b;
const uint8_t* const max_ptr = result + count;
while(result < max_ptr) {
while (result < max_ptr) {
b = abs(col1[1] - col2[1]);
g = abs(col1[2] - col2[2]);
r = abs(col1[3] - col2[3]);
@ -3671,7 +3707,7 @@ __attribute__((noinline)) void std_delta8_abgr(const uint8_t* col1, const uint8_
int r,g,b;
const uint8_t* const max_ptr = result + count;
while(result < max_ptr) {
while (result < max_ptr) {
b = abs(col1[1] - col2[1]);
g = abs(col1[2] - col2[2]);
r = abs(col1[3] - col2[3]);

View File

@ -122,7 +122,7 @@ void Zone::Setup(
} else {
diag_path[0] = 0;
}
} // end Zone::Setup
} // end Zone::Setup
Zone::~Zone() {
delete[] label;
@ -131,7 +131,7 @@ Zone::~Zone() {
delete[] ranges;
}
void Zone::RecordStats( const Event *event ) {
void Zone::RecordStats(const Event *event) {
static char sql[ZM_SQL_MED_BUFSIZ];
db_mutex.lock();
snprintf(sql, sizeof(sql),
@ -142,7 +142,7 @@ void Zone::RecordStats( const Event *event ) {
Error("Can't insert event stats: %s", mysql_error(&dbconn));
}
db_mutex.unlock();
} // end void Zone::RecordStats( const Event *event )
} // end void Zone::RecordStats( const Event *event )
bool Zone::CheckOverloadCount() {
if ( overload_count ) {
@ -151,40 +151,40 @@ bool Zone::CheckOverloadCount() {
return false;
}
return true;
} // end bool Zone::CheckOverloadCount()
} // end bool Zone::CheckOverloadCount()
void Zone::SetScore(unsigned int nScore) {
score = nScore;
} // end void Zone::SetScore(unsigned int nScore)
} // end void Zone::SetScore(unsigned int nScore)
void Zone::SetAlarmImage(const Image* srcImage) {
delete image;
image = new Image(*srcImage);
} // end void Zone::SetAlarmImage( const Image* srcImage )
} // end void Zone::SetAlarmImage( const Image* srcImage )
int Zone::GetOverloadCount() {
return overload_count;
} // end int Zone::GetOverloadCount()
} // end int Zone::GetOverloadCount()
void Zone::SetOverloadCount(int nOverCount) {
overload_count = nOverCount;
} // end void Zone::SetOverloadCount(int nOverCount )
} // end void Zone::SetOverloadCount(int nOverCount )
int Zone::GetOverloadFrames() {
return overload_frames;
} // end int Zone::GetOverloadFrames
} // end int Zone::GetOverloadFrames
int Zone::GetExtendAlarmCount() {
return extend_alarm_count;
} // end int Zone::GetExtendAlarmCount()
} // end int Zone::GetExtendAlarmCount()
void Zone::SetExtendAlarmCount(int nExtendAlarmCount) {
extend_alarm_count = nExtendAlarmCount;
} // end void Zone::SetExtendAlarmCount( int nExtendAlarmCount )
} // end void Zone::SetExtendAlarmCount( int nExtendAlarmCount )
int Zone::GetExtendAlarmFrames() {
return extend_alarm_frames;
} // end int Zone::GetExtendAlarmFrames()
} // end int Zone::GetExtendAlarmFrames()
bool Zone::CheckExtendAlarmCount() {
Info("ExtendAlarm count: %d, ExtendAlarm frames: %d", extend_alarm_count, extend_alarm_frames);
@ -194,7 +194,7 @@ bool Zone::CheckExtendAlarmCount() {
return true;
}
return false;
} // end bool Zone::CheckExtendAlarmCount
} // end bool Zone::CheckExtendAlarmCount
bool Zone::CheckAlarms(const Image *delta_image) {
ResetStats();
@ -984,10 +984,14 @@ bool Zone::DumpSettings(char *output, bool /*verbose*/) {
sprintf( output+strlen(output), " Max Blob Pixels : %d\n", max_blob_pixels );
sprintf( output+strlen(output), " Min Blobs : %d\n", min_blobs );
sprintf( output+strlen(output), " Max Blobs : %d\n", max_blobs );
return( true );
return true;
}
void Zone::std_alarmedpixels(Image* pdiff_image, const Image* ppoly_image, unsigned int* pixel_count, unsigned int* pixel_sum) {
void Zone::std_alarmedpixels(
Image* pdiff_image,
const Image* ppoly_image,
unsigned int* pixel_count,
unsigned int* pixel_sum) {
uint32_t pixelsalarmed = 0;
uint32_t pixelsdifference = 0;
uint8_t calc_max_pixel_threshold = 255;

View File

@ -380,54 +380,54 @@ class Event extends ZM_Object {
$Event = $this;
$eventPath = $Event->Path();
if ( $frame and ! is_array($frame) ) {
if ( $frame and !is_array($frame) ) {
# Must be an Id
Logger::Debug("Assuming that $frame is an Id");
$frame = array( 'FrameId'=>$frame, 'Type'=>'', 'Delta'=>0 );
$frame = array('FrameId'=>$frame, 'Type'=>'', 'Delta'=>0);
}
if ( ( ! $frame ) and file_exists($eventPath.'/snapshot.jpg') ) {
if ( ( !$frame ) and file_exists($eventPath.'/snapshot.jpg') ) {
# No frame specified, so look for a snapshot to use
$captImage = 'snapshot.jpg';
Logger::Debug("Frame not specified, using snapshot");
$frame = array('FrameId'=>'snapshot', 'Type'=>'','Delta'=>0);
Logger::Debug('Frame not specified, using snapshot');
$frame = array('FrameId'=>'snapshot', 'Type'=>'', 'Delta'=>0);
} else {
$captImage = sprintf( '%0'.ZM_EVENT_IMAGE_DIGITS.'d-analyze.jpg', $frame['FrameId'] );
$captImage = sprintf('%0'.ZM_EVENT_IMAGE_DIGITS.'d-analyze.jpg', $frame['FrameId']);
if ( ! file_exists( $eventPath.'/'.$captImage ) ) {
$captImage = sprintf( '%0'.ZM_EVENT_IMAGE_DIGITS.'d-capture.jpg', $frame['FrameId'] );
if ( ! file_exists( $eventPath.'/'.$captImage ) ) {
$captImage = sprintf('%0'.ZM_EVENT_IMAGE_DIGITS.'d-capture.jpg', $frame['FrameId']);
if ( !file_exists($eventPath.'/'.$captImage) ) {
# Generate the frame JPG
if ( $Event->DefaultVideo() ) {
$videoPath = $eventPath.'/'.$Event->DefaultVideo();
if ( ! file_exists( $videoPath ) ) {
Error("Event claims to have a video file, but it does not seem to exist at $videoPath" );
if ( !file_exists($videoPath) ) {
Error('Event claims to have a video file, but it does not seem to exist at '.$videoPath);
return '';
}
#$command ='ffmpeg -v 0 -i '.$videoPath.' -vf "select=gte(n\\,'.$frame['FrameId'].'),setpts=PTS-STARTPTS" '.$eventPath.'/'.$captImage;
$command ='ffmpeg -ss '. $frame['Delta'] .' -i '.$videoPath.' -frames:v 1 '.$eventPath.'/'.$captImage;
Logger::Debug( "Running $command" );
Logger::Debug('Running '.$command);
$output = array();
$retval = 0;
exec( $command, $output, $retval );
exec($command, $output, $retval);
Logger::Debug("Retval: $retval, output: " . implode("\n", $output));
} else {
Error("Can't create frame images from video because there is no video file for event ".$Event->Id().' at ' .$Event->Path() );
Error('Can\'t create frame images from video because there is no video file for event '.$Event->Id().' at ' .$Event->Path());
}
} // end if capture file exists
} // end if analyze file exists
} // end if frame or snapshot
$captPath = $eventPath.'/'.$captImage;
if ( ! file_exists($captPath) ) {
Error("Capture file does not exist at $captPath");
if ( !file_exists($captPath) ) {
Error('Capture file does not exist at '.$captPath);
}
$analImage = sprintf('%0'.ZM_EVENT_IMAGE_DIGITS.'d-analyse.jpg', $frame['FrameId']);
$analPath = $eventPath.'/'.$analImage;
$alarmFrame = $frame['Type']=='Alarm';
$alarmFrame = $frame['Type'] == 'Alarm';
$hasAnalImage = $alarmFrame && file_exists($analPath) && filesize($analPath);
$isAnalImage = $hasAnalImage && !$captureOnly;
@ -443,8 +443,8 @@ class Event extends ZM_Object {
$fraction = sprintf('%.3f', $scale/SCALE_BASE);
$scale = (int)round($scale);
$thumbCaptPath = preg_replace( '/\.jpg$/', "-$scale.jpg", $captPath );
$thumbAnalPath = preg_replace( '/\.jpg$/', "-$scale.jpg", $analPath );
$thumbCaptPath = preg_replace('/\.jpg$/', "-$scale.jpg", $captPath);
$thumbAnalPath = preg_replace('/\.jpg$/', "-$scale.jpg", $analPath);
if ( $isAnalImage ) {
$imagePath = $analPath;
@ -457,7 +457,7 @@ class Event extends ZM_Object {
$thumbFile = $thumbPath;
if ( $overwrite || ! file_exists($thumbFile) || ! filesize($thumbFile) ) {
// Get new dimensions
list( $imageWidth, $imageHeight ) = getimagesize($imagePath);
list($imageWidth, $imageHeight) = getimagesize($imagePath);
$thumbWidth = $imageWidth * $fraction;
$thumbHeight = $imageHeight * $fraction;
@ -484,7 +484,7 @@ class Event extends ZM_Object {
);
return $imageData;
}
} # getImageSrc
public function link_to($text=null) {
if ( !$text )

View File

@ -256,33 +256,189 @@ function getNavBarHTML($reload = null) {
$status = $running ? ($state ? $state : translate('Running')) : translate('Stopped');
?>
<div class="navbar navbar-inverse navbar-static-top">
<div class="container-fluid">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#main-header-nav" aria-expanded="false">
<div class="container-fluid">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#main-header-nav" aria-expanded="false">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
</button>
<div class="navbar-brand">
<a href="<?php echo validHtmlStr(ZM_HOME_URL); ?>" target="<?php echo validHtmlStr(ZM_WEB_TITLE); ?>"><?php echo ZM_HOME_CONTENT ?></a>
</div>
</div>
<div class="collapse navbar-collapse" id="main-header-nav">
<ul class="nav navbar-nav">
</div>
<div class="collapse navbar-collapse" id="main-header-nav">
<ul class="nav navbar-nav">
<?php
// *** Build the navigation bar menu items ***
if ( $user and $user['Username'] ) {
echo getConsoleHTML();
echo getOptionsHTML();
echo getLogHTML();
echo getDevicesHTML();
echo getGroupsHTML();
echo getFilterHTML();
echo getCycleHTML();
echo getMontageHTML();
echo getMontageReviewHTML();
echo getRprtEvntAuditHTML();
echo getHeaderFlipHTML();
?>
</ul>
<div class="navbar-right">
<?php
echo getAcctCircleHTML($user);
echo getStatusBtnHTML($status);
?>
</div>
<?php } else { # end if !$user or $user['Id'] meaning logged in ?>
</ul>
<?php } # end if !$user or $user['Id'] meaning logged in ?>
</div><!-- End .navbar-collapse -->
</div> <!-- End .container-fluid -->
<div id="panel"<?php echo ( isset($_COOKIE['zmHeaderFlip']) and $_COOKIE['zmHeaderFlip'] == 'down' ) ? 'style="display:none;"' : '' ?>>
<?php
} //end reload null. Runs on full page load
if ( (!ZM_OPT_USE_AUTH) or $user ) {
if ($reload == 'reload') ob_start();
?>
<!-- *** Build the statistics shown on the navigation bar *** -->
<div id="reload" class="container-fluid reduced-text">
<div id="Bandwidth" class="pull-left">
<?php echo getBandwidthHTML($bandwidth_options,$user) ?>
</div>
<div id="Version" class="pull-right">
<?php echo getZMVersionHTML($versionClass) ?>
</div>
<ul class="list-inline">
<?php
echo getSysLoadHTML();
echo getDbConHTML();
echo getStorageHTML();
echo getShmHTML();
?>
</ul>
<?php echo getConsoleBannerHTML() ?>
</div><!-- End .footer/reload -->
<?php
if ($reload == 'reload') return ob_get_clean();
} // end if (!ZM_OPT_USE_AUTH) or $user )
?>
</div>
</div><!-- End .navbar .navbar-default -->
<?php
return ob_get_clean();
} // end function getNavBarHTML()
// Returns the html representing the current unix style system load
function getSysLoadHTML() {
echo '<li class="Load">';
echo '<i class="material-icons md-18">trending_up</i>';
echo '&nbsp;'.translate('Load').':'.getLoad();
echo '</li>';
}
// Returns the html representing the current number of connections made to the database
function getDbConHTML() {
$connections = dbFetchOne('SHOW status WHERE variable_name=\'threads_connected\'', 'Value');
$max_connections = dbFetchOne('SHOW variables WHERE variable_name=\'max_connections\'', 'Value');
$percent_used = $max_connections ? 100 * $connections / $max_connections : 100;
$class = $percent_used > 90 ? 'warning' : '';
echo '<i class="material-icons md-18">storage</i>';
echo '<li class="'. $class .'">'.translate('DB').':'.$connections.'/'.$max_connections.'</li>';
}
// Returns the html representing up to 4 storage areas and their current capacity
function getStorageHTML() {
$func = function($S) {
$class = '';
if ( $S->disk_usage_percent() > 98 ) {
$class = 'error';
} else if ( $S->disk_usage_percent() > 90 ) {
$class = 'warning';
}
$title = human_filesize($S->disk_used_space()) . ' of ' . human_filesize($S->disk_total_space()).
( ( $S->disk_used_space() != $S->event_disk_space() ) ? ' ' .human_filesize($S->event_disk_space()) . ' used by events' : '' );
return '<span class="'.$class.'" title="'.$title.'">'.$S->Name() . ': ' . $S->disk_usage_percent().'%' . '</span>';
};
$storage_areas = ZM\Storage::find(array('Enabled'=>true));
$num_storage_areas = count($storage_areas);
$storage_paths = null;
$storage_areas_with_no_server_id = array();
foreach ( $storage_areas as $area ) {
$storage_paths[$area->Path()] = $area;
if ( ! $area->ServerId() ) {
$storage_areas_with_no_server_id[] = $area;
}
}
echo '<li>'.translate('Storage').':';
if ( $num_storage_areas > 4 ) {
$storage_areas = $storage_areas_with_no_server_id;
} else {
echo implode(', ', array_map($func, $storage_areas));
}
echo '</li>';
}
// Returns the html representing the current capacity of mapped memory filesystem (usually /dev/shm)
function getShmHTML() {
$shm_percent = getDiskPercent(ZM_PATH_MAP);
$shm_total_space = disk_total_space(ZM_PATH_MAP);
$shm_used = $shm_total_space - disk_free_space(ZM_PATH_MAP);
$class = '';
if ( $shm_percent > 98 ) {
$class = 'error';
} else if ( $shm_percent > 90 ) {
$class = 'warning';
}
echo ' <span class="'.$class.'" title="' . human_filesize($shm_used).' of '.human_filesize($shm_total_space).'">'.ZM_PATH_MAP.': '.$shm_percent.'%</span>';
}
// Returns the html representing the optional web console banner text
function getConsoleBannerHTML() {
if ( defined('ZM_WEB_CONSOLE_BANNER') and ZM_WEB_CONSOLE_BANNER != '' ) {
echo '<h3 id="development">'.validHtmlStr(ZM_WEB_CONSOLE_BANNER).'</h3>';
}
}
// Returns the html representing the current high,medium,low bandwidth setting
function getBandwidthHTML($bandwidth_options,$user) {
echo makePopupLink( '?view=bandwidth', 'zmBandwidth', 'bandwidth', "<i class='material-icons md-18'>network_check</i>&nbsp;".$bandwidth_options[$_COOKIE['zmBandwidth']] . ' ', ($user && $user['MaxBandwidth'] != 'low' ));
}
// Returns the html representing the version of ZoneMinder
function getZMVersionHTML($versionClass) {
echo makePopupLink( '?view=version', 'zmVersion', 'version', '<span class="version '.$versionClass.'">v'.ZM_VERSION.'</span>', canEdit('System') );
}
// Returns the html representing the Console menu item
function getConsoleHTML() {
if ( canView('Monitors') ) {
?>
<li><a href="?view=console"><?php echo translate('Console') ?></a></li>
<?php
} // end if canView('Monitors')
echo '<li><a href="?view=console">'.translate('Console').'</a></li>';
}
}
// Returns the html representing the Options menu item
function getOptionsHTML() {
if ( canView('System') ) {
echo '<li><a href="?view=options">'.translate('Options').'</a></li>';
}
}
// Returns the html representing the Log menu item
function getLogHTML() {
if ( canView('System') ) {
?>
<li><a href="?view=options"><?php echo translate('Options') ?></a></li>
<li>
<?php
if ( ZM\logToDatabase() > ZM\Logger::NOLOG ) {
if ( ! ZM_RUN_AUDIT ) {
# zmaudit can clean the logs, but if we aren't running it, then we should clean them regularly
@ -298,28 +454,48 @@ if ( $user and $user['Username'] ) {
ZM\Error('Potentially invalid value for ZM_LOG_DATABASE_LIMIT: ' . ZM_LOG_DATABASE_LIMIT);
}
}
echo makePopupLink('?view=log', 'zmLog', 'log', '<span class="'.logState().'">'.translate('Log').'</span>');
echo '<li>'.makePopupLink('?view=log', 'zmLog', 'log', '<span class="'.logState().'">'.translate('Log').'</span></li>');
}
?>
</li>
<?php
} // end if canview(System)
if ( ZM_OPT_X10 && canView('Devices') ) { ?>
<li><a href="?view=devices">Devices</a></li>
<?php
}
?>
<li><a href="?view=groups"<?php echo $view=='groups'?' class="selected"':''?>><?php echo translate('Groups') ?></a></li>
<li><a href="?view=filter<?php echo $filterQuery.$sortQuery.$limitQuery ?>"<?php echo $view=='filter'?' class="selected"':''?>><?php echo translate('Filters') ?></a></li>
}
<?php
// Returns the html representing the X10 Devices menu item
function getDevicesHTML() {
if ( ZM_OPT_X10 && canView('Devices') ) {
echo '<li><a href="?view=devices">Devices</a></li>';
}
}
// Returns the html representing the Groups menu item
function getGroupsHTML() {
$class = $view == 'groups' ? 'selected' : '';
echo '<li><a href="?view=groups" class="' .$class. '">'. translate('Groups') .'</a></li>';
}
// Returns the html representing the Filter menu item
function getFilterHTML() {
$class = $view == 'filter' ? 'selected' : '';
echo '<li><a href="?view=filter'.$filterQuery.$sortQuery.$limitQuery.'" class="'.$class.'">'.translate('Filters').'</a></li>';
}
// Returns the html representing the Cycle menu item
function getCycleHTML() {
if ( canView('Stream') ) {
?>
<li><a href="?view=cycle"<?php echo $view=='cycle'?' class="selected"':''?>><?php echo translate('Cycle') ?></a></li>
<li><a href="?view=montage"<?php echo $view=='montage'?' class="selected"':''?>><?php echo translate('Montage') ?></a></li>
<?php
}
$class = $view == 'cycle' ? 'selected' : '';
echo '<li><a href="?view=cycle" class="' .$class. '">' .translate('Cycle'). '</a></li>';
}
}
// Returns the html representing the Montage menu item
function getMontageHTML() {
if ( canView('Stream') ) {
$class = $view == 'cycle' ? 'selected' : '';
echo '<li><a href="?view=montage" class="' .$class. '">' .translate('Montage'). '</a></li>';
}
}
// Returns the html representing the MontageReview menu item
function getMontageReviewHTML() {
if ( canView('Events') ) {
if ( isset($_REQUEST['filter']['Query']['terms']['attr']) ) {
$terms = $_REQUEST['filter']['Query']['terms'];
@ -335,119 +511,53 @@ if ( $user and $user['Username'] ) {
$montageReviewQuery = '&minTime='.$minTime.'&maxTime='.$maxTime;
}
}
?>
<li><a href="?view=montagereview<?php echo isset($montageReviewQuery)?'&fit=1'.$montageReviewQuery.'&live=0':'' ?>"<?php echo $view=='montagereview'?' class="selected"':''?>><?php echo translate('MontageReview')?></a></li>
<li><a href="?view=report_event_audit"<?php echo $view=='report_event_audit'?' class="selected"':''?>><?php echo translate('ReportEventAudit') ?></a></li>
<?php
} // end if canView(Events)
?>
<li><a href="#"><i id="flip" class="material-icons md-18 pull-right">keyboard_arrow_<?php echo ( isset($_COOKIE['zmHeaderFlip']) and $_COOKIE['zmHeaderFlip'] == 'down') ? 'down' : 'up' ?></i></a></li>
</ul>
$live = isset($montageReviewQuery) ? '&fit=1'.$montageReviewQuery.'&live=0' : '';
$class = $view == 'montagereview' ? 'selected' : '';
echo '<li><a href="?view=montagereview' .$live. '" class="' .$class. '">' .translate('MontageReview'). '</a></li>';
}
}
<div class="navbar-right">
<?php
// Returns the html representing the Audit Events Report menu item
function getRprtEvntAuditHTML() {
if ( canView('Events') ) {
$class = $view == 'report_event_audit' ? 'selected' : '';
echo '<li><a href="?view=report_event_audit class="' .$class. '">' .translate('ReportEventAudit'). '</a></li>';
}
}
// Returns the html representing the header collapse toggle menu item
function getHeaderFlipHTML() {
$header = ( isset($_COOKIE['zmHeaderFlip']) and $_COOKIE['zmHeaderFlip'] == 'down') ? 'down' : 'up';
echo '<li><a href="#"><i id="flip" class="material-icons md-18 pull-right">keyboard_arrow_' .$header. '</i></a></li>';
}
// Returns the html representing the logged in user name and avatar
function getAcctCircleHTML($user=null) {
if ( ZM_OPT_USE_AUTH and $user ) {
?>
<p class="navbar-text">
<i class="material-icons">account_circle</i>
<?php echo makePopupLink('?view=logout', 'zmLogout', 'logout', $user['Username'], (ZM_AUTH_TYPE == 'builtin') ) ?>
</p>
<?php
echo '<p class="navbar-text">';
echo '<i class="material-icons">account_circle</i>';
echo makePopupLink('?view=logout', 'zmLogout', 'logout', $user['Username'], (ZM_AUTH_TYPE == 'builtin') );
echo '</p>';
}
}
// Returns the html representing the runtime status button
function getStatusBtnHTML($status) {
if ( canEdit('System') ) {
?>
<button type="button" class="btn btn-default navbar-btn" data-toggle="modal" data-target="#modalState"><?php echo $status ?></button>
<?php if ( ZM_SYSTEM_SHUTDOWN ) { ?>
<p class="navbar-text">
<?php echo makePopupLink('?view=shutdown', 'zmShutdown', 'shutdown', '<i class="material-icons md-18">power_settings_new</i>' ) ?>
</p>
<?php } ?>
<?php } else if ( canView('System') ) { ?>
<p class="navbar-text"><?php echo $status ?></p>
<?php } ?>
</div>
<?php } else { # end if !$user or $user['Id'] meaning logged in ?>
</ul>
<?php } # end if !$user or $user['Id'] meaning logged in ?>
</div><!-- End .navbar-collapse -->
</div> <!-- End .container-fluid -->
<div id="panel"<?php echo ( isset($_COOKIE['zmHeaderFlip']) and $_COOKIE['zmHeaderFlip'] == 'down' ) ? 'style="display:none;"' : '' ?>>
<?php
} //end reload null. Runs on full page load
echo '<button type="button" class="btn btn-default navbar-btn" data-toggle="modal" data-target="#modalState">' .$status. '</button>';
if ( (!ZM_OPT_USE_AUTH) or $user ) {
if ($reload == 'reload') ob_start();
?>
<div id="reload" class="container-fluid reduced-text">
<div id="Bandwidth" class="pull-left">
<?php echo makePopupLink( '?view=bandwidth', 'zmBandwidth', 'bandwidth', "<i class='material-icons md-18'>network_check</i>&nbsp;".$bandwidth_options[$_COOKIE['zmBandwidth']] . ' ', ($user && $user['MaxBandwidth'] != 'low' ) ) ?>
</div>
<div id="Version" class="pull-right">
<?php echo makePopupLink( '?view=version', 'zmVersion', 'version', '<span class="version '.$versionClass.'">v'.ZM_VERSION.'</span>', canEdit('System') ) ?>
</div>
<ul class="list-inline">
<li class="Load"><i class="material-icons md-18">trending_up</i>&nbsp;<?php echo translate('Load') ?>: <?php echo getLoad() ?></li>
<i class="material-icons md-18">storage</i>
<?php
$connections = dbFetchOne('SHOW status WHERE variable_name=\'threads_connected\'', 'Value');
$max_connections = dbFetchOne('SHOW variables WHERE variable_name=\'max_connections\'', 'Value');
$percent_used = $max_connections ? 100 * $connections / $max_connections : 100;
echo '<li'. ( $percent_used > 90 ? ' class="warning"' : '' ).'>'.translate('DB').':'.$connections.'/'.$max_connections.'</li>';
?>
<li><?php echo translate('Storage') ?>:
<?php
$storage_areas = ZM\Storage::find(array('Enabled'=>true));
$storage_paths = null;
$storage_areas_with_no_server_id = array();
foreach ( $storage_areas as $area ) {
$storage_paths[$area->Path()] = $area;
if ( ! $area->ServerId() ) {
$storage_areas_with_no_server_id[] = $area;
}
if ( ZM_SYSTEM_SHUTDOWN ) {
echo '<p class="navbar-text">';
echo makePopupLink('?view=shutdown', 'zmShutdown', 'shutdown', '<i class="material-icons md-18">power_settings_new</i>' );
echo '</p>';
}
} else if ( canView('System') ) {
echo '<p class="navbar-text">';
echo $status;
echo '</p>';
}
$func = function($S){
$class = '';
if ( $S->disk_usage_percent() > 98 ) {
$class = 'error';
} else if ( $S->disk_usage_percent() > 90 ) {
$class = 'warning';
}
$title = human_filesize($S->disk_used_space()) . ' of ' . human_filesize($S->disk_total_space()).
( ( $S->disk_used_space() != $S->event_disk_space() ) ? ' ' .human_filesize($S->event_disk_space()) . ' used by events' : '' );
return '<span class="'.$class.'" title="'.$title.'">'.$S->Name() . ': ' . $S->disk_usage_percent().'%' . '</span>
'; };
#$func = function($S){ return '<span title="">'.$S->Name() . ': ' . $S->disk_usage_percent().'%' . '</span>'; };
if ( count($storage_areas) > 4 )
$storage_areas = $storage_areas_with_no_server_id;
if ( count($storage_areas) <= 4 )
echo implode(', ', array_map($func, $storage_areas));
$shm_percent = getDiskPercent(ZM_PATH_MAP);
$shm_total_space = disk_total_space(ZM_PATH_MAP);
$shm_used = $shm_total_space - disk_free_space(ZM_PATH_MAP);
$class = '';
if ( $shm_percent > 98 ) {
$class = 'error';
} else if ( $shm_percent > 90 ) {
$class = 'warning';
}
echo ' <span class="'.$class.'" title="' . human_filesize($shm_used).' of '.human_filesize($shm_total_space).'">'.ZM_PATH_MAP.': '.$shm_percent.'%</span>';
?></li>
</ul>
<?php if ( defined('ZM_WEB_CONSOLE_BANNER') and ZM_WEB_CONSOLE_BANNER != '' ) { ?>
<h3 id="development"><?php echo validHtmlStr(ZM_WEB_CONSOLE_BANNER); ?></h3>
<?php } ?>
<!-- End .footer/reload --></div>
<?php
if ($reload == 'reload') return ob_get_clean();
} // end if (!ZM_OPT_USE_AUTH) or $user )
?>
</div>
</div><!-- End .navbar .navbar-default -->
<?php
return ob_get_clean();
} // end function getNavBarHTML()
}
function xhtmlFooter() {
global $cspNonce;

View File

@ -50,19 +50,19 @@ $lastFid = $maxFid;
$alarmFrame = $Frame->Type() == 'Alarm';
if ( isset( $_REQUEST['scale'] ) ) {
if ( isset($_REQUEST['scale']) ) {
$scale = validNum($_REQUEST['scale']);
} else if ( isset( $_COOKIE['zmWatchScale'.$Monitor->Id()] ) ) {
} else if ( isset($_COOKIE['zmWatchScale'.$Monitor->Id()]) ) {
$scale = validNum($_COOKIE['zmWatchScale'.$Monitor->Id()]);
} else if ( isset( $_COOKIE['zmWatchScale'] ) ) {
} else if ( isset($_COOKIE['zmWatchScale']) ) {
$scale = validNum($_COOKIE['zmWatchScale']);
} else {
$scale = max(reScale(SCALE_BASE, $Monitor->DefaultScale(), ZM_WEB_DEFAULT_SCALE), SCALE_BASE);
}
$scale = $scale ?: 'auto';
$scale = $scale ? $scale : 0;
$imageData = $Event->getImageSrc( $frame, $scale, 0 );
if ( ! $imageData ) {
$imageData = $Event->getImageSrc($frame, $scale, 0);
if ( !$imageData ) {
ZM\Error("No data found for Event $eid frame $fid");
$imageData = array();
}
@ -89,10 +89,10 @@ xhtmlHeaders(__FILE__, translate('Frame').' - '.$Event->Id().' - '.$Frame->Frame
<form>
<div id="headerButtons">
<?php if ( ZM_RECORD_EVENT_STATS && $alarmFrame ) { echo makePopupLink( '?view=stats&amp;eid='.$Event->Id().'&amp;fid='.$Frame->FrameId(), 'zmStats', 'stats', translate('Stats') ); } ?>
<?php if ( canEdit( 'Events' ) ) { ?><a href="?view=none&amp;action=delete&amp;markEid=<?php echo $Event->Id() ?>"><?php echo translate('Delete') ?></a><?php } ?>
<?php if ( canEdit('Events') ) { ?><a href="?view=none&amp;action=delete&amp;markEid=<?php echo $Event->Id() ?>"><?php echo translate('Delete') ?></a><?php } ?>
<a href="#" data-on-click="closeWindow"><?php echo translate('Close') ?></a>
</div>
<div id="scaleControl"><label for="scale"><?php echo translate('Scale') ?></label><?php echo buildSelect('scale', $scales); ?></div>
<div id="scaleControl"><label for="scale"><?php echo translate('Scale') ?></label><?php echo htmlSelect('scale', $scales, $scale); ?></div>
<h2><?php echo translate('Frame') ?> <?php echo $Event->Id().'-'.$Frame->FrameId().' ('.$Frame->Score().')' ?></h2>
<input type="hidden" name="base_width" id="base_width" value="<?php echo $Event->Width(); ?>"/>
<input type="hidden" name="base_height" id="base_height" value="<?php echo $Event->Height(); ?>"/>
@ -100,7 +100,6 @@ xhtmlHeaders(__FILE__, translate('Frame').' - '.$Event->Id().' - '.$Frame->Frame
</div>
<div id="content">
<p id="image">
<?php if ( $imageData['hasAnalImage'] ) {
echo sprintf('<a href="?view=frame&amp;eid=%d&amp;fid=%d&scale=%d&amp;show=%s">', $Event->Id(), $Frame->FrameId(), $scale, ( $show=='anal'?'capt':'anal' ) );
} ?>

View File

@ -11,7 +11,7 @@ function changeScale() {
if ( img ) {
var baseWidth = $j('#base_width').val();
var baseHeight = $j('#base_height').val();
if ( scale == 'auto' ) {
if ( ! parseInt(scale) ) {
var newSize = scaleToFit(baseWidth, baseHeight, img, $j('#controls'));
newWidth = newSize.width;
newHeight = newSize.height;
@ -24,7 +24,7 @@ function changeScale() {
img.css('width', newWidth + 'px');
img.css('height', newHeight + 'px');
}
Cookie.write( 'zmWatchScale', scale, {duration: 10*365} );
Cookie.write('zmWatchScale', scale, {duration: 10*365});
$j.each(controlsLinks, function(k, anchor) { //Make frames respect scale choices
if ( anchor ) {
anchor.prop('href', anchor.prop('href').replace(/scale=.*&/, 'scale=' + scale + '&'));
@ -32,7 +32,7 @@ function changeScale() {
});
}
if ( scale == 'auto' ) {
if ( !scale ) {
$j(document).ready(changeScale);
}