Merge branch 'storageareas' of github.com:ConnorTechnology/ZoneMinder into storageareas

This commit is contained in:
Isaac Connor 2017-04-28 10:36:04 -04:00
commit b166579f4b
2 changed files with 1587 additions and 1582 deletions

View File

@ -27,7 +27,7 @@ zmdc.pl - ZoneMinder Daemon Control script
=head1 SYNOPSIS =head1 SYNOPSIS
zmdc.pl {command} [daemon [options]] zmdc.pl {command} [daemon [options]]
=head1 DESCRIPTION =head1 DESCRIPTION
@ -39,12 +39,13 @@ connect to the server and pass instructions to it.
=head1 OPTIONS =head1 OPTIONS
{command} - One of 'startup|shutdown|status|check|logrot' or {command} - One of 'startup|shutdown|status|check|logrot' or
'start|stop|restart|reload|version'. 'start|stop|restart|reload|version'.
[daemon [options]] - Daemon name and options, required for second group of commands [daemon [options]] - Daemon name and options, required for second group of commands
=cut =cut
use strict; use strict;
use warnings;
use bytes; use bytes;
# ========================================================================== # ==========================================================================
@ -53,7 +54,9 @@ use bytes;
# #
# ========================================================================== # ==========================================================================
use constant MAX_CONNECT_DELAY => 10; # in useconds, not seconds.
use constant MAX_CONNECT_DELAY => 10*1000*1000;
use constant KILL_DELAY => 10*1000; # 1/10th of a second
# ========================================================================== # ==========================================================================
# #
@ -66,6 +69,7 @@ use ZoneMinder;
use POSIX; use POSIX;
use Socket; use Socket;
use IO::Handle; use IO::Handle;
use Time::HiRes qw(usleep);
use autouse 'Pod::Usage'=>qw(pod2usage); use autouse 'Pod::Usage'=>qw(pod2usage);
#use Data::Dumper; #use Data::Dumper;
@ -98,10 +102,10 @@ my @daemons = (
'zmupdate.pl', 'zmupdate.pl',
'zmtrack.pl', 'zmtrack.pl',
'zmtelemetry.pl' 'zmtelemetry.pl'
); );
my $command = shift @ARGV; my $command = shift @ARGV;
if( !$command ) { if( ! $command ) {
print( STDERR "No command given\n" ); print( STDERR "No command given\n" );
pod2usage(-exitstatus => -1); pod2usage(-exitstatus => -1);
} }
@ -111,7 +115,7 @@ if ( $command eq 'version' ) {
} }
my $needs_daemon = $command !~ /(?:startup|shutdown|status|check|logrot|version)/; my $needs_daemon = $command !~ /(?:startup|shutdown|status|check|logrot|version)/;
my $daemon = shift( @ARGV ); my $daemon = shift( @ARGV );
if( $needs_daemon && !$daemon ) { if ( $needs_daemon && ! $daemon ) {
print( STDERR "No daemon given\n" ); print( STDERR "No daemon given\n" );
pod2usage(-exitstatus => -1); pod2usage(-exitstatus => -1);
} }
@ -128,8 +132,8 @@ if ( $needs_daemon ) {
} }
foreach my $arg ( @ARGV ) { foreach my $arg ( @ARGV ) {
# Detaint arguments, if they look ok # Detaint arguments, if they look ok
#if ( $arg =~ /^(-{0,2}[\w]+)/ ) #if ( $arg =~ /^(-{0,2}[\w]+)/ )
if ( $arg =~ /^(-{0,2}[\w\/?&=.-]+)$/ ) { if ( $arg =~ /^(-{0,2}[\w\/?&=.-]+)$/ ) {
push( @args, $1 ); push( @args, $1 );
} else { } else {
@ -142,8 +146,10 @@ socket( CLIENT, PF_UNIX, SOCK_STREAM, 0 ) or Fatal( "Can't open socket: $!" );
my $saddr = sockaddr_un( SOCK_FILE ); my $saddr = sockaddr_un( SOCK_FILE );
my $server_up = connect( CLIENT, $saddr ); my $server_up = connect( CLIENT, $saddr );
if ( !$server_up ) { if ( ! $server_up ) {
# Server is not up. Some commands can still be handled
if ( $command eq 'logrot' ) { if ( $command eq 'logrot' ) {
# If server is not running, then logrotate doesn't need to do anything.
exit(); exit();
} }
if ( $command eq 'check' ) { if ( $command eq 'check' ) {
@ -153,43 +159,47 @@ if ( !$server_up ) {
print( "Unable to connect to server using socket at " . SOCK_FILE . "\n" ); print( "Unable to connect to server using socket at " . SOCK_FILE . "\n" );
exit( -1 ); exit( -1 );
} }
# The server isn't there # The server isn't there
print( "Starting server\n" ); print( "Starting server\n" );
close( CLIENT ); close( CLIENT );
if ( my $cpid = fork() ) { if ( my $cpid = fork() ) {
# Parent process just sleep and fall through
# I'm still not sure why we need to re-init the logs
logInit(); logInit();
# Parent process just sleep and fall through
socket( CLIENT, PF_UNIX, SOCK_STREAM, 0 ) or Fatal( "Can't open socket: $!" ); socket( CLIENT, PF_UNIX, SOCK_STREAM, 0 ) or Fatal( "Can't open socket: $!" );
my $attempts = 0; my $attempts = 0;
while (!connect( CLIENT, $saddr )) { while( !connect( CLIENT, $saddr ) ) {
$attempts++; $attempts++;
Error("Waiting for zmdc.pl server process, attempt $attempts" );
Fatal( "Can't connect: $!" ) if ($attempts > MAX_CONNECT_DELAY); Fatal( "Can't connect: $!" ) if ($attempts > MAX_CONNECT_DELAY);
sleep(1); usleep(100);
} } # end while
} elsif ( defined($cpid) ) { } elsif ( defined($cpid) ) {
ZMServer::run(); ZMServer::run();
} else { } else {
Fatal( "Can't fork: $!" ); Fatal( "Can't fork: $!" );
} }
} } # end if ! server is up
if ( $command eq 'check' && !$daemon ) {
if ( $command eq 'check' && ! $daemon ) {
print( "running\n" ); print( "running\n" );
exit(); exit();
} elsif ( $command eq 'startup' ) { } elsif ( $command eq 'startup' ) {
# Our work here is done # Our work here is done
exit() if ( !$server_up ); exit() if ( !$server_up );
} }
# The server is there, connect to it # The server is there, connect to it
#print( "Writing commands\n" ); #print( "Writing commands\n" );
CLIENT->autoflush(); CLIENT->autoflush();
my $message = "$command"; my $message = join(';', $command, ( $daemon ? $daemon : () ), @args );
$message .= ";$daemon" if ( $daemon );
$message .= ";".join( ';', @args ) if ( @args );
print( CLIENT $message ); print( CLIENT $message );
shutdown( CLIENT, 1 ); shutdown( CLIENT, 1 );
while ( my $line = <CLIENT> ) { while( my $line = <CLIENT> ) {
chomp( $line ); chomp( $line );
print( "$line\n" ); print( "$line\n" );
} }
@ -202,6 +212,7 @@ exit;
package ZMServer; package ZMServer;
use strict; use strict;
use warnings;
use bytes; use bytes;
@EXTRA_PERL_LIB@ @EXTRA_PERL_LIB@
@ -275,7 +286,7 @@ sub run {
} elsif ( $command eq 'reload' ) { } elsif ( $command eq 'reload' ) {
reload( $daemon, @args ); reload( $daemon, @args );
} elsif ( $command eq 'startup' ) { } elsif ( $command eq 'startup' ) {
# Do nothing, this is all we're here for # Do nothing, this is all we're here for
dPrint( ZoneMinder::Logger::WARNING, "Already running, ignoring command '$command'\n" ); dPrint( ZoneMinder::Logger::WARNING, "Already running, ignoring command '$command'\n" );
} elsif ( $command eq 'shutdown' ) { } elsif ( $command eq 'shutdown' ) {
shutdownAll(); shutdownAll();
@ -298,9 +309,9 @@ sub run {
} }
} elsif ( $nfound < 0 ) { } elsif ( $nfound < 0 ) {
if ( $! == EINTR ) { if ( $! == EINTR ) {
# Dead child, will be reaped # Dead child, will be reaped
#print( "Probable dead child\n" ); #print( "Probable dead child\n" );
# See if it needs to start up again # See if it needs to start up again
restartPending(); restartPending();
} elsif ( $! == EPIPE ) { } elsif ( $! == EPIPE ) {
Error( "Can't select: $!" ); Error( "Can't select: $!" );
@ -308,7 +319,7 @@ sub run {
Fatal( "Can't select: $!" ); Fatal( "Can't select: $!" );
} }
} else { } else {
#print( "Select timed out\n" ); #print( "Select timed out\n" );
restartPending(); restartPending();
} }
} }
@ -353,7 +364,7 @@ sub start {
my $process = $cmd_hash{$command}; my $process = $cmd_hash{$command};
if ( !$process ) { if ( !$process ) {
# It's not running, or at least it's not been started by us # It's not running, or at least it's not been started by us
$process = { daemon=>$daemon, args=>\@args, command=>$command, keepalive=>!undef }; $process = { daemon=>$daemon, args=>\@args, command=>$command, keepalive=>!undef };
} elsif ( $process->{pid} && $pid_hash{$process->{pid}} ) { } elsif ( $process->{pid} && $pid_hash{$process->{pid}} ) {
dPrint( ZoneMinder::Logger::INFO, "'$process->{command}' already running at " dPrint( ZoneMinder::Logger::INFO, "'$process->{command}' already running at "
@ -381,7 +392,7 @@ sub start {
$cmd_hash{$process->{command}} = $pid_hash{$cpid} = $process; $cmd_hash{$process->{command}} = $pid_hash{$cpid} = $process;
sigprocmask( SIG_SETMASK, $sigset ) or Fatal( "Can't restore SIGCHLD: $!" ); sigprocmask( SIG_SETMASK, $sigset ) or Fatal( "Can't restore SIGCHLD: $!" );
} elsif ( defined($cpid ) ) { } elsif ( defined($cpid ) ) {
# Force reconnection to the db. # Force reconnection to the db.
zmDbConnect(1); zmDbConnect(1);
logReinit(); logReinit();
@ -399,7 +410,7 @@ sub start {
my @good_args; my @good_args;
foreach my $arg ( @args ) { foreach my $arg ( @args ) {
# Detaint arguments, if they look ok # Detaint arguments, if they look ok
if ( $arg =~ /^(-{0,2}[\w\/?&=.-]+)$/ ) { if ( $arg =~ /^(-{0,2}[\w\/?&=.-]+)$/ ) {
push( @good_args, $1 ); push( @good_args, $1 );
} else { } else {
@ -415,7 +426,7 @@ sub start {
POSIX::close( $fd++ ); POSIX::close( $fd++ );
} }
# Child process # Child process
$SIG{CHLD} = 'DEFAULT'; $SIG{CHLD} = 'DEFAULT';
$SIG{INT} = 'DEFAULT'; $SIG{INT} = 'DEFAULT';
$SIG{TERM} = 'DEFAULT'; $SIG{TERM} = 'DEFAULT';
@ -474,7 +485,7 @@ sub kill_until_dead {
} }
sigprocmask(SIG_UNBLOCK, $blockset) or die "dying at unblock...\n"; sigprocmask(SIG_UNBLOCK, $blockset) or die "dying at unblock...\n";
usleep( 100 ); usleep( KILL_DELAY );
sigprocmask(SIG_BLOCK, $blockset, $sigset ) or die "dying at block...\n"; sigprocmask(SIG_BLOCK, $blockset, $sigset ) or die "dying at block...\n";
} }
} }
@ -581,7 +592,7 @@ sub reaper {
$out_str .= 'normally'; $out_str .= 'normally';
} }
} }
#print( ", core dumped" ) if ( $core_dumped ); #print( ", core dumped" ) if ( $core_dumped );
$out_str .= "\n"; $out_str .= "\n";
if ( $exit_status == 0 ) { if ( $exit_status == 0 ) {
@ -591,16 +602,16 @@ sub reaper {
} }
if ( $process->{keepalive} ) { if ( $process->{keepalive} ) {
# Schedule for immediate restart # Schedule for immediate restart
$cmd_hash{$process->{command}} = $process; $cmd_hash{$process->{command}} = $process;
if ( !$process->{delay} || ($process->{runtime} > $Config{ZM_MAX_RESTART_DELAY} ) ) { if ( !$process->{delay} || ($process->{runtime} > $Config{ZM_MAX_RESTART_DELAY} ) ) {
#start( $process->{daemon}, @{$process->{args}} ); #start( $process->{daemon}, @{$process->{args}} );
$process->{pending} = $process->{stopped}; $process->{pending} = $process->{stopped};
$process->{delay} = 5; $process->{delay} = 5;
} else { } else {
$process->{pending} = $process->{stopped}+$process->{delay}; $process->{pending} = $process->{stopped}+$process->{delay};
$process->{delay} *= 2; $process->{delay} *= 2;
# Limit the start delay to 15 minutes max # Limit the start delay to 15 minutes max
if ( $process->{delay} > $Config{ZM_MAX_RESTART_DELAY} ) { if ( $process->{delay} > $Config{ZM_MAX_RESTART_DELAY} ) {
$process->{delay} = $Config{ZM_MAX_RESTART_DELAY}; $process->{delay} = $Config{ZM_MAX_RESTART_DELAY};
} }
@ -612,7 +623,7 @@ sub reaper {
} }
sub restartPending { sub restartPending {
# Restart any pending processes # Restart any pending processes
foreach my $process ( values( %cmd_hash ) ) { foreach my $process ( values( %cmd_hash ) ) {
if ( $process->{pending} && $process->{pending} <= time() ) { if ( $process->{pending} && $process->{pending} <= time() ) {
dPrint( ZoneMinder::Logger::INFO, "Starting pending process, $process->{command}\n" ); dPrint( ZoneMinder::Logger::INFO, "Starting pending process, $process->{command}\n" );
@ -623,12 +634,12 @@ sub restartPending {
sub shutdownAll { sub shutdownAll {
foreach my $pid ( keys %pid_hash ) { foreach my $pid ( keys %pid_hash ) {
# This is a quick fix because a SIGCHLD can happen and alter pid_hash while we are in here. # This is a quick fix because a SIGCHLD can happen and alter pid_hash while we are in here.
next if ! $pid_hash{$pid}; next if ! $pid_hash{$pid};
send_stop( 1, $pid_hash{$pid} ); send_stop( 1, $pid_hash{$pid} );
} }
foreach my $pid ( keys %pid_hash ) { foreach my $pid ( keys %pid_hash ) {
# This is a quick fix because a SIGCHLD can happen and alter pid_hash while we are in here. # This is a quick fix because a SIGCHLD can happen and alter pid_hash while we are in here.
next if ! $pid_hash{$pid}; next if ! $pid_hash{$pid};
my $process = $pid_hash{$pid}; my $process = $pid_hash{$pid};
@ -637,7 +648,9 @@ sub shutdownAll {
delete( $cmd_hash{$$process{command}} ); delete( $cmd_hash{$$process{command}} );
delete( $pid_hash{$pid} ); delete( $pid_hash{$pid} );
} }
if ( 0 ) {
killAll( 5 ); killAll( 5 );
}
dPrint( ZoneMinder::Logger::INFO, "Server shutdown at " dPrint( ZoneMinder::Logger::INFO, "Server shutdown at "
.strftime( '%y/%m/%d %H:%M:%S', localtime() ) .strftime( '%y/%m/%d %H:%M:%S', localtime() )
."\n" ."\n"
@ -653,8 +666,7 @@ sub check {
my $daemon = shift; my $daemon = shift;
my @args = @_; my @args = @_;
my $command = $daemon; my $command = join( ' ', $daemon, @args );
$command .= ' '.join( ' ', ( @args ) ) if ( @args );
my $process = $cmd_hash{$command}; my $process = $cmd_hash{$command};
if ( !$process ) { if ( !$process ) {
cPrint( "unknown\n" ); cPrint( "unknown\n" );
@ -662,7 +674,7 @@ sub check {
cPrint( "pending\n" ); cPrint( "pending\n" );
} else { } else {
my $cpid = $process->{pid}; my $cpid = $process->{pid};
if ( !$pid_hash{$cpid} ) { if ( ! $pid_hash{$cpid} ) {
cPrint( "stopped\n" ); cPrint( "stopped\n" );
} else { } else {
cPrint( "running\n" ); cPrint( "running\n" );
@ -675,28 +687,27 @@ sub status {
my @args = @_; my @args = @_;
if ( defined($daemon) ) { if ( defined($daemon) ) {
my $command = $daemon; my $command = join( ' ', $daemon, @args );
$command .= ' '.join( ' ', ( @args ) ) if ( @args );
my $process = $cmd_hash{$command}; my $process = $cmd_hash{$command};
if ( !$process ) { if ( ! $process ) {
dPrint( ZoneMinder::Logger::DEBUG, "'$command' not running\n" ); dPrint( ZoneMinder::Logger::DEBUG, "'$command' not running\n" );
return(); return();
} }
if ( $process->{pending} ) { if ( $process->{pending} ) {
dPrint( ZoneMinder::Logger::DEBUG, "'$process->{command}' pending at " dPrint( ZoneMinder::Logger::DEBUG, "'$process->{command}' pending at "
.strftime( '%y/%m/%d %H:%M:%S', localtime( $process->{pending}) ) .strftime( '%y/%m/%d %H:%M:%S', localtime( $process->{pending} ) )
."\n" ."\n"
); );
} else { } else {
my $cpid = $process->{pid}; my $cpid = $process->{pid};
if ( !$pid_hash{$cpid} ) { if ( ! $pid_hash{$cpid} ) {
dPrint( ZoneMinder::Logger::DEBUG, "'$command' not running\n" ); dPrint( ZoneMinder::Logger::DEBUG, "'$command' not running\n" );
return(); return();
} }
} }
dPrint( ZoneMinder::Logger::DEBUG, "'$process->{command}' running since " dPrint( ZoneMinder::Logger::DEBUG, "'$process->{command}' running since "
.strftime( '%y/%m/%d %H:%M:%S', localtime( $process->{started}) ) .strftime( '%y/%m/%d %H:%M:%S', localtime( $process->{started} ) )
.", pid = $process->{pid}" .", pid = $process->{pid}"
); );
} else { } else {
@ -712,11 +723,11 @@ sub status {
foreach my $process ( values( %cmd_hash ) ) { foreach my $process ( values( %cmd_hash ) ) {
if ( $process->{pending} ) { if ( $process->{pending} ) {
dPrint( ZoneMinder::Logger::DEBUG, "'$process->{command}' pending at " dPrint( ZoneMinder::Logger::DEBUG, "'$process->{command}' pending at "
.strftime( '%y/%m/%d %H:%M:%S', localtime( $process->{pending}) ) .strftime( '%y/%m/%d %H:%M:%S', localtime( $process->{pending} ) )
."\n" ."\n"
); );
} }
} } # end foreach process
} }
} }

View File

@ -74,8 +74,7 @@ static deinterlace_4field_fptr_t fptr_deinterlace_4field_gray8;
/* Pointer to image buffer memory copy function */ /* Pointer to image buffer memory copy function */
imgbufcpy_fptr_t fptr_imgbufcpy; imgbufcpy_fptr_t fptr_imgbufcpy;
Image::Image() Image::Image() {
{
if ( !initialised ) if ( !initialised )
Initialise(); Initialise();
width = 0; width = 0;
@ -91,8 +90,7 @@ Image::Image()
text[0] = '\0'; text[0] = '\0';
} }
Image::Image( const char *filename ) Image::Image( const char *filename ) {
{
if ( !initialised ) if ( !initialised )
Initialise(); Initialise();
width = 0; width = 0;
@ -798,13 +796,13 @@ bool Image::ReadJpeg( const char *filename, unsigned int p_colours, unsigned int
#endif #endif
} else { } else {
/* Assume RGB */ /* Assume RGB */
/* /*
#ifdef JCS_EXTENSIONS #ifdef JCS_EXTENSIONS
cinfo->out_color_space = JCS_EXT_RGB; cinfo->out_color_space = JCS_EXT_RGB;
#else #else
cinfo->out_color_space = JCS_RGB; cinfo->out_color_space = JCS_RGB;
#endif #endif
*/ */
cinfo->out_color_space = JCS_RGB; cinfo->out_color_space = JCS_RGB;
new_subpixelorder = ZM_SUBPIX_ORDER_RGB; new_subpixelorder = ZM_SUBPIX_ORDER_RGB;
} }
@ -928,13 +926,13 @@ bool Image::WriteJpeg( const char *filename, int quality_override, struct timeva
#endif #endif
} else { } else {
/* Assume RGB */ /* Assume RGB */
/* /*
#ifdef JCS_EXTENSIONS #ifdef JCS_EXTENSIONS
cinfo->out_color_space = JCS_EXT_RGB; cinfo->out_color_space = JCS_EXT_RGB;
#else #else
cinfo->out_color_space = JCS_RGB; cinfo->out_color_space = JCS_RGB;
#endif #endif
*/ */
cinfo->in_color_space = JCS_RGB; cinfo->in_color_space = JCS_RGB;
} }
break; break;
@ -946,20 +944,20 @@ bool Image::WriteJpeg( const char *filename, int quality_override, struct timeva
cinfo->dct_method = JDCT_FASTEST; cinfo->dct_method = JDCT_FASTEST;
jpeg_start_compress( cinfo, TRUE ); jpeg_start_compress( cinfo, TRUE );
if ( config.add_jpeg_comments && text[0] ) if ( config.add_jpeg_comments && text[0] ) {
{
jpeg_write_marker( cinfo, JPEG_COM, (const JOCTET *)text, strlen(text) ); jpeg_write_marker( cinfo, JPEG_COM, (const JOCTET *)text, strlen(text) );
} }
// If we have a non-zero time (meaning a parameter was passed in), then form a simple exif segment with that time as DateTimeOriginal and SubsecTimeOriginal // If we have a non-zero time (meaning a parameter was passed in), then form a simple exif segment with that time as DateTimeOriginal and SubsecTimeOriginal
// No timestamp just leave off the exif section. // No timestamp just leave off the exif section.
if(timestamp.tv_sec) if(timestamp.tv_sec)
{ {
#define EXIFTIMES_MS_OFFSET 0x36 // three decimal digits for milliseconds #define EXIFTIMES_MS_OFFSET 0x36 // three decimal digits for milliseconds
#define EXIFTIMES_MS_LEN 0x03 #define EXIFTIMES_MS_LEN 0x03
#define EXIFTIMES_OFFSET 0x3E // 19 characters format '2015:07:21 13:14:45' not including quotes #define EXIFTIMES_OFFSET 0x3E // 19 characters format '2015:07:21 13:14:45' not including quotes
#define EXIFTIMES_LEN 0x13 // = 19 #define EXIFTIMES_LEN 0x13 // = 19
#define EXIF_CODE 0xE1 #define EXIF_CODE 0xE1
// This is a lot of stuff to allocate on the stack. Recommend char *timebuf[64];
char timebuf[64], msbuf[64]; char timebuf[64], msbuf[64];
strftime(timebuf, sizeof timebuf, "%Y:%m:%d %H:%M:%S", localtime(&(timestamp.tv_sec))); strftime(timebuf, sizeof timebuf, "%Y:%m:%d %H:%M:%S", localtime(&(timestamp.tv_sec)));
snprintf(msbuf, sizeof msbuf, "%06d",(int)(timestamp.tv_usec)); // we only use milliseconds because that's all defined in exif, but this is the whole microseconds because we have it snprintf(msbuf, sizeof msbuf, "%06d",(int)(timestamp.tv_usec)); // we only use milliseconds because that's all defined in exif, but this is the whole microseconds because we have it
@ -971,8 +969,8 @@ bool Image::WriteJpeg( const char *filename, int quality_override, struct timeva
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0x00 }; 0xff, 0x00 };
memcpy(&exiftimes[EXIFTIMES_OFFSET], timebuf,EXIFTIMES_LEN); memcpy(&exiftimes[EXIFTIMES_OFFSET], timebuf,EXIFTIMES_LEN);
memcpy(&exiftimes[EXIFTIMES_MS_OFFSET], msbuf ,EXIFTIMES_MS_LEN); memcpy(&exiftimes[EXIFTIMES_MS_OFFSET], msbuf, EXIFTIMES_MS_LEN);
jpeg_write_marker (cinfo, EXIF_CODE, (const JOCTET *)exiftimes, sizeof(exiftimes) ); jpeg_write_marker( cinfo, EXIF_CODE, (const JOCTET *)exiftimes, sizeof(exiftimes) );
} }
JSAMPROW row_pointer; /* pointer to a single row */ JSAMPROW row_pointer; /* pointer to a single row */
@ -1081,13 +1079,13 @@ bool Image::DecodeJpeg( const JOCTET *inbuffer, int inbuffer_size, unsigned int
#endif #endif
} else { } else {
/* Assume RGB */ /* Assume RGB */
/* /*
#ifdef JCS_EXTENSIONS #ifdef JCS_EXTENSIONS
cinfo->out_color_space = JCS_EXT_RGB; cinfo->out_color_space = JCS_EXT_RGB;
#else #else
cinfo->out_color_space = JCS_RGB; cinfo->out_color_space = JCS_RGB;
#endif #endif
*/ */
cinfo->out_color_space = JCS_RGB; cinfo->out_color_space = JCS_RGB;
new_subpixelorder = ZM_SUBPIX_ORDER_RGB; new_subpixelorder = ZM_SUBPIX_ORDER_RGB;
} }
@ -1185,13 +1183,13 @@ bool Image::EncodeJpeg( JOCTET *outbuffer, int *outbuffer_size, int quality_over
#endif #endif
} else { } else {
/* Assume RGB */ /* Assume RGB */
/* /*
#ifdef JCS_EXTENSIONS #ifdef JCS_EXTENSIONS
cinfo->out_color_space = JCS_EXT_RGB; cinfo->out_color_space = JCS_EXT_RGB;
#else #else
cinfo->out_color_space = JCS_RGB; cinfo->out_color_space = JCS_RGB;
#endif #endif
*/ */
cinfo->in_color_space = JCS_RGB; cinfo->in_color_space = JCS_RGB;
} }
break; break;
@ -2007,18 +2005,14 @@ void Image::Annotate( const char *p_text, const Coord &coord, const unsigned int
} }
} }
void Image::Timestamp( const char *label, const time_t when, const Coord &coord, const int size ) void Image::Timestamp( const char *label, const time_t when, const Coord &coord, const int size ) {
{
char time_text[64]; char time_text[64];
strftime( time_text, sizeof(time_text), "%y/%m/%d %H:%M:%S", localtime( &when ) ); strftime( time_text, sizeof(time_text), "%y/%m/%d %H:%M:%S", localtime( &when ) );
char text[64]; char text[64];
if ( label ) if ( label ) {
{
snprintf( text, sizeof(text), "%s - %s", label, time_text ); snprintf( text, sizeof(text), "%s - %s", label, time_text );
Annotate( text, coord, size ); Annotate( text, coord, size );
} } else {
else
{
Annotate( time_text, coord, size ); Annotate( time_text, coord, size );
} }
} }